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