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
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
2条答案
按热度按时间fdx2calv1#
字符串
如果
getHashData
返回一个HashTable
,那么hashData
是一个后期绑定的HashTable
,你可以调用它的成员,包括它的Item
属性:型
对于
Object
的后期绑定成员调用,您不会得到编译时验证,因此您需要特别小心打字错误,因为当涉及后期绑定时,Option Explicit
无法保存您。有关可以调用的成员,请参阅上面链接的HashTable
文档。添加对
mscorlib.tlb
的引用(您可以在C:\Windows\Microsoft.NET\Framework\v4.0.30319
下找到它,或者如果您的Excel是64位的,则引用\Framework64
中的等效内容-库的位数需要与主机应用程序的位数相匹配)通常允许早期绑定,但尽管此库是COM可见的,但它旨在从托管(.net)代码中使用,因此您将从接口访问这些对象-具体类型不会直接公开任何成员:x1c 0d1x的数据
知道
Hashtable
实现了IDictionary
接口,我们可以使用早期绑定并获得编译时验证和 IntelliSense,如果我们声明hashData As IDictionary
:型
请注意,
Item
属性公开为 *default成员 *:的
这意味着您可以隐式调用
Item
成员,就像您可以对任何标准VBA集合对象执行的操作一样:型
早期绑定的代码更容易编写,特别是当您不熟悉所涉及的类型时。但是,如果项目引用的是64位框架,并且您的宏需要在32位Excel上运行,则需要坚持后期绑定以避免绑定问题。
还要注意,使用
For Each
循环迭代Hashtable
对象是不起作用的,因为枚举器在VBA中的工作方式与在.NET中的工作方式不同;Keys
和Values
集合是实现ICollection
接口的对象,因此迭代它们也是非常重要的:For Each
循环将不起作用,虽然您可以设置For i = 0 To hashData.Keys.Count - 1
,但您无法从ICollection
中获取索引为i
的项。但是我们知道
ICollection
继承了IEnumerable
,并且IEnumerable
* 确实 * 与For Each
一起工作,所以我们可以将Keys
集合 * 转换 * 为IEnumerable
,并像这样迭代所有键和值:型
问题是,你不能使用后期绑定代码或不引用
mscorlib.tlb
而 * 强制转换 * 到IEnumerable
,后期绑定不知何故不会看到GetEnumerator
成员,所以这会引发错误438:型
结论:如果您需要VBA代码在32位和64位主机上都能运行,那么您将不得不通过各种方式来使后期绑定的代码正常工作。如果您使用的是64位主机,我建议您使用64位框架的早期绑定,并为32位主机分发引用32位框架的宏的单独副本。分发代码有点麻烦,但比让后期绑定的代码工作要轻松。
pgx2nnw82#
我知道自从这个问题被问到/回答以来已经过去了很多时间,但请允许我回答,为了像我这样试图找到一种方法来迭代HashTable的键(在VBA的VBIDE中)的其他人。
通过阅读Mathieu Guindon的答案(非常棒)和this以及this,我想提出我的2美分,我们可以做到这一点,而不必添加引用和后期绑定(也可以在VBA的即时窗口内工作)。
如所附的屏幕截图所示,我们只需要使用ArrayList的.AddRange方法将Hashtable的键添加到ArrayList中,如:
字符串
这一点也被提及。
由于Hashtable的Keys属性是一个 ICollection,而ArrayList的AddRange方法也可以使用 ICollection,它们就像是天作之合,瞧,现在我们可以迭代Hashtable的键,尽管是以一种迂回的方式作为ArrayList。
我从这里提到的使用Queue的Enqueue向ArrayList添加一系列值中得到了这个想法。但是,该方法不允许在VBA中使用For Each进行迭代,而是将添加的键视为单个对象而不是可迭代对象。
我只是希望以后在某个地方的某个人会发现这很有用。谢谢大家。
x1c 0d1x的数据