如何在VBA中实现一个填充了类内对象的数组

时间:2016-09-13 02:13:17

标签: vba

我试图以几种不同的方式实现这一点,显然我错过了一些东西。

包含CPanel对象数组的CUnit类 -

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

模块正文:

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()

这是有效的

Panels(1).Width = 1

当我运行它时,我得到"对象变量或未设置块变量。"

UnitBom.Panel(1).Width = 2

你们不得不原谅我,因为我显然没有很好地解释。我需要一个CUnit对象内的CPanel对象数组。问题是,当我创建CUnit对象时,我不知道制作CPanel数组有多大。我试图创建一个适当大小的临时数组,只要我知道该大小应该是什么,然后将CUnit数组设置为等于临时数组,以便" size"它。可能有更好的方法来完成同样的事情。

2 个答案:

答案 0 :(得分:1)

从我可以猜到的那些(少数)你的代码片段中,我认为有一些编码错误来自代码逻辑需要进行审核:

获取财产

代码:

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

应该被重写,因为您要返回Panel类型对象(...As CPanel),您应该在赋值语句左侧的每个Set出现之前添加Panel关键字:

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

但是在RIndex = 0的情况下再次出现错误,因为您尝试将Panel类型对象设置为Panel个对象的数组,这是完全不同的!

所以你可以采用Variant方法:

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

仍然(成功)允许这样的陈述:

UnitBom.Panel(1).Width = 2

但也会(不成功)允许以下声明:

UnitBom.Panel().Width = 2 

你最有可能(也希望也是)不需要,但是你的班级实际上会允许它......

所以也许您会查看CUnit课程的功能,例如,采用默认Rindex

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

让财产

这将用于以下声明:

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

同时让Panel(1)Panel(2)引用相同的Panel对象

但是您必须再次使用Set关键字

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

答案 1 :(得分:0)

这里第一行是不必要的。我猜测Unit尚未设置,这导致代码进一步出现问题。

'设置UnitBom =新CUnit' '设置UnitBom = Unit'

此处Panels()中的每个引用都设置为PanelTemp的同一个实例。

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

这是你真正想要做的事情:

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