已迁移的 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。
我正在将 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。