我正在开发一个Excel VBA插件,用COM服务器交换对象,如下所示:
'get an array of objects
Dim Ents() As ISomething
ComObject.GetEntities Ents
'send an array with 10 objects
ReDim Ents(9)
Set Ents(0) = ...
...
ComObject.SetEntities Ents
获取数组运行良好:如果数组包含对象,它按预期工作,如果数组为空,则为UBound(Ents) = -1
,一切都按预期工作。
发送数组仅适用于非空数组,因为我无法Redim Ents(-1)
和Erase
数组VBA和COM服务器崩溃:Debug.Print UBound(Ents)
在VBA中崩溃,谁知道服务器崩溃了什么。
看起来Erase
语句使数组未定义/损坏而不是空。
编辑(澄清以下评论):
执行此代码时会崩溃,因为它无法计算UBound
:
Sub Test()
Dim Ents() As ISmartId
Debug.Print UBound(Ents)
End Sub
但是如果将Ents
添加到监视窗口,然后将断点设置为Debug.Print
行并执行,则调试器会在“类型”列中显示ISmartId(0 to -1)
。在此之后,执行继续而不会崩溃,并且“调试”窗口显示预期的-1
。
看起来调试器能够以我需要的方式正确初始化空数组,以显示其值。
答案 0 :(得分:3)
对于对象,只需将未定义的数组复制到变量中并返回:
即可Dim o() As Worksheet
Dim v As Variant
v = o
o = v
对于非对象,在变量中创建一个空数组,然后更改其类型代码:
Private Declare Sub GetMem2 Lib "msvbvm60" (src As Any, dest As Any)
Dim i() as Long
Dim v as Variant
v = Array()
Dim NewTypeCode As Integer
NewTypeCode = vbArray Or vbLong
GetMem2 NewTypeCode, v
i = v
答案 1 :(得分:0)
如果你需要一个新阵列,你可以创建一个“工厂”功能来返回一个
Function FreshArray() As ISomething()
Dim rv() As ISomething
FreshArray = rv
End Function
Ents = FreshArray()
ComObject.GetEntities Ents