vba 一个类可以扩展 Collection 对象吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5748085/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can a class extend the Collection object?
提问by Jean-Fran?ois Corbett
I'm trying to extend functionality of the VBA Collection
object in a new class and make this class an inheritant of Collection
, but the Implements Collection
statement gives me the following error:
我试图Collection
在一个新类中扩展 VBA对象的功能并使这个类成为 的继承者Collection
,但该Implements Collection
语句给了我以下错误:
Bad interface for Implements: method has underscore in its name.
用于实现的错误接口:方法名称中有下划线。
What underscore?! Add
, Item
, Remove
, and Count
are the only methods listed in the documentation for Collection
. All four are underscore-free.
什么下划线?!Add
、Item
、Remove
和Count
是 的文档中列出的唯一方法Collection
。所有四个都没有下划线。
EDIT: To clarify, I'm making a class called UniformCollection
(that only accepts members that are all of the same type, inspired by this approach). I'd like it to implementCollection
, so that a UniformCollection
is aCollection
and can be used in place of a Collection
when calling other objects' methods, etc.
编辑:为了澄清,我正在创建一个名为UniformCollection
(仅接受所有相同类型的成员,受此方法启发)的类。我希望它实现Collection
,以便在调用其他对象的方法等时aUniformCollection
是 aCollection
并且可以代替 a 使用Collection
。
I know I have to write delegating methods/properties for Add, Item, etc., and a NewEnum property for For Each
to work, and I've done so already.
我知道我必须为 Add、Item 等编写委托方法/属性,以及一个 NewEnum 属性For Each
才能工作,而且我已经这样做了。
My problem is that the Implements Collection
statement gives me the error stated above.
我的问题是该Implements Collection
语句给了我上述错误。
Bonus question: is Count
a method or a property of Collection
? Help calls it a property, but the Object Browser in the VBA editor calls it a function i.e. method (flying yellow box).
额外的问题:是Count
方法还是属性Collection
?帮助将其称为属性,但 VBA 编辑器中的对象浏览器将其称为函数即方法(飞黄框)。
采纳答案by mischab1
You are running into one of the limitations of Implements in VBA. You can't implement another class if the other class has any public methods or properties with an underscore in the name. Collection
class of course has _NewEnum
but any underscore will cause a problem.
您遇到了 VBA 中实现的限制之一。如果另一个类具有名称中带有下划线的任何公共方法或属性,则您不能实现另一个类。Collection
类当然有,_NewEnum
但任何下划线都会导致问题。
For example, if you created a class AddressClass
that had the following:
例如,如果您创建了一个AddressClass
具有以下内容的类:
Public Address_City As String
Then created another class CustomerAddress
:
然后创建了另一个类CustomerAddress
:
Implements AddressClass
Private Property Get ClassInterface_Address_City() As String
End Property
Private Property Let ClassInterface_Address_City(ByVal RHS As String)
End Property
When you compile, you will get an error "Object module needs to implement 'Address_City' for interface 'AddressClass'." Changing the property to AddressCity
makes the error go away.
编译时会报错“对象模块需要为接口‘AddressClass’实现‘Address_City’”。将属性更改为AddressCity
使错误消失。
Possible solution:If I understand correctly, you want to implement the collection class so you can pass your new class to methods that take in collections as parameters. Is it possible to alter those methods? My suggestion would be to create your own collection class MyCollection
and then implement it instead. i.e. UniformMyCollection
That way you can completely avoid problems with underscores.
可能的解决方案:如果我理解正确,您希望实现集合类,以便您可以将新类传递给将集合作为参数的方法。是否有可能改变这些方法?我的建议是创建自己的集合类MyCollection
,然后实现它。即UniformMyCollection
这样你就可以完全避免下划线的问题。
As for Count
, I would trust the Object Browser over the help text anytime. On the other hand, if you are creating your own collection class, it doesn't matter which one you choose.
至于Count
,我会随时信任对象浏览器而不是帮助文本。另一方面,如果您要创建自己的集合类,则选择哪个都无关紧要。
回答by Dick Kusleika
VBA has a lot of limitations on what classes you can implement. The NewEnum is tripping up Collection, but even if it wasn't, there could very well be something else in that class to trip it up. I think it reports the first problem it finds.
VBA 对您可以实现的类有很多限制。NewEnum 正在绊倒 Collection,但即使不是,该类中也很可能有其他东西来绊倒它。我认为它报告了它发现的第一个问题。
Because Collection has so few properties and methods, I just rewrite them.
因为 Collection 的属性和方法太少了,我就重写了。
Private mcolParts As Collection
Public Sub Add(clsPart As CPart)
mcolParts.Add clsPart, CStr(clsPart.PartID)
End Sub
Public Property Get Count() As Long
Count = mcolParts.Count
End Property
Public Property Get Item(vItm As Variant) As CPart
Set Item = mcolParts.Item(vItm)
End Property
Public Sub Remove(vIndex As Variant)
mcolParts.Remove vIndex
End Sub
In don't know why the OB shows methods (they look like green boxes to me). For my money, methods either change multiple properties or interact with something outside of the class. Everything else is a property. I'd call both Count and Index properties.
不知道为什么 OB 会显示方法(对我来说它们看起来像绿框)。为了我的钱,方法要么改变多个属性,要么与类之外的东西交互。其他一切都是财产。我会调用 Count 和 Index 属性。
回答by RolandTumble
Dick Kusleika has most of it, but if you want to use For Each
on your custom class, you'll also need:
Dick Kusleika 拥有大部分,但如果你想For Each
在你的自定义类中使用,你还需要:
'--- required additional property that allow to enumerate the collection with For Each
Public Property Get NewEnum() As IUnknown
Set NewEnum = m_ColParts.[_NewEnum]
End Property
This isn't discussed in either of the links I found in my Favorites (this oneor this one), but they're both worth reading. If I find the site that talks about NewEnum I'll do an Edit to add it.
我在我的收藏夹(这个或这个)中找到的任何一个链接中都没有讨论这一点,但它们都值得一读。如果我找到谈论 NewEnum 的站点,我将进行编辑以添加它。
EDIT
编辑
Neither of these links are the one I was looking for, either, but both discuss the NewEnum property (including a little extra voodoo that neeeds to be added):
这些链接都不是我正在寻找的链接,但都讨论了 NewEnum 属性(包括需要添加的一些额外的巫毒教):
Both of these talk about Excel, but the VBA is the same in other Office applications (including the need for the export->text edit->import process to get "Attributes").
这两个都讲Excel,但VBA在其他Office应用程序中是一样的(包括需要导出->文本编辑->导入过程才能获得“属性”)。
回答by Martyn Barry
Re RolandTumble's note on "NewEnum" :
重新 RolandTumble 关于“NewEnum”的说明:
My own experience in Access 2003 is that "For Each" works fine by importing code including the line
我自己在 Access 2003 中的经验是“For Each”可以通过导入包括行在内的代码来正常工作
Attribute NewEnum.VB_UserMemId = -4
... but after I "/decompile" the file (command line switch), the line has been removed (verified on export) and the "For Each" does not function.
...但在我“/反编译”文件(命令行开关)后,该行已被删除(在导出时验证)并且“For Each”不起作用。
Unfortunately I need to use "/Decompile" when "Compress and Repair" does not fix things for me.
不幸的是,当“压缩和修复”无法为我解决问题时,我需要使用“/Decompile”。