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

VBA Zeilen löschen in Excel — Zeilen, Leerzeilen und Zeilen nach Bedingung löschen (rückwärts schleifen!)

|

VBA Zeilen löschen in Excel — Zeilen, Leerzeilen und Zeilen nach Bedingung löschen (rückwärts schleifen!)

Kurz gesagt — Eine Zeile zu löschen ist eine strukturelle Bearbeitung: Sie leert die Zeile nicht, sie entfernt sie und schiebt jede Zeile darunter um eins nach oben. Diese eine Tatsache steckt hinter dem häufigsten VBA-Bug überhaupt — eine vorwärts laufende Schleife, die Zeilen löscht, überspringt jede Zeile, die auf eine gelöschte folgte, weil sich die Zeilennummern unter der Schleife verschieben. Die Lösung ist ein Wort: schleifen Sie rückwärts (For i = last To first Step -1). Löschen Sie die ganze Zeile mit .EntireRow.Delete, und sammeln Sie viele verstreute Zeilen in einem einzigen Union und löschen Sie einmal — das ist schneller und umgeht das Verschiebeproblem vollständig.

' Jede Zeile löschen, deren Spalte A leer ist - von UNTEN nach OBEN schleifen.
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Data")
Dim lastRow As Long, i As Long
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row

For i = lastRow To 2 Step -1                 ' <-- rückwärts, sonst überspringen Sie Zeilen
    If Trim(ws.Cells(i, "A").Value) = "" Then ws.Rows(i).EntireRow.Delete
Next i

„Diese Zeilen löschen“ klingt nach der einfachsten Aufgabe der Excel-Automatisierung, und es ist die, an der fast jeder beim ersten Mal scheitert. Der Grund ist nicht die Delete-Methode — es ist, dass das Löschen genau das verändert, worüber Sie gerade schleifen. Stimmt die Laufrichtung, ist das Löschen nach Bedingung trivial; stimmt sie nicht, lässt Ihr Makro klammheimlich die Hälfte der passenden Zeilen zurück. Diese Anleitung dreht sich um diese eine Idee und die praktischen Muster, die daraus folgen.

Was Sie lernen

  • Das mentale Modell — Löschen entfernt eine Zeile und schiebt alles darunter nach oben
  • Die wichtigste Regel — schleifen Sie rückwärts, sonst überspringt eine vorwärts laufende Schleife Zeilen
  • Warum .EntireRow.Delete das sichere Ziel ist und was .Delete auf einer Zelle stattdessen anrichtet
  • Das schnellere Muster für verstreute Zeilen — ein Union bauen, einmal löschen
  • Leerzeilen entfernen und nach Bedingung löschen, ohne Verweisformeln zu zerstören

Das mentale Modell: Löschen verschiebt das Raster, es leert keine Zeile

Es gibt zwei völlig verschiedene Vorgänge, die beide „Löschen“ genannt werden. Ein Druck auf Entf leert eine Zelle — die Zeile bleibt, der Wert verschwindet. Rechtsklick ▸ Löschen oder Rows(i).Delete im Code entfernt die Zeile — die Zeile hört auf zu existieren, und jede Zeile darunter rutscht um eins nach oben und schließt die Lücke. Aus der ehemaligen Zeile 11 wird Zeile 10.

Dieses Schließen der Lücke ist die ganze Geschichte. Wenn Sie Zeile 10 löschen, sitzen die Daten von Zeile 11 nun in Zeile 10. Jeder Code, der annahm „Zeile 11 enthält noch, was sie eben enthielt“, liegt jetzt falsch. Deshalb fühlt sich das Löschen von Zeilen anders an als jede andere Schleife, die Sie schreiben: Die Adresse der noch nicht verarbeiteten Daten ändert sich in dem Moment, in dem Sie löschen. Sie bearbeiten das Koordinatensystem, während Sie es durchschreiten.

