将范围对象从 VBA 传递到 .NET 会导致 "Runtime Error 91"
Passing a range object from VBA to .NET causes "Runtime Error 91"
是以下的.NET类型:
Microsoft.Office.Interop.Excel.Range
与 VBA 相同的类型:
excel.range
?
将它从 VBA 传递到 .NET 不起作用。
它导致:
Run-time error '91': Object variable or With block variable not set.
.NET 代码(在本例中为 VB.NET)是:
Imports Microsoft.Office.Interop.Excel
Public Class clsDotNetClass
private mRangeObject as Excel.Range
Public Property FirstProperty As Excel.Range
Get
Return mRangeObject
End Get
Set(value As Excel.Range)
mRangeObject = value
End Set
End Property
End class
VBA是:
Public sub DoesNotWork ()
Dim wkbObject As Workbook
Dim shtObject As Worksheet
Dim rngObject As Range
Set wkbObject = ThisWorkbook
Set shtObject = wkbObject.Worksheets("Sheet1")
Set rngObject = shtObject.Range("A1:B2")
Dim clsAttempt1 as new clsDotNetClass
With clsAttempt1
.FirstProperty = rngObject
End With
End sub
否则 COM 连接工作正常。
如有任何想法,我们将不胜感激,
海因
Is the .NET type of: Microsoft.Office.Interop.Excel.Range
the same type as VBA: Excel.Range
?
不,不是。 .NET 类型是托管类型,VBA 类型是 COM 对象类型。 COM-Interop 类型正在包装 COM 对象,使非托管对象可通过 .NET 使用。
不过,托管互操作类型应该很好地编组到一个和另一个。
除了这不是你想的那样:
With clsAttempt1
.FirstProperty = rngObject
End With
不涉及任何 .NET 代码,它与此相同:
Public Sub test()
Dim foo As Range
foo = Sheet1.Range("A1")
End Sub
此代码被 Rubberduck 标记如下:
Assignment to 'foo' implicitly assigns to the default member '_Default' of class 'EXCEL.EXE:Excel.Range'.
换句话说,您不是在分配 .FirstProperty
,而是分配给 .FirstProperty.[_Default]
(在 VBA 规范中记录为 "let-coercion",此处涉及 hidden 默认成员),如果未设置范围引用,则会引发错误 91,因为您正在对 Nothing
.[=24 进行隐式成员调用=]
尝试使用 Set
关键字:
With clsAttempt1
Set .FirstProperty = rngObject
End With
Set
关键字在 VBA 中 是必需的 ,每当您要分配对象引用时:这是因为在 VBA 中,无参数默认成员是完全合法的(它们不在 VB.NET 中)。
是以下的.NET类型:
Microsoft.Office.Interop.Excel.Range
与 VBA 相同的类型:
excel.range
?
将它从 VBA 传递到 .NET 不起作用。
它导致:
Run-time error '91': Object variable or With block variable not set.
.NET 代码(在本例中为 VB.NET)是:
Imports Microsoft.Office.Interop.Excel
Public Class clsDotNetClass
private mRangeObject as Excel.Range
Public Property FirstProperty As Excel.Range
Get
Return mRangeObject
End Get
Set(value As Excel.Range)
mRangeObject = value
End Set
End Property
End class
VBA是:
Public sub DoesNotWork ()
Dim wkbObject As Workbook
Dim shtObject As Worksheet
Dim rngObject As Range
Set wkbObject = ThisWorkbook
Set shtObject = wkbObject.Worksheets("Sheet1")
Set rngObject = shtObject.Range("A1:B2")
Dim clsAttempt1 as new clsDotNetClass
With clsAttempt1
.FirstProperty = rngObject
End With
End sub
否则 COM 连接工作正常。
如有任何想法,我们将不胜感激,
海因
Is the .NET type of:
Microsoft.Office.Interop.Excel.Range
the same type as VBA:Excel.Range
?
不,不是。 .NET 类型是托管类型,VBA 类型是 COM 对象类型。 COM-Interop 类型正在包装 COM 对象,使非托管对象可通过 .NET 使用。
不过,托管互操作类型应该很好地编组到一个和另一个。
除了这不是你想的那样:
With clsAttempt1 .FirstProperty = rngObject End With
不涉及任何 .NET 代码,它与此相同:
Public Sub test()
Dim foo As Range
foo = Sheet1.Range("A1")
End Sub
此代码被 Rubberduck 标记如下:
Assignment to 'foo' implicitly assigns to the default member '_Default' of class 'EXCEL.EXE:Excel.Range'.
换句话说,您不是在分配 .FirstProperty
,而是分配给 .FirstProperty.[_Default]
(在 VBA 规范中记录为 "let-coercion",此处涉及 hidden 默认成员),如果未设置范围引用,则会引发错误 91,因为您正在对 Nothing
.[=24 进行隐式成员调用=]
尝试使用 Set
关键字:
With clsAttempt1
Set .FirstProperty = rngObject
End With
Set
关键字在 VBA 中 是必需的 ,每当您要分配对象引用时:这是因为在 VBA 中,无参数默认成员是完全合法的(它们不在 VB.NET 中)。