Kurzfassung — In VBA zählen Sie ein Array nicht, Sie fragen es.
UBound(a)gibt den höchsten gültigen Index zurück;LBound(a)den niedrigsten. Arrays sind standardmäßig nullbasiert, also hältDim a(9)zehn Elemente mit den Indizes0bis9—UBoundist9, nicht10. Dieser Off-by-One-Fehler ist der mit Abstand häufigste Schleifenfehler. Die Schleife, die immer übersteht, lautetFor i = LBound(a) To UBound(a), und die wahre Länge istUBound(a) - LBound(a) + 1. Ein Array hat kein.Lengthund kein.Count.
Sub LoopSafely()
Dim a() As String
a = Split("red,green,blue", ",") ' Split liefert ein 0-basiertes Array
Dim i As Long
For i = LBound(a) To UBound(a) ' funktioniert unabhaengig von den Grenzen
Debug.Print i, a(i) ' 0 red / 1 green / 2 blue
Next i
Debug.Print "count = " & (UBound(a) - LBound(a) + 1) ' 3
End Sub
UBound ist der Weg, die Form eines Arrays zu lesen, und der Partner von ReDim:
Sie dimensionieren das Array und fragen dann, welche Größe dabei herauskam. Bekommen Sie die Grenzen
falsch, überspringen Sie entweder das letzte Element oder laufen über das Ende hinaus in Laufzeitfehler 9.
Weil verschiedene Quellen Ihnen Arrays mit unterschiedlichen Startindizes reichen, ist die Gewohnheit des
Fragens — statt 0 oder 1 anzunehmen — das, was Schleifen korrekt hält.
Was Sie lernen
- Was
UBoundundLBoundzurückgeben und warum ein Array keine.Length-Eigenschaft hat - Warum VBA-Arrays standardmäßig nullbasiert sind und woher der Off-by-One-Fehler kommt
- Die Schleife, die immer funktioniert:
For i = LBound(a) To UBound(a) - Die wahre Array-Länge:
UBound(a) - LBound(a) + 1 - Die Größe jeder Dimension eines 2D-Arrays mit
UBound(a, 2)ermitteln - Warum
UBoundauf einem leeren dynamischen Array Fehler 9 auslöst und wie Sie ihn absichern
UBound und LBound: fragen, nicht zählen
UBound (obere Grenze) gibt den größten Index zurück, den Sie legal verwenden dürfen; LBound (untere
Grenze) gibt den kleinsten. Zusammen beschreiben sie die Form des Arrays. VBA-Arrays haben bewusst
kein .Length und kein .Count — die Grenzen sind die maßgebliche Quelle, und Sie lesen sie zur
Laufzeit:
Dim a(1 To 5) As Long
Debug.Print LBound(a) ' 1
Debug.Print UBound(a) ' 5
Warum fragen statt sich merken? Weil das Array, über das Sie iterieren, oft anderswo dimensioniert wurde —
durch ein ReDim, durch Split, durch das Einlesen eines Bereichs — und die
Größe, die Sie zu haben glauben, fest zu verdrahten ist genau der Weg, wie Schleifen aus dem Tritt mit
der Wirklichkeit geraten.
Standardmäßig nullbasiert: wo der Off-by-One-Fehler wohnt
Sofern Sie nichts anderes sagen, beginnt ein VBA-Array bei Index 0. Dim a(9) gibt Ihnen also nicht
neun Elemente — es gibt Ihnen zehn, mit den Indizes 0 bis 9:
Dim a(9) As Long ' zehn Elemente: a(0) .. a(9)
Debug.Print LBound(a) ' 0
Debug.Print UBound(a) ' 9 <- nicht 10
Das ist die Wurzel des klassischen Fehlers. For i = 1 To UBound(a) überspringt still a(0);
For i = 0 To 10 läuft einen Schritt zu weit und trifft «Subscript out of range». Sie können mit
Option Base 1 für ein ganzes Modul einsbasierte Arrays erzwingen oder mit Dim a(1 To 10)
ausdrückliche Grenzen deklarieren — aber die eigentliche Lösung ist, den Start gar nicht mehr zu raten.
Die Schleife, die immer funktioniert
Schreiben Sie die Schleife anhand der eigenen Grenzen des Arrays, und sie ist korrekt, egal wie das Array deklariert wurde oder woher es kam:
Dim i As Long
For i = LBound(a) To UBound(a)
' ... a(i) verwenden ...
Next i
Diese eine Gewohnheit räumt die ganze Familie der Off-by-One-Fehler aus. Sie funktioniert für ein
nullbasiertes Split-Ergebnis, ein einsbasiertes Range.Value-Array, ein Option Base 1-Modul und ein
ausdrückliches Dim a(5 To 12) gleichermaßen. Verdrahten Sie nie 0 oder 1 als Start einer
Array-Schleife fest, wenn LBound Ihnen die Wahrheit gratis nennt.
Array-Länge: UBound minus LBound plus eins
Weil ein Array bei jedem beliebigen Index beginnen kann, ist seine Länge nicht einfach UBound + 1. Die
Formel, die immer stimmt, lautet:
Dim n As Long
n = UBound(a) - LBound(a) + 1
Für ein nullbasiertes Array aus zehn ist das 9 - 0 + 1 = 10; für Dim a(1 To 10) ist es
10 - 1 + 1 = 10. Nutzen Sie die volle Formel, dann ist es egal, welche Basis das Array verwendet. (Die
Leute suchen nach einer „VBA array length"-Eigenschaft; es gibt keine — dieser Ausdruck ist die Antwort.)
2D-Arrays: eine Grenze pro Dimension
Bei einem mehrdimensionalen Array nehmen UBound und LBound ein zweites Argument — welche Dimension Sie
abfragen. UBound(a, 1) ist die erste Dimension (Zeilen), UBound(a, 2) die zweite (Spalten):
Dim g(1 To 3, 1 To 4) As Long ' 3 Zeilen, 4 Spalten
Debug.Print UBound(g, 1) ' 3 (Zeilen)
Debug.Print UBound(g, 2) ' 4 (Spalten)
Dim r As Long, c As Long
For r = LBound(g, 1) To UBound(g, 1)
For c = LBound(g, 2) To UBound(g, 2)
' ... g(r, c) verwenden ...
Next c
Next r
Ein blankes UBound(g) ohne Dimensionsnummer gibt die erste Dimension zurück. Das zählt am meisten, wenn
Sie ein Blatt in ein Array einlesen, denn Range.Value reicht Ihnen stets ein
einsbasiertes 2D-Array — UBound(a, 1) und UBound(a, 2) zu fragen ist der Weg, herauszufinden, wie
viele Zeilen und Spalten Sie tatsächlich bekommen haben.
Das leere dynamische Array absichern
Ein dynamisches Array, das deklariert, aber nie mit ReDim dimensioniert wurde (oder eines, das mit
Erase geleert wurde), hat überhaupt keine Grenzen, und ein UBound darauf löst Laufzeitfehler 9
aus, «Subscript out of range»:
Dim a() As Long
Debug.Print UBound(a) ' Fehler 9 - das Array hat noch keine Groesse
Besteht auch nur die Chance, dass das Array leer ist — etwa weil es aus einem Filter kam, der nichts
traf —, sichern Sie es vor der Schleife ab. Ein kleiner Helfer hält den aufrufenden Code sauber:
Function IsAllocated(a As Variant) As Boolean
On Error Resume Next
IsAllocated = (LBound(a) <= UBound(a))
On Error GoTo 0
End Function
Dann If IsAllocated(a) Then For i = LBound(a) To UBound(a) .... Das ist der Array-Vetter davon, ein
Objekt mit Is Nothing abzusichern, bevor Sie es verwenden.
Wie ExcelMaster hilft
UBound ist eine kleine Funktion mit einer großen Aufgabe — einer Schleife genau zu sagen, wo sie
aufhören soll — und die Fehler drumherum (0 oder 1 annehmen, das leere Array vergessen, eine Länge
fest verdrahten) sind genau die, die ein Makro die letzte Zeile überspringen oder an einem Randfall
abstürzen lassen.
ExcelMaster lässt Sie die Aufgabe
beschreiben — „zieh den benutzten Bereich in ein Array, summiere jede Spalte, schreib die Summen
darunter" — und iteriert von LBound bis UBound auf der richtigen Dimension, berechnet die Länge
korrekt und sichert ein Array ab, das leer zurückgekommen sein könnte, sodass das Makro in der ersten
Zeile, der letzten Zeile und im leeren Fall stimmt. Sie behalten die Arbeitsmappe und den Code.
Häufig gestellte Fragen
Was macht UBound in VBA?
UBound gibt den höchsten gültigen Index eines Arrays zurück — die größte Zahl, die Sie in den Klammern
verwenden dürfen. Für Dim a(1 To 5) ist UBound(a) gleich 5; für ein nullbasiertes Dim a(9) ist es
9. Kombinieren Sie es mit LBound, das den niedrigsten Index zurückgibt, um über ein Array zu
iterieren, ohne seine Größe fest zu verdrahten.
Wie ermittle ich die Länge eines Arrays in VBA?
Ein VBA-Array hat keine .Length- oder .Count-Eigenschaft. Berechnen Sie die Anzahl als
UBound(a) - LBound(a) + 1. Die volle Formel ist nötig, weil ein VBA-Array bei Index 0, 1 oder jeder
ausdrücklichen unteren Grenze beginnen kann, sodass UBound + 1 nur für nullbasierte Arrays stimmt.
Warum bekomme ich den Fehler Subscript out of range mit UBound?
Meist, weil das Array leer ist — ein dynamisches Array, das mit Dim a() deklariert, aber nie mit
ReDim dimensioniert wurde, oder eines, das mit Erase geleert wurde, hat keine Grenzen, sodass
UBound Laufzeitfehler 9 auslöst. Sichern Sie es mit einem kleinen IsAllocated-Helfer ab, bevor Sie
iterieren. Sie sehen Fehler 9 auch, wenn eine Schleife über UBound hinausläuft, etwa For i = 0 To 10
bei einem nullbasierten Array aus zehn Elementen.
Sind VBA-Arrays nullbasiert oder einsbasiert?
Standardmäßig nullbasiert: Dim a(9) hält zehn Elemente mit den Indizes 0 bis 9. Sie können ein Modul
mit Option Base 1 einsbasiert machen oder mit Dim a(1 To 10) ausdrückliche Grenzen setzen. Von
Split und Array zurückgegebene Arrays sind nullbasiert; ein aus Range.Value gelesenes Array ist
einsbasiert. Weil es variiert, iterieren Sie mit LBound bis UBound, statt etwas anzunehmen.
Wie finde ich die Größe eines 2D-Arrays in VBA?
Übergeben Sie die Dimensionsnummer als zweites Argument: UBound(a, 1) für die erste Dimension (Zeilen)
und UBound(a, 2) für die zweite (Spalten), mit LBound(a, 1) und LBound(a, 2) für die unteren
Grenzen. So lesen Sie die Form eines 2D-Arrays, das Range.Value zurückgibt.
Getestet in
Getestet in: Excel 365 (Windows 11), VBA 7.1 — zuletzt geprüft am 24.09.2026.
Verwandte Anleitungen: VBA ReDim · VBA 2D Arrays · VBA Array · VBA For Loop · VBA Split
