Excel-DNA calling xll function from another async xll function (Exception from HRESULT: 0x800AC472)

时间:2016-05-11 13:43:33

标签: c# vb.net excel excel-vba excel-dna vba

I'm using excel-DNA to make the addins, one addin handles communication to an API and another handles the inputs and routes. The second addin needs to be separate as other addins use it to post to the same api, and it is used to hold information about the address and user.

In VBA i used Application.Run() to run other files functions so I assumed the ExcelDnaUtil.Application.run() worked the same way, which it did. The issue is that the async functions, when they are trying to use application.run when the user is entering in a cell or selecting multiple cell and they get an error 0x800AC472.

I tried to solve the problem by looping until the function was successful (example below) using the ideas from this thread HRESULT 800ac472 from set operations in Excel 使用preventDefault,但当有人打开格式或功能向导窗口时,错误仍然存​​在。

Public Shared Function AsyncTest(a As Integer, b As Integer) As Object
    Return ExcelAsyncUtil.Run("AsyncTest", New Object() {a, b}, Function() SyncTest(a, b))
End Function

<MethodImpl(MethodImplOptions.Synchronized)>
Public Shared Function SyncTest(a As Integer, b As Integer) As Object
    Try
        Dim Package = String.Concat({"<Model><a>", a, "</a><b>", b, "</b></Model>"})

        Dim xlApp As Object
        xlApp = ExcelDnaUtil.Application
        Dim failed as boolean = false
        Do
            Try
                Return xlApp.Run("PostToApiXmlToJson", Package, "api/test/add")  

            Catch e As System.Runtime.InteropServices.COMException
                If e.ErrorCode = -2146777998 Then
                    failed = True
                    System.Threading.Thread.Sleep(10)
                End If
                Debug.Write(String.Concat({"ErrorCode: #### ", e.ErrorCode, " #### PostToAPI"}))
            End Try

            count = count + 1

            Loop Until failed = False Or count > 100

        Catch err As Exception
            Return err.Message
        End Try
    End Function

那么从另一个xll调用函数有不同的方法吗?

或者有没有办法告诉函数在函数空闲之前不计算?

或者有没有办法告诉Excel这个功能还没有完成再次计算?

是否有人需要更多信息来提供帮助?

任何帮助将不胜感激

1 个答案:

答案 0 :(得分:1)

运行AsyncTest时,SyncTest将在ThreadPool线程上运行(由于Task.Run)。从那里你正在用Excel进行COM调用。

作为一项规则,Excel加载项应该从不从除主计算线程之外的任何线程调用Excel。 Excel COM对象模型(基本上)是单线程的,因此所有COM调用最终都必须在主线程上执行。来自另一个线程的任何调用可能会因为您看到的COM错误而失败。

Excel-DNA有一个帮助方法,允许您安排在主Excel线程上运行的委托 - 您调用ExcelAsyncUtil.QueueAsMacro(...)。这将在Excel准备好后运行委托,并且该上下文中的COM和C API调用都将起作用,因为委托将在宏上下文中的主线程上运行。 ExcelAsyncUtil.QueueAsMacro可以随时从任何线程调用。