如何清空VBA中的数组?

时间:2014-01-22 17:37:24

标签: arrays vba

我正在开发一个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

看起来调试器能够以我需要的方式正确初始化空数组,以显示其值。

2 个答案:

答案 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