Excel VBA集合保持重复最后一个对象

时间:2016-09-06 02:23:28

标签: excel vba excel-vba

我在尝试填充对象集时遇到了一个奇怪的问题。当我为PromptsRange.Rows的每个循环做一切都是完美的。您可以单步执行NewPrompt区域并观察每一行是否通过,并最终添加到PromptsCollection。我遇到的问题是在这一点之后。如果您尝试对PromptsCollection上的每个循环执行a,则每个对象(36)都完全相同,并且是查找表中的最后一个值。我很难过。也许其中一位学者可以帮助我。

这是我的查阅表 enter image description here

以下代码位于userform模块中。     选项明确

Private pPromptsCollection As New Collection
Private pProductPromptMapping As New clsOrderPromptRow
Private pOrderPrompts As New clsOrderPromptRow
Private pTarget As Range
Private pSKU As String

Public Property Get PromptsCollection() As Collection
    Set PromptsCollection = pPromptsCollection
End Property

Public Property Let PromptsCollection(Value As Collection)
    Set pPromptsCollection = Value
End Property

Private Sub SetPromptControls()
Dim PromptsRange As Range
Dim PromptRow As Range

Set PromptsRange = Range("LookUpTablePrompts")

For Each PromptRow In PromptsRange.Rows
    Dim NewPrompt As New clsPrompt
    NewPrompt.Name = PromptRow.Cells(1, 1)
    NewPrompt.ControlType = PromptRow.Cells(1, 2)
    NewPrompt.ComboboxValues = PromptRow.Cells(1, 3)
    NewPrompt.HelpText = PromptRow.Cells(1, 4)
    NewPrompt.TabIndex = PromptRow.Cells(1, 5)
    NewPrompt.ColumnIndex = PromptRow.Cells(1, 6)
    NewPrompt.TableIndex = PromptRow.Cells(1, 7)
    NewPrompt.ControlName = PromptRow.Cells(1, 8)

    PromptsCollection.Add NewPrompt, CStr(NewPrompt.Name)
Next
PromptsCollection.Count
End Sub

所以现在这里是我遇到问题的地方。这将导致36个对象全部相同。

Dim Prompt As New clsPrompt

For Each Prompt In PromptsCollection
    MsgBox (Prompt.Name)

Next
我甚至将它推到了观察窗口,以确认所有物体都是相同的。它始终以表格底部抽屉前高度的最后一行结果。

希望这很清楚。提前谢谢。

3 个答案:

答案 0 :(得分:7)

使用As New时,VBA将在第一次使用时创建对象的新实例。您应该避免使用As New并改为使用此模式:

Dim NewPrompt As clsPrompt

For Each PromptRow In PromptsRange.Rows
    Set NewPrompt = New clsPrompt

答案 1 :(得分:4)

问题是它对象的同一个实例被多次添加到集合中。 每个循环基本上更新同一个对象的值,从而更新已经在集合中的每个元素,因为它们都引用同一个对象。 最后,集合中的所有元素都将具有最后一行数据的值。

如前所述,要么在每个循环的开头显式创建一个新对象

For Each PromptRow In PromptsRange.Rows
    Set NewPrompt = New clsPrompt

或者在添加对象后销毁它:

....
        set NewPrompt = Nothing
    Next 

两者都将确保为数据的每一行创建一个新对象。

进行调试,将这些行添加到您的类:

Private Sub Class_Initialize()
    Debug.Print "Init"
End Sub

Private Sub Class_Terminate()
    Debug.Print "Term" & Me.Name
End Sub

这将让您看到在调试窗口中创建/终止对象的实例。

答案 2 :(得分:3)

使用简单的图像,我想解释为什么声明As New不能用于收集。 HTH

enter image description here