.net运行时通过mscorlib.dll暴露给VBA(和其他COM客户端)。从理论上讲,VBA可以使用.net HashTables。实际上,我陷入困境。我已经注释掉了行不通的行。一个简单的用例就是像对Scripting.Dictionary
那样对键进行迭代。Function GenerateSampleHashTable() As Object
Dim ht As Object
Set ht = CreateObject("System.Collections.HashTable")
ht.Add "Foo", "Bar"
ht.Add "Red", "FF0000"
ht.Add "Green", "00FF00"
ht.Add "Blue", "0000FF"
Set GenerateSampleHashTable = ht
End Function
Sub TestHashTable()
Dim ht As Object
'*** PRETEND THIS CAME OUT OF A C# COMPONENT ***
Set ht = GenerateSampleHashTable
Debug.Print ht.ContainsKey("Foo")
Dim oKeys As Object
Set oKeys = CreateObject("System.Collections.ArrayList")
oKeys.Capacity = ht.Count
Dim vKeys() As Variant
vKeys() = oKeys.ToArray()
Dim col As mscorlib.ICollection
Set col = ht.Keys()
'col.CopyTo oKeys, 0 'Runtime error: Type mismatch
'col.CopyTo vKeys(), 0 'Compile Error: Type mismatch
Dim vKeyLoop As Variant
For Each vKeyLoop In vKeys()
Debug.Print vKeyLoop, ht.Item(vKeyLoop)
Next
End Sub
答案 0 :(得分:2)
对于将VBA数组传递到期望System.Array
(例如CopyTo(System.Array, Integer)
)的.NET方法引起的不兼容,我并不感到惊讶。
直接使用从.Keys
返回的集合并没有取得很大的成功,因此将其复制到ArrayList
似乎是一个有用的解决方法。
HashTable.Keys
返回一个ICollection
,而ArrayList
可以在其ICollection
中接受一个AddRange()
,因此应该可以:
Dim ht As Object
Set ht = GenerateSampleHashTable()
Dim oKeys As Object
Set oKeys = CreateObject("System.Collections.ArrayList")
oKeys.AddRange ht.Keys()
结果oKeys
可以直接枚举:
Dim i As Long
For i = 0 To oKeys.Count - 1
Debug.Print oKeys.Item(i)
Next
或者可以在Wrap .Net ArrayList with custom VBA class get iterator中描述的包装类的帮助下使用For Each
进行枚举(所有功劳都放在此位置):
Dim wr As ThatCollectionWrapperClass
Set wr = New ThatCollectionWrapperClass
wr.Init oKeys 'Poor man's constructor - add that method to the class and remove its Class_Initialize
Dim k As Variant
For Each k In wr
Debug.Print k
Next