2016-09-06 35 views
1

我有一个奇怪的问题,试图填充我的对象集合。当我为PromptsRange.Rows做每个循环时,一切都很完美。您可以逐步浏览NewPrompt区域,并观看每一行通过,最终将最终添加到PromptsCollection。我有这个问题。如果您尝试为PromptsCollection上的每个循环执行一次,则每个对象(36)都完全相同,并且是可查找的最后一个值。我难倒了。也许其中一位学者可以帮助我。Excel VBA集合保持重复最后一个对象

这里是我的LookupTable中 enter image description here

下面的代码是一个窗体模块内。 显式的选项

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 

我甚至把它推到观察窗口,以验证所有的对象是在面对相同的。它始终与表底部抽屉前部高度的最后一行结果。

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

回答

6

当使用As New时,VBA将在首次使用时创建对象的新实例。您应该避免使用As New和使用这个模式来代替:

Dim NewPrompt As clsPrompt 

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

“作为新”不是真正的问题。真正的问题是循环的每次迭代都写入相同的对象实例。每个迭代都需要创建一个新的对象实例,就像您的示例代码正确执行的那样。您仍然可以将变量声明为“新建”,并在每次循环迭代开始时创建一个新实例。但最好做一个或另一个,所以在这种情况下,您的示例代码将是我的首选解决方案。 –

+1

@JoeBourne说得好。 –

3

通过简单的图像,我想解释为什么声明As New不收集工作。 HTH

enter image description here

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 

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