关于Excel VBA的一个简单问题:如果“ Sheets”对象是一个集合,为什么以下句子返回false?(在“中间”面板上输入)
debug.print TypeOf Sheets Is Collection
Falso
我发现它是因为我做了一个将Collection作为参数的函数。该函数可用于我已声明为Collection的变量,但不适用于其他集合(例如Sheets集合)。
也许VBA在继承和/或多态性方面失败了?
编辑:正如JosieP和方法所解释的那样,Sheets集合不是从Collection类/接口继承的,因此它不是Collection,并且不能多态地用作Collection。
所以现在的问题是:为什么Sheets不是Collection的子类?为什么他们没有继承Collection?鉴于已经在Sheets中实现的方法/属性,这应该是小菜一碟。如我所见,Collection类/接口仅需要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”都可以通过“ for each”循环以相同的方式进行迭代,但是它们没有共享公共接口。如果必须设计类,则层次结构为:
iIterable (interface)
|
|
iCollection (interface)
/ \
/ \
/ \
Collection cSheets (classes)
Sheets将是cSheets类的对象(实例)。
这样,我创建的函数(当前带有Collection参数)将带有iCollection参数,因此它可以与Collection实例和Sheets一起使用。
Sheets
是Object
类型的集合,而不是类型的对象Collection
。
就像JosieP所说的
Sheets类不继承自VBA Collection,也不实现Collection接口(例如,没有Remove方法)
应该足以理解。
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和类型的发现Sheets
向Microsoft解决您的第二个问题。但是请记住,Collection
当Sheets
总是需要至少一个Sheets或Chart对象时,它可以为空。
很多事情取决于Excel中的Sheets集合对象,这就是为什么我认为它必须是一个单独的类。通过实现ICollection接口并提供单独的实现,我看不到任何错误,但是就像我说的向微软提问(很好的问题)
该for each
循环是可能的,因为每个VBA类有属性。并非所有属性都可以通过IDE看到,但它们确实存在(更多VB6常识,而不仅仅是引用VBA)。
好的,现在回答您的第三个问题。您可以遍历集合,因为它实现了IUnknown接口NewEnum()
(可枚举的方法)。您可以在类型的集合(在Sheets情况下为Sheets集合)上指定默认的迭代对象。
有关可枚举方法的更清晰说明,请参见此链接。
请参阅此答案以更好地了解如何进行迭代。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句