Reputation: 71
I've programmed in several languages but i'm at my first tests on VBA.
I need to make a class who has as a property, an array of objects of another class. Let's make an example a Person class who keeps info about name, surname and addresses. And an address class who keeps info about a street and zipcode. A person could have many addresses so Person should have an arrays of Addresses.
class 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
class Person
Private pName as String
Private pSurname as String
Private pAddresses() as Address
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
How should i manage the array of Address?
i tried with such code but if i try to call this method on a person object i get an error" obect doesn't support this property or method"
Public Sub addAddress(val as Address)
ReDim pAddresses(1)
pAddresses(0) = val
End Sub
what's the way to do this? i cannot find any tutorial or something who shows how to use arrays of objects inside of an object
Upvotes: 2
Views: 469
Reputation: 235
Change your code to this should work
Public Sub main()
Dim val As New Address
val.Street = "MyStreet"
val.Zip = 666
Dim val2 As New Address
val2.Street = "my New Street"
val2.Zip = 999
Dim myself As New Person
With myself
.Name = "its Me"
.Surname = "Smith"
Call .addAddress(val)
Call .addAddress(val2)
End With
' Get Number off addresses available
Debug.Print "Number of Adresses: " & myself.GetAddresses.Count
' Read the Addresses
Dim Add As Address
For Each Add In myself.GetAddresses
Debug.Print "Streetname: " & Add.Street & ", Zip:" & Add.Zip
Next
' Get First Address of the List
Debug.Print "First Adress - Streetname: " & myself.GetAddresses(1).Street
Debug.Print "First Adress - Zip: " & myself.GetAddresses(1).Zip
' Get The Address Object itself
Dim theAdd As Address
Set theAdd = myself.GetAddresses(1)
Debug.Print "First Adress - Streetname: " & theAdd.Street
Debug.Print "First Adress - Zip: " & theAdd.Zip
' Remove Address
Call myself.GetAddresses.Remove(1)
End Sub
class Address
Private pStreet As String
Private pZip As Integer
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
end class
class person
Private pName As String
Private pSurname As String
Private pAddresses As Collection
Private Sub Class_Initialize()
Set pAddresses = New Collection
End Sub
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
Public Sub addAddress(val As Address)
Call pAddresses.Add(val)
End Sub
Public Function GetAddresses() As Collection
Set GetAddresses = pAddresses
End Function
end class
First, create objects using NEW
Keyword and then SET
the objects to variables. You Always have to use the SET
Keyword if you want to store a reference to an existing object inside of an variable.
Revealing Access trough the Person.GetAddresses()
Function to the Person
class address collection itself is not a clean way for encapsulation. But I think this helps for a better understanding.
Nice Starting Point to get into collections: Excel Collection Ultimate Guide Definitly important topic, since mostly all for each loops iterate trough collections.
Upvotes: 1
Reputation: 1814
When you use redim, it actually makes a brand new array of the specified size, so all existing data is lost. To copy the values from the old array to the new one, you need the 'Preserve' keyword as follows
ReDim Preserve pAddresses(1)
But this is really inefficient as adding another element to the array requires rewriting the entire array. You are probably better of using a collecion. So instead of declaring pAddress like this
Private pAddresses() as Address ' delcare as an array
do it like this
Private pAddresses as New Collection ' declare as a collection
Now your method to add an address can look like this:
Public Sub addAddress(val as Address)
pAddresses.Add val
End Sub
The indices for collections start counting at one instead of zero (as arrays do) so the following line prints the first entry in the collection
Debug.Print pAddresses(1)
Upvotes: 1