我已经用这个打了几天头脑,在互联网上上下搜索。我知道有很多我不太了解Com Interop,但我已经成功构建并使用更简单的DLL与Excel。无论如何。
运行包含在DLL中的以下代码时,我在Excel VBA中得到上述错误-2147467259 80004005 Automation Error Unspecified Error
。
[GuidAttribute("96BE21CD-887B-4770-9FAA-CF395375AEA9")]
[ComVisibleAttribute(true)]
interface QInterface
{
void ConnectionFill(string SQLQuery, string CONStr);
string QueryValue(int QueryKey);
string ConnectionValue(int ConnectionKey);
string outputFile { get; set; }
void ThreadTest();
}
[ClassInterfaceAttribute(ClassInterfaceType.None)]
[ProgIdAttribute("QueryThread")]
class QueryThread : QInterface
{
DataSet QueryReturn = new DataSet();
private ArrayList SQLList = new ArrayList();
private ArrayList ConList = new ArrayList();
private string OutputFile;
public void ConnectionFill(string SQLQuery, string CONStr)
{
SQLList.Add(SQLQuery);
ConList.Add(CONStr);
}
public string QueryValue(int QueryKey)
{
return SQLList[QueryKey].ToString();
}
public string ConnectionValue(int ConnectionKey)
{
return ConList[ConnectionKey].ToString();
}
public string outputFile
{
set { OutputFile = value; }
get { return OutputFile; }
}
public void ThreadTest()
{
int i = 0;
i = SQLList.Count;
Thread[] myThreads;
myThreads = new Thread[i];
for (int t = 0; t != i; t++)
{
myThreads[t] = new Thread(() => ThreadRun(SQLList[t].ToString(), ConList[t].ToString()));
myThreads[t].Name = "Thread " + t;
myThreads[t].IsBackground = true;
myThreads[t].Start();
Thread.Sleep(600);
if (t > 9)
{
myThreads[t - 9].Join();
}
}
for (int t = 0; t != i; t++)
{
while (myThreads[t].IsAlive)
{
Thread.Sleep(20);
}
}
TextWriter tw = new StreamWriter(OutputFile);
for (int t = 0; t < QueryReturn.Tables.Count; t++)
{
DataTableReader DR = QueryReturn.Tables[t].CreateDataReader();
while (DR.Read())
{
tw.WriteLine("{0} : {1}", DR.GetValue(0), DR.GetValue(1));
}
}
tw.Close();
QueryReturn.Dispose();
}
private void ThreadRun(string SQLString, string ConString)
{
try
{
OleDbConnection DBCon = new OleDbConnection(ConString);
DBCon.Open();
Thread.Sleep(200);
OleDbCommand DBCmd = new OleDbCommand(SQLString, DBCon);
OleDbDataAdapter DataAdapter = new OleDbDataAdapter(DBCmd);
Thread.Sleep(200);
DataAdapter.Fill(QueryReturn, Thread.CurrentThread.Name.ToString());
DBCon.Close();
DataAdapter.Dispose();
DBCon.Dispose();
DBCmd.Dispose();
}
finally
{
}
}
}
使用此VBA代码...
Sub test()
Dim QT As New QueryThreading.QueryThread
Dim MyResults As String
Dim outputfile As String
Dim InputStuff(1, 1) As String
InputStuff(0, 0) = "Select DISTINCT * From TrackingData;"
InputStuff(0, 1) = "Provider =Microsoft.ACE.OLEDB.12.0;Data Source =C:\Users\Nick\Desktop\test.accdb; Persist Security Info =False;Connection Timeout=7;"
InputStuff(1, 0) = "Select DISTINCT * From TrackingData;"
InputStuff(1, 1) = "Provider =Microsoft.ACE.OLEDB.12.0;Data Source =C:\Users\Nick\Desktop\test2.accdb; Persist Security Info =False;Connection Timeout=7;"
QT.ConnectionFill InputStuff(0, 0), InputStuff(0, 1)
QT.ConnectionFill InputStuff(1, 0), InputStuff(1, 1)
outputfile = "C:\Users\Nick\Desktop\testrun.txt"
QT.outputfile = outputfile
QT.ThreadTest
End Sub
它运行正常是一个纯C#控制台应用程序。工作完美,快速,没有问题。但是通过VBA我得到了错误。
我认为这与在多个线程中调用访问数据库有关。我知道那里有很多垃圾代码,它当然没有优化,我仍处于“玩转”阶段。
我已经使用了RegAsm并启用了com互操作和所有这些东西,我可以从退货中读回来就好了。所以我知道DLL工作正常,就在我填充线程并运行“ThreadTest()”时,我得到了自动化错误。
如果我再次运行它,Excel会锁定。
非常感谢任何帮助。
答案 0 :(得分:0)
您正在呼叫QT.DictionaryFill
但我似乎无法在您的C#代码中找到相应的方法...如果您将呼叫更改为QT.ConnectionFill
会怎样?
另一点:IIRC然后VBA在STA中运行对象 - 不确定是否支持MTA
编辑:
根据this相当旧的帖子VBA不支持多线程...