【问题标题】:Automation Error 80004005自动化错误 80004005
【发布时间】:2011-11-24 13:26:19
【问题描述】:

这几天我一直在用这个来打败自己,在互联网上上下搜索。我知道有很多关于 Com Interop 的知识我不太了解,但我已经成功地构建和使用 Excel 中更简单的 DLL。反正都是重点。

运行以下包装在 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 interop 和所有类似的东西,我可以很好地从返回中读取。所以我知道 DLL 工作正常,就在我填充线程并运行“ThreadTest()”时,我得到了自动化错误。

如果我再次运行它,Excel 会锁定。

任何帮助将不胜感激。

【问题讨论】:

  • 无论如何不要使用 ArraList,而是使用通用 List。并使用自动实现的属性。
  • 与 Excel 一起使用时,我无法让 List 正确传递信息并正确存储。我先试过了。无论哪种方式,当信息确实通过时,我仍然会收到错误消息。我会回去修复它并在它正常工作时完成我的实现。不过感谢您的提示。

标签: c# multithreading excel com automation


【解决方案1】:

您正在调用 QT.DictionaryFill 虽然我似乎无法在您的 C# 代码中找到相应的方法...如果您将调用改为 QT.ConnectionFill 会发生什么?

另一点:IIRC 然后 VBA 在 STA 中运行对象 - 但不确定是否支持 MTA

编辑:

根据this 相当老的帖子 VBA 不支持多线程...

【讨论】:

  • DictionaryFill 的好点,我将 C# 中的方法名称改为 ConnectionFill。没有在我的 VBA 代码中更改它。但是,即使在我重命名它之前,我仍然遇到上述问题。我将不得不查找 VBA 中的 STA/MTA 支持。
  • 嗯,看来我得想办法解决这个问题了。我可能会在 C# Windows 窗体程序中设计整个东西...感谢您的帮助。
猜你喜欢
  • 2011-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-18
相关资源
最近更新 更多