Excel VBA:为什么“Sheets”集合不是“Collection”?

时间:2013-12-19 10:15:36

标签: excel vba inheritance collections polymorphism

关于Excel VBA的一个简单问题:如果“Sheets”对象是一个集合,为什么下面的句子返回false? (在中级面板中输入)

debug.print TypeOf Sheets Is Collection
Falso

我发现它是因为我创建了一个以Collection作为参数的函数。该函数适用于我声明为Collection的变量,但不适用于其他集合(例如Sheets集合)。

或许VBA在继承和/或多态性方面失败了?


编辑:正如JosieP和mehow所解释的那样,Sheets集合不会继承Collection类/接口,因此它不是Collection,也不能以多态方式用作Collection 。

所以现在的问题是:为什么Sheets不是Collection的子类?为什么他们没有继承Collection?鉴于已经在Sheets中实现的方法/属性,它应该是小菜一碟。我可以看到,Collection类/接口只需要4个方法:

Add
Count
Item
Remove

表格已经实现了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”都可以以相同的方式迭代,使用“for each”循环,但它们不共享一个公共接口。如果我必须设计类,层次结构将是:

    iIterable       (interface)
        |
        |
    iCollection     (interface)
       / \
      /   \
     /     \
Collection  cSheets    (classes)

和Sheets将是cSheets类的对象(实例)。

通过这种方式,我创建的函数(当前采用Collection参数)将采用iCollection参数,因此它可以与Collection实例和Sheets一起使用。

1 个答案:

答案 0 :(得分:6)

SheetsObject类型的集合,而不是Collection类型的对象。

像JosieP说的那样

  

Sheets类不会从VBA Collection继承,也不会   实现一个Collection接口(没有Remove方法)   例如)

应该足以理解。

MSDN reference

enter image description here

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

要确认打开Object Browser F2 并输入find Sheets


向Microsoft提出第二个问题。但请记住,Collection可以为空,而Sheets始终需要至少有一个表格或图表对象。

很多的东西依赖于Excel中的Sheets集合对象,这就是为什么我认为它必须是一个单独的类。通过实现ICollection接口并提供单独的实现,我看不出有什么问题,但就像我说的那样问微软(好问题)


for each循环是可能的,因为每个VBA类都有attributes。并非所有属性都可以通过IDE看到,但它们确实存在(更多的VB6常识而不仅仅是对VBA的引用)。

好的,现在回答你的第三个问题。您可以迭代集合,因为它实现了IUnknown接口NewEnum() enumarable method )。您在类型集合上指定默认迭代对象(在表格案例中为其Sheets集合)。

有关可枚举方法的更清楚的解释,请参阅this link

请参阅this answer以更好地了解迭代的可行性。