Behalten Sie dieses Bild im Kopf — unterhalb der gelöschten Zeile verschiebt sich alles nach oben — und jede Regel weiter unten ist nur eine Folge davon.

Die wichtigste Regel: rückwärts schleifen, sonst überspringen Sie Zeilen

Hier ist der Bug, geschrieben so, wie ihn fast jeder beim ersten Mal schreibt:

' FALSCH - eine vorwärts laufende Schleife über Zeilen, die Sie löschen.
For i = 2 To lastRow
    If ws.Cells(i, "A").Value = "DELETE" Then ws.Rows(i).EntireRow.Delete
Next i

Angenommen, die Zeilen 5 und 6 enthalten beide „DELETE“. Die Schleife erreicht i = 5, löscht Zeile 5, und Zeile 6 rutscht nach oben zur neuen Zeile 5. Doch die Schleife geht nun weiter zu i = 6 — das ist die Zeile, die früher Zeile 7 war. Die alte Zeile 6 wurde nie geprüft. Zwei benachbarte Treffer, und der zweite überlebt. Bei einem Block von Treffern bleibt ungefähr jeder zweite übrig, und das Symptom („einige Zeilen wurden nicht gelöscht“) wirkt zufällig.

Die Lösung kostet nichts. Laufen Sie von unten nach oben:

' RICHTIG - von der letzten Zeile zurück zur ersten löschen.
For i = lastRow To 2 Step -1
    If ws.Cells(i, "A").Value = "DELETE" Then ws.Rows(i).EntireRow.Delete
Next i

Rückwärts betrachtet schiebt das Löschen von Zeile 6 die Zeilen unterhalb von 6 nach oben — aber die haben Sie schon erledigt. Die noch nicht betrachteten Zeilen liegen alle oberhalb der gerade gelöschten, und ihre Nummern haben sich nicht bewegt. Das Verschieben passiert weiterhin; es passiert nur hinter Ihnen, wo es keinen Schaden anrichten kann. Sobald eine Schleife Zeilen löscht, läuft sie mit Step -1. Prägen Sie sich das ein, und die Hälfte aller Löschbugs verschwindet.

Die Regel, die Ihre Daten ausgerichtet hält: die Zeile löschen, nicht eine Zelle

Delete steht auf jedem Bereich zur Verfügung, und je kleiner der Bereich, desto gefährlicher ist es. Schreiben Sie ws.Cells(i, "A").Delete, löschen Sie eine einzelne Zelle, und Excel schiebt nur die Zellen darunter in Spalte A nach oben — während die Spalten B, C und D genau dort bleiben, wo sie waren. Jede Zeile von dort abwärts ist nun verschoben: Spalte A zeigt einen Datensatz, während B und C den darunterliegenden zeigen. Nichts wirft einen Fehler; Ihre Daten geraten einfach klammheimlich durcheinander.

Das Löschen der ganzen Zeile hält jede Spalte im Gleichschritt:

ws.Rows(i).EntireRow.Delete        ' die ganze Zeile 11 geht; 12, 13... rutschen zusammen nach oben
ws.Cells(i, "A").EntireRow.Delete  ' identisch - .EntireRow erweitert eine Zelle auf ihre ganze Zeile

.EntireRow ist die Erweiterung von „dieser Zelle“ zu „der ganzen Zeile, in der diese Zelle sitzt“, und genau das wollen Sie fast immer. Das nackte Range.Delete mit Shift:=xlUp/xlToLeft heben Sie sich für den seltenen Fall auf, in dem Sie wirklich einen Zellblock verschieben und nicht einen Datensatz entfernen wollen.

Das schnellere, sicherere Muster: einen Union sammeln und einmal löschen

