Dim hashData As Object
Set hashData = obj.getHashData
If getHashData
正在返回一个HashTable
, then hashData
是一个后期绑定HashTable
,你可以调用它的members https://learn.microsoft.com/en-us/dotnet/api/system.collections.hashtable?view=netframework-4.8#properties,包括其Item财产 https://learn.microsoft.com/en-us/dotnet/api/system.collections.hashtable.item?view=netframework-4.8#System_Collections_Hashtable_Item_System_Object_:
Dim value As Variant
value = hashData.Item("key")
您没有对后期绑定成员调用进行编译时验证Object
,所以你需要特别小心拼写错误,因为Option Explicit
当涉及后期绑定时,无法拯救您。请参阅HashTable
上面链接的文档了解您可以调用哪些成员。
添加参考mscorlib.tlb
(你会在下面找到它C:\Windows\Microsoft.NET\Framework\v4.0.30319
,或参考等效的\Framework64
如果您的 Excel 是 64 位 - 库的位数需要与主机应用程序的位数相匹配)通常会允许早期绑定,但是虽然此库是 COM 可见的,但它旨在从托管 (.net) 代码中使用,因此您可以从接口访问这些对象 - 具体类型不会直接公开任何成员:
知道Hashtable
实施IDictionary
接口,我们可以使用早期绑定并获得编译时验证和智能感知如果我们声明hashData As IDictionary
:
Dim hashData As mscorlib.IDictionary
Set hashData = New mscorlib.Hashtable
hashData.Add "foo", 42
Debug.Print hashData.Item("foo") 'prints 42
请注意,Item
财产暴露为默认会员:
这意味着您可以拥有Item
隐式成员调用,正如您对任何标准 VBA 集合对象所做的那样:
Dim hashData As mscorlib.IDictionary
Set hashData = New mscorlib.Hashtable
hashData.Add "foo", 42
Debug.Print hashData("foo") 'prints 42
早期绑定的代码更容易编写,尤其是当您不熟悉所涉及的类型时。但是,如果项目引用 64 位框架并且您的宏需要在 32 位 Excel 上运行,则您需要坚持使用后期绑定以避免绑定问题。
另请注意,迭代Hashtable
对象有一个For Each
循环不起作用,因为枚举器在 VBA 中的工作方式与在 .NET 中的工作方式不同;这Keys
and Values
集合是实现ICollection
接口,因此迭代它们也将是不平凡的:For Each
循环不起作用,虽然你可以设置一个For i = 0 To hashData.Keys.Count - 1
,您无法获取索引处的项目i
从一个ICollection
.
但我们知道ICollection
继承IEnumerable
, and IEnumerable
does与...一起工作For Each
, 所以我们可以cast the Keys
收集到IEnumerable
,并像这样迭代所有键和值:
Dim hashData As mscorlib.IDictionary
Set hashData = obj.getHashData
Dim hashKeys As mscorlib.IEnumerable
Set hashKeys = hashData.Keys
Dim k As Variant
For Each k In hashKeys
Debug.Print k, hashData(k) 'outputs the key and its associated value
Next
问题是你不能cast to IEnumerable
使用后期绑定代码或不引用mscorlib.tlb
,并且后期绑定不知何故不会看到GetEnumerator
成员,所以这会引发错误 438:
Dim hashKeys As Object
Set hashKeys = hashData.Keys
Dim k As Variant
For Each k In hashKeys ' error 438, hashKeys isn't exposing the enumerator
Debug.Print k, hashData(k)
Next
结论:如果您需要 VBA 代码在 32 位和 64 位主机上运行,您将不得不跳过重重困难才能使后期绑定代码正常工作。如果您使用的是 64 位主机,我建议您尽早绑定 64 位框架,并为 32 位主机分发引用 32 位框架的宏的单独副本。分发有点痛苦,但比让后期绑定的代码工作更痛苦。