bluebass44
bluebass44

Reputation: 65

How to implement an array filled with objects inside a class in VBA

I have tried to implement this several different ways and am obviously missing something.

Class CUnit which includes an array of CPanel objects -

Private pPanel() As CPanel

Public Property Get Panel(Optional RIndex As Integer) As CPanel
    If RIndex = 0 Then
        Panel = pPanel
    Else
        Panel = pPanel(RIndex)
    End If
End Property

Public Property Let Panel(Optional RIndex As Integer, Value As Variant)
    If RIndex = 0 Then
        pPanel = Value
    Else
        pPanel(RIndex) = Value
    End If
End Property

Body of module:

Function UnitBom(Unit As CUnit) As CUnit

Set UnitBom = Unit

Dim Panels() As CPanel
ReDim Panels(1 To UnitBom.NumPanels)
Dim PanelTemp As CPanel
Set PanelTemp = New CPanel
Dim i As Variant

For i = 1 To UnitBom.NumPanels
    Set Panels(i) = PanelTemp
Next i

UnitBom.Panel = Panels()

this works

Panels(1).Width = 1

When I run this I get "Object variable or with block variable not set."

UnitBom.Panel(1).Width = 2

You guys will have to forgive me because I have obviously not explained very well. I need an array of CPanel objects inside a CUnit object. The problem is that when I create the CUnit object, I dont know how big to make the CPanel array. I was attempting to create a temporary array that is the proper size as soon as I know what that size should be and then set the CUnit array equal to the temporary array in order to "size" it. There is probably a far better way of accomplishing the same thing.

Upvotes: 0

Views: 102

Answers (2)

user3598756
user3598756

Reputation: 29421

from what I can guess out of those (few) pieces of code of yours, there are some coding errors which I think derive from code logic to be reviewed:


Get property

code:

Public Property Get Panel(Optional RIndex As Integer) As CPanel
    If RIndex = 0 Then
        Panel = pPanel
    Else
        Panel = pPanel(RIndex)
    End If
End Property

should be rewritten because since you are returning a Panel type object (...As CPanel) you should add Set keyword before each Panel occurrence in the left side of assignment statements:

Public Property Get Panel(Optional RIndex As Integer) As CPanel
    If RIndex = 0 Then
        Set Panel = pPanel
    Else
        Set Panel = pPanel(RIndex)
    End If
End Property

but then again in case RIndex = 0 you would get an error since you'd try to set a Panel type object to an array of Panel objects, which is quite not the same!

so you could adopt a Variant approach:

Public Property Get Panel(Optional RIndex As Integer) As Variant
    If RIndex = 0 Then
        Panel = pPanel
    Else
        Set Panel = pPanel(RIndex)
    End If
End Property

which would still (successfully) allow such a statement as:

UnitBom.Panel(1).Width = 2

but would also (unsuccessfully) allow such a statement as:

UnitBom.Panel().Width = 2 

which you most probably (and hopefully, too) don't need, but nevertheless your class would actually allow it ...

so maybe you would review the functionality of your CUnit class and, for instance, adopt a default Rindex:

Public Property Get Panel(Optional RIndex As Integer) As CPanel
    If RIndex = 0 Then RIndex = 1
    Set Panel = pPanel(RIndex)
End Property

Let property

this would be used for such a statement as:

UnitBom.Panel(1) = UnitBom.Panel(2)

to have both Panel(1) and Panel(2) refer to the same Panel object

but then you have to use Set keyword once again

Public Property Let Panel(Optional RIndex As Integer, Value As Variant)
    If RIndex = 0 Then
        pPanel = Value
    Else
        Set pPanel(RIndex) = Value
    End If
End Property

Upvotes: 1

user6432984
user6432984

Reputation:

Here line one is unnecessary. I'm guessing that Unit has not been set and this is causing problems further down the code.

'Set UnitBom = New CUnit' 'Set UnitBom = Unit'

Here every reference in Panels() is being set to the same instance of PanelTemp.

For i = 1 To UnitBom.NumPanels
    Set Panels(i) = PanelTemp
Next i

This is what you actually want to do:

For i = 1 To UnitBom.NumPanels
    Set Panels(i) = New CPanel
Next i

Upvotes: 0

Related Questions