2014-01-22 80 views
3

我工作的一個Excel VBA加載項與COM服務器交換對象,像這樣:如何在VBA中清空數組?

'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語句留下數組未定義/損壞而不是空的。

EDIT(澄清以下評論):

執行此代碼崩潰,因爲它不能計算UBound

Sub Test() 
    Dim Ents() As ISmartId 
    Debug.Print UBound(Ents) 
End Sub 

但是如果你添加Ents到監視窗口,然後設置一個到Debug.Print行的中斷點並執行,調試器在類型列中顯示ISmartId(0 to -1)。在此之後,執行繼續而不發生崩潰,並且「調試」窗口顯示預期的-1

它看起來像調試器能夠以我需要的方式正確初始化空數組,只是爲了顯示其值。

+0

我不認爲你可以。 AFAIK,你只能擦除它們,然後在你嘗試測試它們的大小時捕捉錯誤。在這裏:http://stackoverflow.com/questions/206324/how-to-check-for-empty-array-in-vba-macro – RBarryYoung

+0

@RBarryYoung:我可以在VBA端進行檢查,但COM服務器是第三方應用程序,他們只是期望一個空數組。我只找到了一個只適用於字符串數組的解決方法:'Split(「」)'。我需要一個'IAnything'的通用解決方案。這是否有助於你的幻想? – stenci

+1

「*這是否有助於您的幻想?*」咦?對不起,我沒有關注..? – RBarryYoung

回答

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 
+0

我接受了這個答案,因爲它非常接近我所需要的,即使它不給我我想要的類型。我注意到如果我在監視窗口中有數組,並且在'Erase'後面有一個斷點,VBA會將數組初始化爲一個空數組,然後在那一點上我可以繼續執行並且它工作的很好。你知道在那個觀察窗的引擎蓋下發生了什麼嗎? – stenci

+0

您可以發佈您正在運行的代碼以及斷點的位置嗎?當你在談論'Erase'語句時,我無法理解你的意思。 – Chel

+1

@stenci好吧,我已經用早期綁定對象的更直接的解決方案更新了我的答案。 – Chel

0

如果你需要一個新的數組,你可以創建一個「工廠」函數返回一個

Function FreshArray() As ISomething() 
    Dim rv() As ISomething 
    FreshArray = rv 
End Function 

Ents = FreshArray() 
ComObject.GetEntities Ents 
+1

這可以像'Erase'一樣工作:創建一個損壞/未定義的數組。它崩潰閱讀'UBound(FreshArray)'。 – stenci