🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA ReDim in Excel — Arrays mit ReDim und ReDim Preserve vergrößern

|

VBA ReDim in Excel — Arrays mit ReDim und ReDim Preserve vergrößern

Kurzfassung — Ein VBA-Array legt seine Größe in dem Moment fest, in dem Sie es mit Dim deklarieren — es sei denn, Sie lassen die Klammern leer. Dim a() deklariert ein dynamisches Array, das noch keine Größe hat; ReDim a(1 To 10) gibt ihm eine. Ein blankes ReDim verwirft jeden Wert, den es hielt; um ein Array ohne Datenverlust zu vergrößern, nutzen Sie also ReDim Preserve. Der Haken: Bei einem zweidimensionalen Array kann ReDim Preserve nur die letzte Dimension ändern. Arrays mit fester Größe (Dim a(1 To 10)) lassen sich überhaupt nie mit ReDim ändern.

Sub GrowAnArray()
    Dim a() As Long                 ' dynamisch - noch keine Groesse
    ReDim a(1 To 3)                 ' jetzt haelt es 3 Longs
    a(1) = 10: a(2) = 20: a(3) = 30

    ReDim Preserve a(1 To 5)        ' auf 5 vergroessern, 10, 20, 30 BEHALTEN
    a(4) = 40: a(5) = 50            ' ein blankes ReDim haette hier 10-30 geloescht
End Sub

ReDim ist die ganze Geschichte dynamischer Arrays. Deklarieren Sie das Array offen mit Dim a(), dimensionieren Sie es mit ReDim, fragen Sie mit UBound, wie groß es ist, und — bei einem Gitter — denken Sie daran, dass nur die letzte Dimension wachsen kann (siehe VBA 2D Arrays). Machen Sie ReDim falsch, verschwinden Ihre Daten klammheimlich, es lohnt sich also zu verstehen, wann die Größe festliegt und wann nicht.

Was Sie lernen

  • Die eine Entscheidung, die jedes Array bestimmt — feste Größe beim Dim oder offen mit Dim a()
  • Warum ReDim ein dynamisches Array dimensioniert und warum ein blankes ReDim alles löscht, was es hielt
  • ReDim Preserve — wie Sie ein Array vergrößern und die Daten behalten
  • Die Falle Nummer eins: ReDim Preserve kann nur die letzte Dimension eines 2D-Arrays ändern
  • Warum Sie ein Array mit fester Größe nicht mit ReDim ändern können und was Erase wirklich tut
  • Warum es langsam ist, ein Array in einer Schleife Zeile für Zeile wachsen zu lassen, und was Sie stattdessen tun

Das Denkmodell: fest beim Dim oder offen mit leeren Klammern

Jedes VBA-Array ist von einer von zwei Arten, und Sie wählen bei der Deklaration, welche:

Dim fixed(1 To 10) As Long   ' FEST - 10 Plaetze, fuer immer; Groesse gehoert zum Typ
Dim flex() As Long           ' DYNAMISCH - noch keine Groesse; Sie machen spaeter ReDim

Ein Array mit fester Größe wird einmal dimensioniert und ändert sich nie — die Größe steckt in der Deklaration, also lässt VBA Sie später kein ReDim darauf anwenden (Sie bekommen den Kompilierfehler «Array already dimensioned»). Ein dynamisches Array wird mit leeren Klammern deklariert: Es hat einen Typ, aber keine Größe, und ReDim ist der Weg, ihm eine zu geben. Diese eine Wahl — Klammern voll oder leer beim Dim — entscheidet alles Weitere auf dieser Seite. Wissen Sie noch nicht, wie viele Elemente Sie haben werden, deklarieren Sie es offen.

ReDim dimensioniert ein dynamisches Array

ReDim reserviert frischen Speicher für ein dynamisches Array. Sie können dasselbe Array so oft mit ReDim bearbeiten, wie Sie wollen, und jedes ReDim darf sogar die Grenzen ändern:

Dim a() As String
ReDim a(1 To 3)      ' 3 Elemente, Index 1..3
ReDim a(0 To 99)     ' jetzt 100 Elemente, Index 0..99

Eines müssen Sie im Kopf behalten, und es ist die Quelle der meisten „meine Daten sind weg"-Fehler: Ein blankes ReDim initialisiert das ganze Array neu. Jedes Element fällt auf seinen Standardwert zurück — 0 bei Zahlen, "" bei Zeichenketten, Nothing bei Objekten —, als hätten Sie es gerade erst erzeugt:

Dim a() As Long
ReDim a(1 To 3)
a(1) = 10: a(2) = 20: a(3) = 30
ReDim a(1 To 5)      ' a(1..3) sind wieder 0 - die Werte sind WEG

Wollten Sie die Daten behalten, ist genau das der Zweck von Preserve.

