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

我有一个奇怪的问题,试图填充我的对象集合。 当我为PromptsRange.Rows做每个循环时,一切都是完美的。 您可以遍历NewPrompt区域并观察每一行,最后将其添加到PromptsCollection 。 我的问题是在这之后。 如果您尝试为PromptsCollection上的每个循环执行PromptsCollection ,则每个对象(36)都是完全相同的,并且是可PromptsCollection的最后一个值。 我难倒了。 也许其中一位学者可以帮助我。

这是我的lookuptable 在这里输入图像说明

以下代码位于用户窗体模块中。 选项显式

 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 

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

希望这已经够清楚了。 提前致谢。

当使用As New ,VBA将在第一次使用时创build对象的新实例。 你应该避免使用As New ,而是使用这个模式:

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

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

如前所述,无论是在每个循环开始时显式创build一个新的对象

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

或者一旦添加对象就销毁对象:

 .... set NewPrompt = Nothing Next 

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

为了debugging,将这些行添加到你的类:

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

这将让你看到在debugging窗口中创build/终止对象的实例。

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

在这里输入图像说明