Zeilenweises Schleifen und Löschen funktioniert, sobald Sie rückwärts schleifen, doch auf großen Blättern ist es langsam — jedes .Delete zwingt Excel, das Raster zu verschieben und neu zu berechnen. Es gibt ein Muster, das sowohl schneller als auch immun gegen die Verschiebefalle ist, weil es das gesamte Löschen in einem einzigen Schritt erledigt: Bauen Sie mit Union einen Range aus jeder zu entfernenden Zeile auf und löschen Sie am Ende alles auf einmal.

Dim victims As Range, i As Long
For i = 2 To lastRow                          ' Richtung egal - wir löschen später
    If ws.Cells(i, "A").Value = "DELETE" Then
        If victims Is Nothing Then
            Set victims = ws.Rows(i)
        Else
            Set victims = Union(victims, ws.Rows(i))
        End If
    End If
Next i

If Not victims Is Nothing Then victims.EntireRow.Delete   ' ein Löschvorgang, alle Zeilen auf einmal

Da keine Zeile entfernt wird, bevor die Schleife vorbei ist, bewegen sich die Zeilennummern während des Durchlaufs nie — eine vorwärts laufende Schleife ist hier also völlig sicher. Und ein einzelnes .Delete auf einem mehrflächigen Bereich ist dramatisch schneller als Hunderte einzelner Löschungen. Meine Faustregel: eine Handvoll Zeilen, rückwärts schleifen; Hunderte oder Tausende, einen Union sammeln (oder filtern — siehe unten) und einmal löschen. Verpacken Sie beides in Application.ScreenUpdating = False / Calculation = xlManual, und große Löschvorgänge gehen von Sekunden auf sofort.

Leerzeilen, Bedingungen und die Verweisfalle

Leerzeilen löschen hat einen Einzeiler, der jede Schleife schlägt — lassen Sie Excel die leeren Zellen finden:

On Error Resume Next   ' SpecialCells wirft 1004, wenn es keine leeren Zellen gibt
ws.Range("A2:A" & lastRow).SpecialCells(xlCellTypeBlanks).EntireRow.Delete
On Error GoTo 0

SpecialCells(xlCellTypeBlanks) liefert jede leere Zelle in Spalte A als einen mehrflächigen Bereich zurück, und .EntireRow.Delete entfernt all ihre Zeilen auf einen Schlag. Zwei Vorbehalte: Es richtet sich nach einer Spalte (eine Zeile mit leerem A, aber gefülltem B fliegt trotzdem raus), und es wirft einen Fehler, wenn es keine Leerzellen gibt — daher die On Error-Absicherung.

Löschen nach Bedingung bei großen Datenmengen: Der professionelle Zug ist AutoFilter — filtern Sie auf die unerwünschten Zeilen, löschen Sie die sichtbaren, entfernen Sie den Filter. Das ist der schnellste Ansatz von allen, weil Excel den Abgleich übernimmt:

With ws.Range("A1").CurrentRegion
    .AutoFilter Field:=1, Criteria1:="DELETE"
    .Offset(1).SpecialCells(xlCellTypeVisible).EntireRow.Delete  ' Kopfzeile überspringen
End With
ws.AutoFilterMode = False

Eine Falle überlebt sie alle: Das Löschen von Zeilen verschiebt Verweise. Zeigt eine Formel anderswo auf =A20 und Sie löschen Zeile 5, schreibt Excel sie zu =A19 um — meist genau das, was Sie wollen. Löschen Sie aber die Zeile, von der eine Formel abhängt, wird aus dieser Formel #REF!. Zeilen unter laufenden Formeln wegzulöschen ist die klassische Ursache für ein Blatt voller #REF!-Fehler; wissen Sie also vor einem Massenlöschen, ob irgendetwas weiter unten auf die Zeilen verweist, die Sie entfernen. Herauszufinden, wo Ihre Daten enden, ist eine verwandte Fertigkeit — siehe VBA Letzte Zeile.

Wie ExcelMaster hilft