ReDim Preserve: vergrößern ohne Datenverlust

ReDim Preserve kopiert die vorhandenen Werte in das neu dimensionierte Array, bevor es zurückgegeben wird:

Dim a() As Long
ReDim a(1 To 3)
a(1) = 10: a(2) = 20: a(3) = 30
ReDim Preserve a(1 To 5)   ' a(1..3) halten noch 10, 20, 30; a(4), a(5) sind 0

Greifen Sie zu Preserve, wann immer Sie ein bereits gefülltes Array erweitern. Es funktioniert beim Vergrößern und beim Verkleinern — beim Verkleinern fallen einfach die Elemente jenseits der neuen Obergrenze weg. Die eine Regel, die Sie beachten müssen, betrifft die Dimensionen, und genau dort tappt fast jeder in die Falle.

Die Falle Nummer eins: Preserve ändert nur die letzte Dimension

Bei einem eindimensionalen Array darf ReDim Preserve die Grenze frei ändern. Bei einem zweidimensionalen Array kann ReDim Preserve nur die letzte Dimension ändern. Versuchen Sie, die erste zu ändern, wirft VBA Laufzeitfehler 9, «Subscript out of range»:

Dim g() As Long
ReDim g(1 To 3, 1 To 2)          ' 3 Zeilen, 2 Spalten
ReDim Preserve g(1 To 5, 1 To 2) ' Fehler 9 - die ERSTE Dimension laesst sich nicht aendern
ReDim Preserve g(1 To 3, 1 To 4) ' OK - die LETZTE (Spalten-)Dimension darf wachsen

Das ist kein Fehler, den Sie mit einem cleveren ReDim umschiffen können; so speichert VBA Arrays im Speicher. Es kollidiert auch mit der Intuition, denn ein Blatt ist Zeilen × Spalten, sodass das „Wachsen", das Sie meist wollen — Zeilen hinzufügen —, die erste Dimension betrifft, die eine, die Sie nicht anfassen dürfen. Zwei Auswege: Deklarieren Sie das Gitter als Spalten × Zeilen, damit die Dimension, die Sie vergrößern, die letzte ist, oder, häufiger, dimensionieren Sie das Array vor der Schleife einmal auf seine endgültige Zeilenzahl und lassen Sie Preserve ganz weg. Müssen Sie wirklich Zeilen zu einem bestehenden 2D-Array hinzufügen, bauen Sie es neu auf (oder transponieren, die letzte Dimension ändern, zurücktransponieren). Mehr dazu unter VBA 2D Arrays.

Ein Array mit fester Größe lässt sich nicht mit ReDim ändern

ReDim ist nur für Arrays da, die mit leeren Klammern deklariert wurden. Haben Sie das Array in seinem Dim dimensioniert, ist die Größe in die Deklaration eingebacken und ReDim ein Kompilierfehler:

Dim a(1 To 10) As Long
ReDim a(1 To 20)      ' Kompilierfehler - "Array already dimensioned"

Ertappen Sie sich beim Wunsch, ein Array in der Größe zu ändern, ist das das Signal, dass es von vornherein dynamisch (Dim a()) hätte deklariert werden sollen. Ein dynamisches Array, das Sie einmal mit ReDim bearbeiten — direkt nachdem Sie die Anzahl kennen —, gibt Ihnen das Beste aus beiden Welten: eine saubere, feste Arbeitsgröße, zur Laufzeit gewählt.

Erase: zurücksetzen oder freigeben

Erase tut je nach Art des Arrays zweierlei. Bei einem Array mit fester Größe setzt es jedes Element auf seinen Standardwert zurück, behält aber die Größe. Bei einem dynamischen Array geht es weiter — es gibt den Speicher frei und versetzt das Array in seinen dimensionslosen Zustand zurück, als hätten Sie nur Dim a() geschrieben:

Dim fixed(1 To 3) As Long
Erase fixed            ' alle drei Elemente sind wieder 0; weiter Groesse 3

Dim flex() As Long
ReDim flex(1 To 3)
Erase flex             ' Speicher frei; flex hat wieder keine Groesse - ReDim vor Wiederverwendung

Nachdem Sie ein dynamisches Array geleert haben, löst ein UBound darauf Fehler 9 aus, bis Sie es erneut mit ReDim dimensionieren — das Array hat schlicht keine Grenzen mehr, die es melden könnte.

Einmal dimensionieren, nicht Stück für Stück wachsen

Weil jedes ReDim Preserve einen neuen Block reserviert und den alten Inhalt hineinkopiert, macht das Vergrößern eines Arrays um eins bei jedem Schleifendurchlauf aus einer O(n)-Aufgabe eine O(n²) — in Ordnung für 50 Elemente, schmerzhaft für 50.000. Die idiomatische Lösung: Dimensionieren Sie das Array einmal im Voraus, mit einer Anzahl, die Sie bereits haben (eine letzte Zeile, eine Collection-Größe), und kürzen Sie erst am Ende, falls nötig:

