Home > OS >  Managing Collections inside a Class
Managing Collections inside a Class

Time:04-01

i'm trying to work with classes in vba and i haven't found any documentation related to managing objects inside objects such as arrays or collections inside a class.

Let's say i have a class person and a class address and i want to manage addresses of a person.

Address

Private pStreet as String
Private pZip as Int

Public Property Let Street(val As String)
    pStreet = val
End Property
Public Property Get Street() As String
    Street = pStreet
End Property
Public Property Let Zip(val As String)
    pZip = val
End Property
Public Property Get Zip() As String
    Zip = pZip
End Property

Person

Private pName As String
Private pSurname As String
Private pAddresses As Collection

Public Property Let Name(val As String)
    pName = val
End Property
Public Property Get Name() As String
    Name = pName
End Property

Public Property Let Surname(val As String)
    pSurname = val
End Property
Public Property Get Surname() As String
    Surame = pSurname
End Property

Private Sub Class_Initialize()
    Set pAddresses = New Collection
End Sub
Private Sub Class_Terminate()
    Set pAddresses = Nothing
End Sub

Public Sub addAddress(ByVal val As Address)
    pAddresses.Add val
End Sub
Public Property Get Addresses() As Collection
    Set Addresses = pAddresses
End Property
Public Property Get Address(ByVal Index As Long) As Address
    Set Address = pAddresses(Index)
End Property

Module1

Sub test()

Dim x As Person
Set x = New Person
Dim a1 As Address
Set a1 = New Address
Dim a2 As Address
Set a2 = New Address

x.Name = "Mark"
x.Surname = "Doe"
a1.Street = "first avenue 213"
a1.Zip = "41242"
a2.Street = "second avenue 213"
a2.Zip = "55242"
x.addAddress a1
x.addAddress a2

Debug.Print x.Address(0)

End Sub

how should i deal with the address collection inside the person class? for instance, how could i retrieve all the addresses or the second address of the collection? x.addresses(1) doesn't work.

CodePudding user response:

The Person class should hold a collection of addresses, to avoid having to expand and preserve an array. The collection should be initialized/terminated as soon as the class is initialized/terminated.

See an example:

Private pAddresses as Collection

Private Sub Class_Initialize()
    Set pAddresses = New Collection
End Sub

Private Sub Class_Terminate()
    Set pAddresses = Nothing
End Sub

The class can expose the whole address collection via a property for looping, or a single address accessed by index.

Public Property Get Addresses() As Collection
    Set Addresses = pAddresses 
End property

Public Property Get Address(ByVal Index As Long) As Address
    Set Address = pAddresses(Index)
End property

Then you can loop:

Dim p As Person, a As Address

For Each a In p.Addresses
    a.Zip = ...
Next

Or get a single address by index:

Set a = p.Addresses(1)

Lastly, a simple Add method, to add an address to the person:

Public Sub AddAddress(ByVal param As Address)
    pAddresses.Add param
End Sub

You could also add (or replace) an address using a property by supplying both the address object and the index, but I dont know how useful it is in your case. Of course you need to make sure Index is valid.

Public Property Let Address(ByVal Index As Long, ByVal param As Address)
    pAddresses.Add param, Index
End property

Then to call it:

p.Addresses(Index) = a

To enforce the Set keyword, since we're dealing with objects, change Let to Set. Then, you need to set-it:

Set p.Addresses(Index) = a
  • Related