2016-09-06 7 views
1

オブジェクトコレクションを作成しようとすると奇妙な問題が発生しています。私がPromptsRange.Rowsのために各ループのためにやっているとき、すべてが完璧です。 NewPromptエリアを通過して、各行が通過するのを見て、最終的に最後にPromptsCollectionに追加することができます。私が持っている問題はこの時点の後です。 PromptsCollectionの各ループに対してaを実行しようとすると、各オブジェクト(36)は完全に同じであり、ルックアップテーブルの最後の値になります。イムは困惑した。おそらく、奨学生の一人が私を助けてくれるかもしれません。Excel VBAコレクションが繰り返し保存されている最後のオブジェクト

は、ここに私のルックアップテーブル enter image description here

次のコードは、ユーザーフォームモジュール内にあるのです。 Option Explicit

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

「新しいものとして」は実際の問題ではありません。実際の問題は、ループのすべての反復が同じオブジェクトインスタンスに書き込むことです。あなたのサンプルコードが正しく動作するように、各反復で新しいオブジェクトインスタンスを作成する必要があります。変数 "as New"を宣言し、各ループ反復の開始時に新しいインスタンスを作成することができます。しかし、どちらかを行うのが最善です。この場合、サンプルコードが私の好みの解決策になります。 –

+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 

これはあなたがオブジェクトのインスタンスは、デバッグウィンドウで終了/作成したばかり見るようになります。

関連する問題