关于Excel VBA的一个简单问题:如果“Sheets”对象是一个集合,为什么下面的句子返回false? (在中间面板输入)
debug.print TypeOf Sheets Is Collection
Falso
我发现它是因为我创建了一个以 Collection 作为参数的函数。该函数适用于我声明为 Collection 的变量,但不适用于其他集合(例如 Sheets 集合)。
也许 VBA 在继承和/或多态性方面失败了?
<小时/>编辑:正如JosieP和mehow所解释的,Sheets集合不继承自Collection类/接口(interface),因此它不是一个Collection,并且不能作为Collection进行多态使用。
现在的问题是:为什么 Sheets 不是 Collection 的子类?为什么他们没有从 Collection 继承?考虑到已在 Sheets 中实现的方法/属性,这应该是小菜一碟。正如我所看到的,Collection 类/接口(interface)只需要 4 个方法:
Add
Count
Item
Remove
Sheets 已经实现了 4 个类似的方法/属性:
Add
Count
Item
Delete
所以映射是微不足道的。他们可以轻松地将 Sheets 集合转换为 Collection。
<小时/>编辑2:我感谢mehow提出询问MS的建议,但我不会这样做,因为他们可能会说“这不是一个设计错误,这是一个功能”: )。更多思考内容:在新工作簿中运行以下代码:
Sheets.Add.name = "sh2"
Sheets.Add.name = "sh3"
Dim col As Collection
Set col = New Collection
col.Add Sheets(1)
col.Add Sheets(2)
col.Add Sheets(3)
For Each ele In col
Debug.Print "ele in col: " & ele.name
Next ele
For Each ele In Sheets
Debug.Print "ele in Sheets: " & ele.name
Next ele
令我感到奇怪的是,“col”和“Sheets”都可以通过“foreach”循环以相同的方式进行迭代,但它们不共享公共(public)接口(interface)。如果我必须设计类,层次结构将是:
iIterable (interface)
|
|
iCollection (interface)
/ \
/ \
/ \
Collection cSheets (classes)
Sheets 将是 cSheets 类的对象(实例)。
通过这种方式,我创建的函数(当前采用 Collection 参数)将采用 iCollection 参数,因此它可以与 Collection 实例和工作表一起使用。
最佳答案
Sheets
是 Object
类型的集合,而不是 Collection
类型的对象。
正如 JosieP 所说
the Sheets class does not inherit from the VBA Collection nor does it implement a Collection interface (there is no Remove method for example)
应该足够理解了。
Sub Main()
Dim c As Collection
Set c = New Collection
Debug.Print VarType(c), TypeOf c Is Collection
Debug.Print VarType(Sheets), TypeOf Sheets Is Object
End Sub
要确认,请使用 F2 打开对象浏览器
,然后输入 find Sheets
向 Microsoft 询问您的第二个问题。但请记住,Collection
可以为空,而 Sheets
始终需要至少有一个 Sheets 或 Chart 对象。
很多东西都依赖于 Excel 中的 Sheets 集合对象,这就是为什么我认为它必须是一个单独的类。我看不出实现 ICollection 接口(interface)并提供单独的实现有什么问题,但就像我说的问 Microsoft(好问题)。
<小时/>for every
循环是可能的,因为每个 VBA 类都有 attributes 。并非所有属性都可以通过 IDE 看到,但它们确实存在(更多的是 VB6 常识,而不仅仅是引用 VBA)。
好的,现在回答你的第三个问题。您可以迭代集合,因为它实现了 IUnknown 接口(interface) NewEnum()
(可枚举方法)。您可以在您的类型的集合上指定默认迭代对象(在 Sheets 情况下为 Sheets 集合)。
参见this link对可枚举方法有更清晰的解释。
参见this answer更好地理解迭代是如何实现的。
关于Excel VBA : Why "Sheets" collection is not a "Collection"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20678834/