VBA subclass reference

2019-06-08 07:34发布

In this post there is the description of "subclass" usage in VBA. I'm looking for the next step of it: when I have first subitem added I want to use it and don't know how.

When I write baseItem(1).itemName it doesn't work.

I assume it's just because that baseItem is not a collection or an array, but I don't know any other way.

2条回答
爷、活的狠高调
2楼-- · 2019-06-08 08:00

Welcome to SO!

In vba like many other languages it is a Property. You call them directly and not numerically, but you need to write GET/LET methods unless the class is public (that is not really encapsulation to simply access directly).

baseItem.itemName would be your call.

But ... As I said before, better that you write accessor(s) to your class as methods.

Here is a guy that sets the tone for OOP in VBA (for me): https://stackoverflow.com/a/45570268/8716187

He is a driver of the Rubberduck project.

I would ask you to ask yourself if you really need a class, I will often use 4-10 dictionaries of keys holding arrays. I could wrap them in a class but why bother? What I need is a searchable and editable ("array"-the dictionary of arrays).

I have very few class modules written, it seems that one can operate without it many times.

-WWC

查看更多
放我归山
3楼-- · 2019-06-08 08:09

I assume it's just because that baseItem is not a collection or an array...

The baseItem itself is not a collection nor an array. It is just an object of type BaseClass. But this object baseItem wrapps a collection so we maybe could say it is almost a collection.

The problem with this object though is, that as it is defined now in the answer you mentioned, it provides no way how the clients can get to this collection. The class BaseClass needs to be modified so it provides access to this inner collection for the client of this class. With access e.g. some public function is meant which will return something from this collection.

Add something like this to the BaseClass:

Public Function getSubItem(index As Variant) As SubClass
    Set getSubItem = subClassCollection.Item(index)
End Function

Now objects which will be at runtime created based on this class definition will provide access to the inner collection via this function getSubItem. The code which will use this function will look like this. So it is now almost that what you are trying to achieve.

Dim name As String
name = baseItem.getSubItem(1).itemName
Debug.Print name ' Prints "Something" in output window

But it could be made even exactly to what you are trying to achieve. When exporting the file of BaseClass.cls and adding Attribute Value.VB_UserMemId = 0 to the very beginning of function getSubItem and importing it again to project.

Public Function getSubItem(index As Variant) As SubClass
    Attribute Value.VB_UserMemId = 0
    Set getSubItem = subClassCollection.Item(index)
End Function

Now you can really write your code exactly that way you wanted. HTH

Dim name As String
name = baseItem(1).itemName
Debug.Print name ' Prints "Something" in output window

For more information about Creating A Default Member In VBA have a look e.g. here.

查看更多
登录 后发表回答