已迁移的 Excel XLL UDF 加载项调用在出错时接收 HRESULT 而不是 Error

Migrated Excel add-in invoke of XLL UDF receives HRESULT on error instead of Error

我正在将 VB6 Excel COM 加载项迁移到 VB.NET。我遇到了一个问题,加载项调用 Excel 来调用我们在 XLL 中实现的 UDF(使用 Excel 2013 SDK 用 C++ 编写),其中 Excel returns 一个包含 0x800A07DF(FACILITY_CONTROL,错误 2015)而不是错误的 32 位整数。

我们的VB6 Excel COM加载项具有以下功能:

' VB6 version of function.
Public Function GetValueFromSheet(ByVal szName As String, _
                            ByRef szValue As String) As Boolean
    Dim Val As Variant
    On Error GoTo GetValueFromSheetHandler

    Val = xlApp.run("XLLUDF", szName)

    ' If the UDF encountered an error, Val will contain an Error.
    If VarType(Val) = vbError Then
        GoTo GetValueFromSheetHandler
    Else
        szValue = Val
    End If

    GetValueFromSheet = True
    Exit Function

GetValueFromSheetHandler:
        GetValueFromSheet = False
        szValue = vbNullString
        Err.Clear
End Function

' VB.NET version of function.
Public Function GetValueFromSheet(ByVal sName As String, ByRef sValue As String) As Boolean
        Dim val As Object
        On Error GoTo GetValueFromSheetHandler

        val = xlApp.Run("XLLUDF", sName)

        ' If the UDF encountered an error, Val will contain an integer 
        ' representing an HRESULT (FACILITY_CONTROL, error 2015), and 
        ' the line below never evaluates to True, breaking the logic.
        If VarType(val) = VariantType.Error Then
            GoTo GetValueFromSheetHandler
        Else                
            sValue = val
        End If

        ' Even though "OURXLLUDF" returned an error, we're returning success. 
        GetValueFromSheet = True
        Exit Function

GetValueFromSheetHandler:
        GetValueFromSheet = False
        sValue = String.Empty
        Err.Clear()
    End Function    

逻辑现在被打破:函数返回 True,即使 XLL 调用返回错误。出于某种原因,错误正在被丢弃,取而代之的是 HRESULT。

我们可以做些什么来缓解这种情况,并确定 XLL 调用何时遇到错误?

此行为是设计使然,如官方文档所述:Marshaling Variant to Object

The following table identifies each variant type and the corresponding object type that the marshaler creates when a variant is passed from COM to the .NET Framework.

...

VT_ERROR => System.UInt32

...

因此您可以使用此特殊错误代码 (-2146826273) 检查结果是否为整数类型(我尚未测试但从您的评论看来该类型实际上是 System.Int32),或者您更改您的代码逻辑和 return 您将能够测试的另一种类型的 VARIANT。