2012-03-29 3 views
1

Ich habe diesen Code:VBA: Ich ändere arr (0), kann nicht verstehen, warum arr (1) geändert wird?

Call MakeRoomForArrayItem(interAll, 0) 

interAll(0).StartY = tempStartY 
interAll(0).K = tempK 

In der ersten Zeile ich einen neuen langgestreckten Interall() durch eine erfolgreich erstellen.

Dann erwarte ich, dass die Zeilen zwei und drei nur interAll (0) betreffen, aber sie führen die gleichen Änderungen an interAll (1) durch. Warum ist das? Habe ich erfolgreich ein neues Objekt für interAll (1) erstellt?

Sub MakeRoomForArrayItem(ItemArray As Variant, ByVal ItemElement As Integer) 
    Dim i As Integer 
    ReDim Preserve ItemArray(LBound(ItemArray) To UBound(ItemArray) + 1) 

    For i = UBound(ItemArray) - 1 To ItemElement Step -1 
     Set ItemArray(i + 1) = ItemArray(i) 
    Next 
    'Erase values in object ItemArray(ItemElement) would be nice 
End Sub 

Ich habe die gleiche Funktion in anderen Fällen erfolgreich verwendet. Könnte es mit fehlenden Deklarationen in der aufrufenden Funktion zu tun haben?

EDIT: Ich habe das Problem behoben, indem

Set interval = New CInterval 
Set interAll(0) = interval 

Hinzufügen Können Sie mir erklären, was hier wirklich passiert ist, damit ich nicht wieder den gleichen Fehler machen?

+0

Psst ... vergessen Sie nicht, um Kommentare upvote Sie hilfreich, und akzeptieren Sie die Antwort, die Sie am meisten hilfreich! (Es muss nicht mein sein!) –

Antwort

1

Es hängt davon ab, welche Art von Variable Sie in MakeRoomForArrayItem übergeben. Wenn Ihr Array einen Wert Variable vom Typ, wie Integer oder Boolean halten, dann wird es funktionieren, weil die Zuordnungsanweisung

Set ItemArray(i + 1) = ItemArray(i) 

einen Wert zu kopieren. Wenn Sie jedoch eine Variable verwenden, die als Verweis übergeben wird, kopieren Sie nicht ihren Wert, sondern kopieren den Verweis auf die Variable. In diesem Fall scheinen Sie eine Klassenvariable zu übergeben, die als Referenz übergeben wird.

BEARBEITEN: Wenn Sie den Anruf an New CInterval machten, haben Sie tatsächlich eine neue Variable zugewiesen, anstatt einen Verweis auf die vorherige Variable zu kopieren. Deshalb hat dein Fix funktioniert. Ohne Ihre Korrektur hatten Sie nur einen "Slot" im Speicher, um einen Wert zu speichern, aber Ihr Array referenzierte diesen Speicher mehrfach. Nach dem Fix hatten Sie so viele "Steckplätze" im Speicher, wie Sie Anrufe an New CInterval hatten, und jedes Element des Arrays referenzierte den neuen Speicherort.

Vielleicht ist der folgende Code wird helfen:

Set interval1 = New CInterval ' you have a single CInterval instance 
Set interval2 = New CInterval ' changes to interval1 or interval2 do not affect each other 
Set interval3 = interval2  ' changes to interval3 also make changes to interval2, 
           ' because they are the same object. 
Dim arr as CInterval(3)   
' Create a single array that has 3 elements, 
' which will hold 3 references to CInterval instances. 
' Those references may or may not be to the same actual CInterval instance. 

Set arr(0) = interval1 ' the first element of the array references the first object instance 
Set arr(1) = interval1 ' the second element of the array also references the first object instance 
Set arr(2) = interval2 ' the third element of the array references the second object instance. 
         ' Changes to this element will affect both interval2 and interval3, because they are references to the same object in memory. 
1

Wenn Sie dies tun:

Set ItemArray(i + 1) = ItemArray(i)

Sie kopieren eine Referenz, kein Wert. Also am Ende der Schleife, wenn i=0, was diese Zeile sagt ist "kopieren Sie einen Verweis auf das Objekt in ItemArray(0) an Stelle 1." Daher enthalten sowohl ItemArray(0) als auch ItemArray(1) Referenzen, die auf dieselbe Objektinstanz zeigen. Sie sollten dies mit dem Debugger bestätigen können.

Verwandte Themen