Code zum Zeilenlöschen hat eine Handvoll stiller Fehlerquellen: die vorwärts laufende Schleife, die Zeilen überspringt, das Einzelzellen-Löschen, das Spalten verschiebt, den SpecialCells-Aufruf, der ohne Leerzellen abstürzt, das Massenlöschen, das #REF! hinterlässt. Keine davon wirft einen offensichtlichen Fehler — sie produzieren einfach leicht falsche Daten.

ExcelMaster lässt Sie stattdessen das Ergebnis beschreiben. Sagen Sie „lösche jede Zeile, in der Spalte A leer ist“ oder „entferne Zeilen, deren Status Storniert ist“, und es schreibt die Schleife in der sicheren Richtung (oder einen Union/Filter für große Datenmengen), zielt auf .EntireRow, sichert die Randfälle ab und legt zuerst eine Sicherung des Blatts an. Sie behalten die Arbeitsmappe und den Code; Sie sparen sich den Teil, in dem ein vergessenes Step -1 klammheimlich einen Bericht beschädigt.

Häufig gestellte Fragen

Warum überspringt meine VBA-Schleife beim Löschen Zeilen?

Weil das Löschen einer Zeile jede Zeile darunter um eins nach oben schiebt, eine vorwärts laufende Schleife aber weiter hochzählt. Nachdem Sie Zeile 5 gelöscht haben, wird aus der alten Zeile 6 die Zeile 5 — und die Schleife geht weiter zu Zeile 6 und überspringt sie. Schleifen Sie stattdessen rückwärts: For i = lastRow To 2 Step -1. Die noch nicht geprüften Zeilen liegen dann immer oberhalb der Löschung, ihre Nummern bewegen sich also nie.

Wie lösche ich in VBA eine ganze Zeile?

Nehmen Sie .EntireRow.Delete — zum Beispiel ws.Rows(11).EntireRow.Delete oder ws.Cells(11, "A").EntireRow.Delete. Beide entfernen die ganze Zeile, sodass jede Spalte ausgerichtet bleibt. Meiden Sie Cells(11, "A").Delete, das eine einzelne Zelle löscht und nur diese Spalte verschiebt, was den Rest durcheinanderbringt.

Was ist der schnellste Weg, viele Zeilen in VBA zu löschen?

Bei Hunderten oder Tausenden von Zeilen löschen Sie nicht einzeln. Filtern Sie entweder per AutoFilter auf die unerwünschten Zeilen und löschen Sie die sichtbaren Zellen in einem Schritt, oder bauen Sie während der Schleife einen Union aller Zielzeilen und rufen Sie am Ende einmal .EntireRow.Delete auf. Ein einzelnes Löschen mehrerer Zeilen ist weit schneller als viele einzelne, besonders bei abgeschaltetem ScreenUpdating und Calculation.

Wie lösche ich in VBA alle Leerzeilen?

ws.Range("A2:A" & lastRow).SpecialCells(xlCellTypeBlanks).EntireRow.Delete entfernt jede Zeile mit leerer Spalte A in einem Vorgang. Umschließen Sie es mit On Error Resume Next / On Error GoTo 0, weil SpecialCells einen Fehler wirft, wenn es keine leeren Zellen zu finden gibt.

Warum bekomme ich nach dem Löschen von Zeilen #REF!-Fehler?

Das Löschen von Zeilen verschiebt Zellbezüge. Formeln, die hinter die gelöschten Zeilen zeigen, werden automatisch neu nummeriert, doch jede Formel, die auf eine Zelle innerhalb einer gelöschten Zeile verwies, lässt sich nicht mehr auflösen und wird zu #REF!. Prüfen Sie vor einem Massenlöschen, ob andere Zellen von den Zeilen abhängen, die Sie gleich entfernen.

Getestet in

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

Verwandte Anleitungen: VBA Zeilen und Spalten einfügen · VBA Spalten und Zeilen ausblenden · VBA Letzte Zeile · VBA For-Schleife · VBA Range