Autor: Peter Haserodt  --- Aus Excel VBA - Gruppe: Tutorials

Felder - Arrays (3) - Redim und Redim Preserve

Autor: Peter Haserodt - Erstellt: --      - Letzte Revision: --Gruppenthema: 3 Folgen 1 2 3 Sie sind in Folge:3
ReDim und ReDim Preserve

Beschäfigen wir uns zunächst mit dem ReDim.
Es gibt immer wieder Situationen, in welcher man die benötigte Größe eines Feldes erst innerhalb einer Berechnung ermittelt, dass sich die Größen verändern können und das Feld neu bestückt wird.
Grundsätzlich gilt:
Idealerweise dimensionioniert man ein Feld genau so groß, wie viele Elemente es aufnehmen soll.
Dies hat nur Vorteile. Erstens spart es Speicherplatz, zweitens kann ich vernünftig mit LBound und UBound später arbeiten, drittens ist mein Feld dann mit Werten komplett gefüllt.
In der Regel hat man dafür dann erst einmal ein Dummyfeld.
Wir schauen uns ein Beispiel an:

Public Sub FeldTest8()
Dim fMeinFeld() As Long
ReDim fMeinFeld(5)
fMeinFeld(5) = 3
MsgBox fMeinFeld(5)
ReDim fMeinFeld(7)
MsgBox fMeinFeld(5)
' Produziert hier einen Fehler
fMeinFeld(2) = "Haus"
End Sub
Bevor ich zur Analyse komme: Wieviele Zahlen kann denn fMeinFeld nach dem ersten Redim aufnehmen? Na, erinnern Sie sich noch? Ich verrate es Ihnen jedenfalls nicht!

Analyse:

Als erstes habe ich mir ein Feld ohne Dimensionen angelegt, vom Typ Long.
Mit ReDim habe ich ihm im Beispiel nun die Obergrenze 5 gegeben.
Jetzt einen Wert rein und ausgeben lassen.

Nun ein neues ReDim und mal schauen, was mit meinem Wert passiert ist.
Der blöde Wert ist weg!!!

Ergo
: Mit ReDim dimensioniere ich das Feld neu und neu heißt hier, dass es neu aufgebaut wird!

Im nächsten Schritt habe ich netterweise (so wie ich halt bin) einen Fehler für Sie produziert.
Den Typen eines Feldes kann ich nicht durch ReDim ändern!
Probieren Sie auch mal:
ReDim fMeinFeld(3) as Variant aus. Auch da bekommen Sie eine hübsche Fehlermeldung.
Habe ich ein Feld ersteinmal typisiert, kann ich den Typen nicht mehr ändern !!!


Hinweis
: Natürlich kann ich auch ein Feld über mehrere Dimensionen Redimensionieren, also ein:
Redim fMeinFeld(3,5) ist absolut zugelassen!

ReDim Preserve

Ich mag es nicht, ich mag es nicht, ich mag es nicht! Aber das hilft mir wenig.
Meine Frau sagt: Wenn schon denn schon und überhaupt (obwohl meine Frau mal ausnahmsweise nichts damit zu tun hat)

Von vielen geliebt und missbraucht!

Dass Preserve steht für Erhalten.
Jetzt kann man sich schon vorstellen, was damit gemeint ist: Ich redimensioniere mein Feld und erhalte die bisherigen Werte!
Das kling unheimlich gut und ist in Wirklichkeit ganz be... scheiden!
Aber ersteinmal ein simples Beispiel:

Public Sub FeldTest9()
Dim fMeinFeld() As Long
ReDim fMeinFeld(5)
fMeinFeld(5) = 6
ReDim Preserve fMeinFeld(20)
MsgBox fMeinFeld(5)
fMeinFeld(19) = 23
MsgBox fMeinFeld(19)
End Sub
Analyse:

Als erstes habe ich mal mein ReDim.
Dann stelle ich irgendwann fest: Oh Oh Oh, meine Feldgrenze ist zu klein. Was mache ich nur.
Und jetzt kommt ReDim Preserve ins Spiel.
Wir erweitern die Grenze und erhalten die Daten des Feldes.
Sieht auf den ersten Blick toll aus, ist aber oft Murks aus Faulheit geboren (Yep Yep, Sie haben Recht, der von Ihnen so geliebte Autor ist der erste Kandidat für diese Faulheit!).
Aber schauen wir uns mal die Nachteile von ReDim Preserve im Einzelnen an:

Zuerst: So richtig Sinn gibt Redim Preserve nur bei eindimensionalen Feldern.
Denn ReDim Preserve kann nur mit der Erweiterung der letzten Dimension gehandelt werden:

Public Sub FeldTest10()
Dim fMeinFeld() As Long
ReDim fMeinFeld(3, 5)
'Produziert Fehler
ReDim Preserve fMeinFeld(5, 6)
End Sub
Das funktioniert:

Public Sub FeldTest11()
Dim fMeinFeld() As Long
ReDim fMeinFeld(3, 5)
fMeinFeld(1, 4) = 12
ReDim Preserve fMeinFeld(3, 6)
MsgBox fMeinFeld(1, 4)
End Sub
Performance:

Redim Preserve ist ein Zeitkiller. Daten müssen geschaufelt werden (wohin auch immer) Felder neu aufgebaut werden, oder irgend so ein anderes schmutziges Zeug, was im Hintergrund abläuft und von dem ich nichts verstehe.
Aber wenn mich etwas von meinem Feierabendbier abhält, weil es zu langsam ist, dann werde ich schon sauer!

Aber Trotz allem Negativem:

Es kann auch nützlich sein, wenn man es intelligent anwendet.
Wollen wir uns mal im nächsten Kasten dies etwas genauer ansehen.

Interner Tipp:
Eine Excel Schulung von einem Profi ist Gold wert!
Peter Haserodt bietet Ihnen das und noch viel mehr...
Mehr dazu unter: Schulung

ReDim Preserve - Überlegungen für Profis

Dies ist nun nicht unbedingt für den Novizen geeignet. (Dies meine ich ernst!)

Völlig Performance- Absurd ist das Preservieren in Einzelsteps.
(Wobei ich gestehen muss, dass soetwas auch in meinen Codes noch irgendwo rumfliegt, weil es manchmal so bequem ist)

Stellen wir uns das Szenario vor, das man Dateien in ein Feld einlesen will. Man kennt die Anzahl vorher nicht (auch wenn man diese vorher ermittleln könnte)
Jetzt ist ein Schleife, die jedesmal unser Feld um 1 erhöht, wenn wir einen Treffer landen, nicht unbedingt der Treffer.
Eine Lösung hierzu ist eine sprunghafte Erhöhung des Feldes unter Zuhilfenahme eines Zählers und späterer Reduzierung.

Ich redimensioniere mein Feld erstmal auf z.B. 100. Wird diese Grenze überschritten, dann erhöhe ich die Grenze auf 200 etc...
D.h. ich habe eine ReDim nur aller 100 Einheiten.

Über meinen Zähler redimensioniere ich das Feld am Ende wieder zurück.
Ich reduziere es also auf seine tatsächliche Zahl.


Dieses Thema hat weitere Beiträge

Felder - Arrays (1) - Einführung und LBound/UBound
Felder - Arrays (2) - Inhalte
Felder - Arrays (3) - Redim und Redim Preserve

Weitere Artikel der Gruppe: Tutorials Aus Excel VBA
Nach oben