Ein Array ist eine Variable, die viele Werte desselben Typs unter einem Namen speichert. Statt zehn einzelne Variablen anzulegen, hast du einen Behälter mit zehn nummerierten Fächern — auf jedes greifst du über seinen Index zu.
Statisches Array deklarieren
Bei einem statischen Array steht die Größe schon beim Deklarieren fest. Du gibst die Ober- (und optional Unter-)grenze in Klammern an:
Option Explicit
Public Sub StatischesArray()
Dim werte(1 To 10) As Long ' 10 Fächer: Index 1 bis 10
werte(1) = 100
werte(2) = 200
werte(10) = 999
Debug.Print werte(2) ' 200
End Sub
Mit 1 To 10 legst du Unter- und Obergrenze explizit fest. Das ist die klarste
Schreibweise, weil du sofort siehst, welche Indizes gültig sind.
0-basiert oder 1-basiert?
Schreibst du nur Dim werte(10), meint VBA nicht zehn Fächer, sondern die
Indizes 0 bis 10 — also elf Fächer. Denn ohne To beginnt die Zählung
standardmäßig bei 0:
Dim a(10) As Long ' Index 0 bis 10 -> 11 Elemente!
Dim b(1 To 10) As Long ' Index 1 bis 10 -> 10 Elemente
Mit Option Base 1 ganz oben im Modul verschiebst du die Standard-Untergrenze
auf 1:
Option Base 1
Public Sub MitBaseEins()
Dim a(10) As Long ' jetzt Index 1 bis 10
Debug.Print LBound(a) ' 1
End Sub
Option Base 1gilt nur für das Modul, in dem es steht, und nicht für Arrays ausArray()oderSplit(). Verlass dich lieber nicht darauf, sondern schreib Grenzen mit1 To …explizit hin — dann ist der Code überall eindeutig.
Grenzen abfragen mit UBound und LBound
UBound liefert den höchsten, LBound den niedrigsten gültigen Index. So
durchläufst du ein Array, ohne die Größe fest einzutippen:
Dim werte(1 To 5) As Long
Dim i As Long
For i = LBound(werte) To UBound(werte)
werte(i) = i * 10
Next i
Debug.Print LBound(werte) ' 1
Debug.Print UBound(werte) ' 5
Diese Schleife funktioniert unverändert, egal ob das Array 0- oder 1-basiert ist
oder später seine Größe ändert. Genau deshalb nimmst du LBound/UBound statt
fester Zahlen.
Mehrdimensionale Arrays
Ein Array kann mehrere Dimensionen haben — praktisch für Tabellen (Zeilen × Spalten). Die Indizes trennst du mit Komma:
Dim matrix(1 To 3, 1 To 2) As String ' 3 Zeilen, 2 Spalten
matrix(1, 1) = "Meier"
matrix(1, 2) = "Berlin"
matrix(2, 1) = "Schmidt"
matrix(2, 2) = "Hamburg"
' Bei mehreren Dimensionen brauchst du die Dimensionsnummer:
Debug.Print UBound(matrix, 1) ' 3 (erste Dimension)
Debug.Print UBound(matrix, 2) ' 2 (zweite Dimension)
Bei UBound/LBound gibst du als zweiten Parameter die Dimension an. Ohne
Angabe wird immer die erste Dimension genommen.
Dynamische Arrays mit ReDim
Oft kennst du die Größe erst zur Laufzeit — etwa die Anzahl gefundener Datensätze.
Dann deklarierst du das Array mit leeren Klammern und legst die Größe später mit
ReDim fest:
Public Sub DynamischesArray()
Dim namen() As String ' noch ohne Größe
Dim anzahl As Long
anzahl = 3
ReDim namen(1 To anzahl) ' Größe zur Laufzeit setzen
namen(1) = "Anna"
namen(2) = "Ben"
namen(3) = "Carla"
End Sub
ReDim legt das Array komplett neu an. Alle bisherigen Werte gehen dabei
verloren — das Array wird auf leere Standardwerte zurückgesetzt.
ReDim Preserve — Werte behalten
Willst du die vorhandenen Werte behalten und das Array nur vergrößern, hängst du
Preserve an:
Dim werte() As Long
Dim i As Long
ReDim werte(1 To 3)
werte(1) = 10: werte(2) = 20: werte(3) = 30
ReDim Preserve werte(1 To 5) ' auf 5 vergrößern, 10/20/30 bleiben
werte(4) = 40
werte(5) = 50
For i = 1 To 5
Debug.Print werte(i) ' 10 20 30 40 50
Next i
Wichtig: Bei einem mehrdimensionalen Array darf
ReDim Preservenur die letzte Dimension ändern. Versuchst du eine andere zu ändern, gibt es Laufzeitfehler 9 ("Index außerhalb des gültigen Bereichs"). Und:Preservekopiert bei jedem Aufruf das ganze Array. In einer engen Schleife ist das langsam — vergrößere lieber in größeren Schritten.
Array() — schnell befüllen
Mit der Funktion Array() erzeugst du ein Array direkt aus einer Werteliste. Das
Ziel muss dabei ein Variant sein:
Dim tage As Variant
tage = Array("Mo", "Di", "Mi", "Do", "Fr")
Debug.Print tage(0) ' Mo (Array() ist immer 0-basiert)
Debug.Print tage(4) ' Fr
Array() ignoriert Option Base 1 und beginnt immer bei 0.
Split() — Text in ein Array zerlegen
Split zerteilt einen String an einem Trennzeichen und liefert ein
0-basiertes String-Array zurück. Sehr nützlich für CSV-Zeilen oder
zusammengesetzte Schlüssel:
Dim zeile As String
Dim felder() As String
Dim i As Long
zeile = "Meier;Berlin;1985"
felder = Split(zeile, ";")
For i = LBound(felder) To UBound(felder)
Debug.Print i & ": " & felder(i)
Next i
' 0: Meier
' 1: Berlin
' 2: 1985
Das Gegenstück ist Join(felder, ";"), das aus einem Array wieder einen String
mit Trennzeichen baut.
Über ein Array iterieren
Du kannst ein Array mit einer klassischen For-Schleife über den Index oder mit
For Each ohne Index durchlaufen:
Dim farben As Variant
Dim f As Variant
farben = Array("rot", "grün", "blau")
' Variante 1: mit Index
Dim i As Long
For i = LBound(farben) To UBound(farben)
Debug.Print farben(i)
Next i
' Variante 2: For Each (nur Lesen, kein Schreiben ins Array)
For Each f In farben
Debug.Print f
Next f
For Each ist kürzer, aber du kannst damit die Elemente nur lesen, nicht
überschreiben. Zum Ändern brauchst du den Index.
Erase — Array leeren
Erase setzt ein Array zurück. Bei einem dynamischen Array wird der Speicher
komplett freigegeben — danach musst du erneut ReDim aufrufen. Bei einem
statischen Array bleiben die Fächer erhalten, ihre Werte werden nur
zurückgesetzt (Zahlen auf 0, Strings auf ""):
Dim dyn() As Long
ReDim dyn(1 To 3)
Erase dyn ' Array ist jetzt wieder "leer", braucht neues ReDim
Dim stat(1 To 3) As Long
stat(1) = 99
Erase stat ' stat(1) ist wieder 0, Array behält 3 Fächer
Typische Fehler
Index außerhalb des gültigen Bereichs (Laufzeitfehler 9) ist der Klassiker. Er entsteht, wenn du auf einen Index zugreifst, den es nicht gibt:
Dim a(1 To 3) As Long
a(4) = 10 ' Fehler 9: Index 4 existiert nicht
a(0) = 10 ' Fehler 9: Untergrenze ist 1, nicht 0
Häufige Ursachen und wie du sie vermeidest:
| Ursache | Lösung |
|---|---|
Off-by-one (0 vs 1) | Grenzen mit 1 To … explizit setzen |
| Feste Zahl statt Grenze | LBound/UBound in Schleifen nutzen |
Zugriff vor ReDim | Dynamisches Array erst dimensionieren |
Preserve auf falscher Dimension | Nur letzte Dimension ändern |
Ein leeres, noch nicht dimensioniertes dynamisches Array hat übrigens gar keine
gültigen Grenzen — ein UBound darauf löst ebenfalls Fehler 9 aus. Wenn du
unsicher bist, kannst du das vorher prüfen, z. B. über einen Zähler, den du beim
Befüllen mitführst.
Zusammengefasst
Dim a(1 To 10) As Longist ein statisches Array; ohneTobeginnt der Index bei0.Option Base 1verschiebt die Standard-Untergrenze, gilt aber nicht fürArray()/Split()— Grenzen lieber explizit schreiben.- Dynamische Arrays mit
ReDimdimensionieren;ReDim Preservebehält Werte, darf aber nur die letzte Dimension ändern. LBound/UBoundmachen Schleifen unabhängig von der konkreten Größe;Array()undSplit()liefern fertige (0-basierte) Arrays.- Der häufigste Fehler ist "Index außerhalb des gültigen Bereichs" (Fehler 9) — meist ein Off-by-one bei den Grenzen.