Getestet mit: Excel 365 v2509 · Excel 2021 · Excel 2019 · zuletzt geprüft am 05.06.2026
Kurz gesagt — Range ist das Objekt, das auf eine oder mehrere Zellen zeigt. Mit .Value lesen Sie es, genauso schreiben Sie es. Kein .Select nötig:
Sub RangeGrundlagen()
' Eine einzelne Zelle LESEN
Dim menge As Long
menge = Range("B2").Value
' Eine einzelne Zelle SCHREIBEN
Range("C2").Value = menge * 1.1
' Einen ganzen Block auf einmal SCHREIBEN (ohne Schleife)
Range("A1:C1").Value = Array("Produkt", "Menge", "Preis")
End Sub
Alles andere — Cells, End, CurrentRegion, Resize — ist nur eine andere Art, Range die gemeinten Zellen zu übergeben. Diese Anleitung zeigt die acht, die Sie wirklich brauchen.
Alle Beispiele gehen von einer kleinen Tabelle in Tabelle1 aus: Überschriften Produkt / Menge / Preis in A1:C1, Daten ab Zeile 2.
Was das Range-Objekt wirklich ist
Range ist das meistgenutzte Objekt in Excel VBA. Es steht für eine Zelle, einen Zellblock, eine ganze Zeile oder Spalte oder sogar mehrere getrennte Blöcke. Fast alles, was Sie tun — einen Wert lesen, eine Formel schreiben, eine Farbe ändern, kopieren, sortieren — ist eine Methode oder Eigenschaft, die Sie auf einem Range aufrufen.
Range("A2").Value = "Widget" ' Eigenschaft einer Zelle
Range("A2:C2").Interior.Color = vbYellow ' Eigenschaft dreier Zellen
Range("A:A").Columns.AutoFit ' Eigenschaft einer ganzen Spalte
Beispiel 1 — Range gegen Cells (wann welches?)
Beide zeigen auf Zellen. Der Unterschied liegt in der Adressierung.
| Am besten für | Syntax | |
|---|---|---|
Range("A2") |
Eine feste, lesbare Adresse | Textadresse wie im Namensfeld |
Cells(2, 1) |
Eine aus Zahlen berechnete Position | Cells(Zeile, Spalte) — Zeile zuerst |
' Diese beiden Zeilen treffen DIESELBE Zelle (Zeile 2, Spalte 1):
Range("A2").Value = "Widget"
Cells(2, 1).Value = "Widget"
Nehmen Sie Range, wenn Sie die Adresse kennen. Nehmen Sie Cells in Schleifen, wo Zeile oder Spalte variabel sind:
Dim z As Long
For z = 2 To 6
Cells(z, 3).Value = Cells(z, 2).Value * 1.1 ' Preis = Menge * 1.1
Next z
Sie lassen sich sogar kombinieren — Range(Cells(2, 1), Cells(6, 3)) baut den Block A2:C6 aus zwei Eckzellen, ideal bei berechneten Ecken.
Beispiel 2 — .Value gegen .Value2 gegen .Text gegen .Formula
Das ist die Falle, in die jeder Anfänger tappt. Dieselbe Zelle liefert vier verschiedene Dinge:
' Zelle B2 zeigt "1.250,00 €" aus der Formel =A2*5
Debug.Print Range("B2").Value ' 1250 (ein Währungs-/Datums-bewusster Variant)
Debug.Print Range("B2").Value2 ' 1250 (ein reiner Double — am schnellsten)
Debug.Print Range("B2").Text ' "1.250,00 €" (was der Nutzer SIEHT, als Text)
Debug.Print Range("B2").Formula ' "=A2*5" (der Formeltext)
Faustregeln:
.Value2— beim Lesen großer Bereiche oder beim Rechnen. Es überspringt die Währungs-/Datumsumwandlung, ist daher schneller und überrascht Sie nie mit einem gerundeten Währungswert..Text— quasi schreibgeschützt, liefert die angezeigte Zeichenfolge. Vorsicht: Ist die Spalte zu schmal, kommt"####"zurück..Formula— liest oder schreibt die Formel, nicht das Ergebnis.
Beispiel 3 — Schluss mit .Select (das Anti-Muster Nr. 1)
Der Makrorekorder schreibt überall .Select. Echte Makros tun das nicht. Auswählen ist langsam, flackert und bricht, sobald das falsche Blatt aktiv ist.
' ❌ Rekorder-Stil — fragil und langsam
Range("A2").Select
Selection.Value = "Widget"
' ✅ Direkt auf dem Range arbeiten
Range("A2").Value = "Widget"
Qualifizieren Sie das Blatt, statt es auszuwählen — so läuft der Code unabhängig davon, was gerade angezeigt wird:
ThisWorkbook.Worksheets("Tabelle1").Range("A2").Value = "Widget"
Beispiel 4 — Die letzte Zeile finden (die Standardformel)
Ein fest verdrahtetes A2:A100 bricht, sobald die Daten wachsen. Diese Zeile findet die echte letzte belegte Zeile in Spalte A:
Dim letzteZeile As Long
letzteZeile = Cells(Rows.Count, 1).End(xlUp).Row ' von ganz unten hochspringen
MsgBox "Daten enden in Zeile " & letzteZeile
End(xlUp) ahmt Strg + ↑ nach. Es ist der zuverlässigste Weg, einen Bereich an die Daten anzupassen.
Beispiel 5 — Dynamische Bereiche mit CurrentRegion
CurrentRegion greift den gesamten zusammenhängenden Block um eine Zelle — genau das, was Strg + Umschalt + Pfeiltasten auswählt. Kein Zeilenzählen nötig:
Dim daten As Range
Set daten = Range("A1").CurrentRegion ' die ganze Tabelle samt Überschriften
MsgBox daten.Rows.Count & " Zeilen × " & daten.Columns.Count & " Spalten"
' Überschrift überspringen — eins nach unten (Offset), eins kürzer (Resize):
Dim rumpf As Range
Set rumpf = daten.Offset(1, 0).Resize(daten.Rows.Count - 1)
Offset(Zeilen, Spalten) verschiebt einen Bereich; Resize(Zeilen, Spalten) ändert seine Größe. Zusammen schneiden Sie eine Überschrift ab, fügen eine Spalte hinzu oder vergrößern einen Block — ganz ohne fest verdrahtete Adresse.
Beispiel 6 — Einen Bereich lesbar durchlaufen
Wenn Sie jede Zelle wollen, ist For Each sauberer als Indexrechnerei:
Dim zelle As Range
For Each zelle In Range("B2:B6")
If zelle.Value > 100 Then zelle.Interior.Color = vbGreen
Next zelle
Beispiel 7 — Einen ganzen Bereich in ein Array lesen (der schnelle Weg)
Hier ist das Geheimnis der Profis: Tausende Zugriffe auf das Tabellenblatt sind langsam. Lesen Sie den gesamten Bereich in einem Zug in den Speicher, arbeiten Sie dort und schreiben Sie einmal zurück. Bei 10.000 Zeilen ist das der Unterschied zwischen 8 Sekunden und 0,1:
Sub SchnellerBereich()
Dim arr As Variant
arr = Range("A2:C10000").Value2 ' EIN Lesen -> 2D-Array (1-basiert)
Dim i As Long
For i = 1 To UBound(arr, 1)
arr(i, 3) = arr(i, 2) * 1.1 ' im Speicher rechnen, keine Zellzugriffe
Next i
Range("A2:C10000").Value2 = arr ' EIN Schreiben
End Sub
Der Trick arr = IrgendeinBereich.Value2 ist so wichtig, dass er eine eigene Anleitung hat.
Beispiel 8 — Getrennte Bereiche und benannte Bereiche
Ein Range kann mehrere getrennte Blöcke umfassen (eine Union), und Sie können einen benannten Bereich über seinen Namen ansprechen:
' Zwei getrennte Blöcke, gemeinsam eingefärbt:
Range("A2:A6, C2:C6").Interior.Color = vbCyan
' Ein im Namensfeld benannter Bereich "Steuersatz":
Range("Steuersatz").Value = 0.2
Häufige Range-Fehler (und die Lösung)
| Symptom | Ursache | Lösung |
|---|---|---|
| Falsches Blatt wird bearbeitet | Range(...) ohne Blattangabe nutzt das aktive Blatt |
ThisWorkbook.Worksheets("Tabelle1").Range(...) voranstellen |
Cells(1, 2) trifft die falsche Zelle |
Cells ist (Zeile, Spalte), nicht (Spalte, Zeile) |
Die Zeilennummer kommt zuerst |
| Schleife quälend langsam | Jede Zelle einzeln lesen/schreiben | In ein Array laden (Beispiel 7) |
.Text liefert "####" |
Spalte zu schmal für den Wert | .Value2 statt .Text lesen |
| Bereich endet zu früh nach Wachstum | Fest verdrahtetes A2:A100 |
Mit End(xlUp) oder CurrentRegion dimensionieren |
Schluss mit Range-Klempnerei — beschreiben Sie das Ergebnis
Range, Cells, End, Resize — viel Klempnerei, nur um eine Zahlenspalte zu bewegen. ExcelMaster Agent lässt Sie es in klarem Deutsch sagen — „multipliziere in Tabelle1 jede Menge in Spalte B mit 1,1 und schreibe das Ergebnis in Spalte C, für so viele Zeilen wie vorhanden" — und erzeugt bereichssicheren Code, der die letzte Zeile, die Überschrift und die Aktiv-Blatt-Falle schon berücksichtigt. Kostenlos testen →
Weitere Anleitungen
- VBA Array in Excel — einen Bereich 100× schneller lesen
- VBA Dictionary in Excel — Nachschlagen, Duplikate entfernen & Gruppieren
- VBA For-Schleife in Excel — 8 Praxisbeispiele
FAQ
Was ist der Unterschied zwischen Range und Cells in VBA?
Beide zeigen auf Zellen. Range("A2") nutzt eine Textadresse; Cells(2, 1) nutzt numerische (Zeile, Spalte)-Koordinaten — ideal in Schleifen, wo die Position variabel ist. Range(Cells(2,1), Cells(6,3)) kombiniert beides zu einem Block aus berechneten Ecken.
Soll ich .Value oder .Value2 in VBA verwenden?
Nehmen Sie .Value2 zum Lesen großer Bereiche und zum Rechnen — es liefert einen reinen Double, überspringt die Währungs-/Datumsumwandlung und ist schneller. .Value brauchen Sie nur, wenn Sie ausdrücklich Währungs- oder Datumstypisierung wollen.
Wie spreche ich einen Bereich mit variabler Zeile und Spalte an?
Mit Cells(Zeile, Spalte) und Variablen oder Range(Cells(z1, s1), Cells(z2, s2)) für einen Block. Die letzte Zeile finden Sie mit Cells(Rows.Count, 1).End(xlUp).Row.
Wie spreche ich eine ganze Tabelle an, ohne ihre Größe zu kennen?
Range("A1").CurrentRegion liefert den gesamten zusammenhängenden Block. Um die Überschrift wegzulassen: .Offset(1, 0).Resize(.Rows.Count - 1).
Warum sollte ich .Select in VBA vermeiden?
.Select ist langsam, lässt den Bildschirm flackern und hängt davon ab, dass das richtige Blatt aktiv ist. Arbeiten Sie direkt auf dem Bereich — Range("A2").Value = "x" — und qualifizieren Sie ihn mit dem Tabellenblatt.