Dim a() As Long, n As Long, i As Long
n = Cells(Rows.Count, 1).End(xlUp).Row   ' wie viele Datenzeilen
ReDim a(1 To n)                          ' eine einzige Zuweisung
For i = 1 To n
    a(i) = Cells(i, 1).Value
Next i

Wenn Sie die Anzahl wirklich nicht im Voraus wissen können, ist ein gängiges Muster, in großzügigen Blöcken ReDim zu machen (etwa die Größe zu verdoppeln, wenn der Platz ausgeht) und am Ende einmal mit ReDim Preserve auf die genaue Anzahl herunterzugehen — weit weniger Kopiervorgänge als beim Wachsen um eins.

Wie ExcelMaster hilft

Die ganze ReDim-Geschichte ist eine Entscheidung — hat dieses Array eine feste Größe oder wächst es? —, und die zwei klassischen Fehler sind ein blankes ReDim, das Ihre Daten still löscht, und ein ReDim Preserve, das an der falschen Dimension auf Fehler 9 läuft.

ExcelMaster lässt Sie die Aufgabe beschreiben — „lies Spalte A in ein Array ein, behalte die nicht leeren Werte, schreib sie in Spalte C" — und deklariert das Array dynamisch, dimensioniert es einmal aus der echten Zeilenzahl, nutzt ReDim Preserve nur dort, wo die Dimension es erlaubt, und liest den Bereich in einem Rutsch statt Zelle für Zelle. Sie behalten die Arbeitsmappe und den Code.

Häufig gestellte Fragen

Was macht ReDim in VBA?

ReDim setzt oder ändert die Größe eines dynamischen Arrays — eines, das mit leeren Klammern deklariert wurde, etwa Dim a() As Long. ReDim a(1 To 10) gibt dem Array zehn Elemente. Sie können dasselbe Array wiederholt mit ReDim bearbeiten, und jedes ReDim darf die Grenzen ändern. Ein blankes ReDim initialisiert außerdem jedes Element auf seinen Standardwert neu, nutzen Sie also ReDim Preserve, wenn Sie die vorhandenen Daten behalten müssen.

Was ist der Unterschied zwischen ReDim und ReDim Preserve?

Ein blankes ReDim reserviert die neue Größe und setzt jedes Element auf seinen Standardwert zurück, wobei alles verworfen wird, was das Array hielt. ReDim Preserve kopiert zuerst die vorhandenen Werte in das neu dimensionierte Array, sodass die Daten überleben. Nutzen Sie ein blankes ReDim für die erste Dimensionierung und ReDim Preserve, wann immer Sie ein bereits gefülltes Array erweitern.

Warum gibt ReDim Preserve bei einem 2D-Array Fehler 9?

Weil ReDim Preserve nur die letzte Dimension eines mehrdimensionalen Arrays ändern kann. Die erste Dimension zu ändern löst Laufzeitfehler 9 aus, «Subscript out of range». Um einem Gitter „Zeilen" hinzuzufügen, deklarieren Sie es entweder als Spalten × Zeilen, sodass die wachsende Dimension die letzte ist, dimensionieren es vor der Schleife auf seine endgültige Zeilenzahl, oder bauen das Array neu auf.

Kann ich ein Array mit fester Größe mit ReDim ändern?

Nein. Haben Sie das Array mit einer Größe deklariert, etwa Dim a(1 To 10), ist diese Größe Teil des Typs und ReDim ein Kompilierfehler, «Array already dimensioned». Nur Arrays, die mit leeren Klammern (Dim a()) deklariert wurden, lassen sich mit ReDim dimensionieren und in der Größe ändern.

Wie füge ich einem VBA-Array ein Element hinzu?

Führen Sie die Anzahl selbst mit und machen Sie ReDim Preserve, um Platz zu schaffen: ReDim Preserve a(1 To n + 1): a(n + 1) = value: n = n + 1. Das funktioniert, aber bei jedem Element neu zu dimensionieren ist langsam, weil jedes ReDim Preserve das ganze Array kopiert. Für große Schleifen dimensionieren Sie das Array einmal aus einer bekannten Anzahl, oder vergrößern es in Blöcken und kürzen einmal am Ende. Eine Collection ist oft einfacher, wenn die Anzahl wirklich unbekannt ist.

Getestet in

Getestet in: Excel 365 (Windows 11), VBA 7.1 — zuletzt geprüft am 24.09.2026.

Verwandte Anleitungen: VBA UBound · VBA 2D Arrays · VBA Array · VBA Dim · VBA For Loop