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

VBA Worksheet_Change in Excel — Code ausführen, wenn eine Zelle bearbeitet wird (und die Endlosschleife, die Sie vermeiden müssen)

|

VBA Worksheet_Change in Excel — Code ausführen, wenn eine Zelle bearbeitet wird (und die Endlosschleife, die Sie vermeiden müssen)

TL;DRWorksheet_Change ist ein Ereignis, das Excel jedes Mal auslöst, wenn ein Benutzer (oder Ihr Code) eine Zelle auf diesem Blatt bearbeitet. Excel reicht Ihnen die geänderte Zelle als Target, sodass Sie reagieren können — die Zeile mit einem Zeitstempel versehen, die Eingabe prüfen, die Änderung protokollieren. Das eine, was Sie wissen müssen: Wenn Ihr Handler in eine Zelle schreibt, löst dieses Schreiben Worksheet_Change erneut aus — und wieder — bis Excel einfriert. Die Lösung ist ein einziges Zeilenpaar, Application.EnableEvents = False … = True, um jedes Schreiben herum. Verinnerlichen Sie diesen Reflex, und alles Übrige ist Detail.

' Liegt im eigenen Objekt des Blatts (z. B. Sheet1), NICHT in einem Module oder in ThisWorkbook.
Private Sub Worksheet_Change(ByVal Target As Range)
    If Intersect(Target, Range("B:B")) Is Nothing Then Exit Sub   ' nur auf Spalte B reagieren
    On Error GoTo Done
    Application.EnableEvents = False          ' verhindern, dass unser eigenes Schreiben dieses Ereignis erneut auslöst
    Target.Offset(0, 1).Value = Now          ' die Zeit neben der Bearbeitung eintragen
Done:
    Application.EnableEvents = True           ' Ereignisse IMMER wieder einschalten
End Sub

Auf Bearbeitungen zu reagieren ist der Punkt, an dem VBA aufhört, „Schaltflächen, die Makros ausführen“ zu sein, und lebendig zu wirken beginnt: Eine Zelle ändert sich, und das Blatt reagiert von selbst. Worksheet_Change ist das Ereignis, das Prüfprotokolle, automatische Zeitstempel, Live-Validierung und abhängige Dropdown-Listen antreibt. Es ist zugleich das Ereignis, das die panischsten „Excel ist eingefroren und ich habe meine Arbeit verloren“-Momente hervorruft — weil der naheliegende Code nur einen kleinen Schritt von einer Endlosschleife entfernt ist.

Was Sie lernen

  • Das mentale Modell — ein Bearbeitungssensor, der Ihnen die geänderte Zelle als Target reicht
  • Die Endlosschleifen-Falle — und die Application.EnableEvents-Lösung, die Ereignis-VBA prägt
  • Warum ein Absturz alle Ihre Ereignisse abschalten kann, bis Sie Excel neu starten
  • Wie Sie den Handler mit Intersect eingrenzen, damit er nicht bei jeder Bearbeitung läuft
  • Warum es Formel-Neuberechnungen ignoriert — und wann Sie stattdessen Worksheet_Calculate brauchen

Das mentale Modell: ein Bearbeitungssensor, keine Schaltfläche

Worksheet_Change ist ein Sensor, der mit dem Blatt verdrahtet ist. Sie rufen es nicht auf; in dem Moment, in dem sich der Inhalt einer Zelle ändert, ruft Excel Sie auf und übergibt die geänderte(n) Zelle(n) als Range namens Target. Ihre Aufgabe ist es, Target zu lesen und zu entscheiden, was damit zu tun ist.

Diese Sichtweise klärt zwei Dinge. Erstens ist Target Ihre gesamte Eingabe — es ist der Ort, an dem die Bearbeitung geschah, und es kann eine Zelle oder viele sein (ein Einfügen, ein Ausfüllen, ein Löschen über eine Auswahl hinweg kommen allesamt als mehrzelliges Target an). Zweitens liegt der Handler im Codeobjekt des betreffenden BlattsSheet1 im Projekt-Explorer, nicht ThisWorkbook und nicht ein Module. Die Signatur ist fest: Private Sub Worksheet_Change(ByVal Target As Range). (Die arbeitsmappenweite Variante, für alle Blätter auf einmal, ist Workbook_SheetChange in ThisWorkbook.)

Die Falle, die Excel einfrieren lässt: Ihr Schreiben löst das Ereignis erneut aus

Hier ist der Bug, den jeder VBA-Entwickler genau einmal schreibt. Sie wollen auf eine Bearbeitung reagieren, indem Sie etwas zurück ins Blatt schreiben:

Private Sub Worksheet_Change(ByVal Target As Range)
    Target.Offset(0, 1).Value = Now   ' neben die Bearbeitung schreiben ... was SELBST eine Bearbeitung ist
End Sub

Das Schreiben in Target.Offset(0, 1) ändert eine Zelle — was Worksheet_Change erneut auslöst —, dessen Schreiben es wieder auslöst — endlos. Excel ruft sich rekursiv auf, bis der Stapelspeicher erschöpft ist und ein Fehler geworfen wird, oder es wirkt einfach eingefroren. Das Change-Ereignis hat keinen eingebauten Schutz davor, auf seine eigene Reaktion zu reagieren.

Die Lösung ist das wichtigste Idiom in Ereignis-VBA: Schalten Sie Ereignisse um jedes Schreiben herum ab und danach wieder ein.

Private Sub Worksheet_Change(ByVal Target As Range)
    Application.EnableEvents = False
    Target.Offset(0, 1).Value = Now
    Application.EnableEvents = True
End Sub

Mit EnableEvents = False löst Ihr Schreiben kein neues Worksheet_Change aus, also gibt es keine Rekursion. Danach stellen Sie es wieder her. Brennen Sie sich die Regel ein: Umschließen Sie in jedem Ereignis, das in Zellen schreibt, das Schreiben mit Application.EnableEvents = False … = True.

Die Regel hinter der zweiten Hälfte der Falle: ein Absturz lässt Ereignisse abgeschaltet

Application.EnableEvents ist ein einziger, anwendungsweit globaler Schalter, und Excel stellt ihn nicht automatisch wieder her. Das schafft einen fiesen zweiten Fehlermodus: Läuft Ihr Handler nachdem er ihn auf False gesetzt hat, aber bevor er ihn zurücksetzt, in einen Fehler, bleiben Ereignisse abgeschaltet — für die gesamte Excel-Sitzung, über jedes Blatt und jede Arbeitsmappe hinweg.

Das Symptom ist verwirrend: „Meine Makros haben einfach aufgehört zu funktionieren.“ Ihr Worksheet_Change ist nicht kaputt — Ereignisse sind global unterdrückt, weil ein früherer Lauf mitten im Handler starb. Deshalb aktiviert das sichere Muster Ereignisse stets in einem Fehlerhandler wieder:

Private Sub Worksheet_Change(ByVal Target As Range)
    On Error GoTo CleanExit
    Application.EnableEvents = False
    Target.Offset(0, 1).Value = Now
    ' ... weitere Logik, die einen Fehler auslösen könnte ...
CleanExit:
    Application.EnableEvents = True     ' läuft, ob wir erfolgreich waren oder einen Fehler hatten
End Sub

Das ist genau die Disziplin „ein Ausgang, der immer aufräumt“ aus VBA On Error, und sie ist hier nicht verhandelbar. (Wenn Ereignisse bereits feststecken, führen Sie eine Zeile im Direktfenster aus — Application.EnableEvents = True — oder starten Sie Excel einfach neu.)

Die Regel, die es zielgerichtet hält: mit Intersect eingrenzen

Ein nacktes Worksheet_Change feuert für jede Zelle auf dem Blatt. Wenn Sie sich nur für Bearbeitungen in einer Spalte oder einer Tabelle interessieren, müssen Sie das sagen — sonst läuft der Handler (und schreibt vielleicht) bei jeder unbeteiligten Bearbeitung. Das Werkzeug ist Intersect: Es liefert die Überschneidung zwischen Target und dem Bereich, der Sie interessiert, oder Nothing, wenn es keine gibt:

Private Sub Worksheet_Change(ByVal Target As Range)
    ' Bearbeitungen außerhalb von B2:B1000 ignorieren
    If Intersect(Target, Range("B2:B1000")) Is Nothing Then Exit Sub
    ' ... nur auf den relevanten Teil reagieren ...
End Sub

Zwei verwandte Warnungen. Target kann viele Zellen sein — ein Einfügen oder ein Ausfüllen einer Spalte reicht Ihnen einen mehrzelligen Bereich, also wird Code, der annimmt, Target.Value sei ein einzelner Wert, einen Fehler werfen oder sich falsch verhalten; iterieren Sie entweder über Target oder grenzen Sie mit If Target.Count > 1 Then Exit Sub ein, wenn Sie wirklich nur einzelne Bearbeitungen wollen. Und reagieren Sie auf die Überschneidung, nicht auf ganz Target, wenn ein Einfügen über Ihren überwachten Bereich und Zellen außerhalb davon hinausreicht.

Die Unterscheidung, über die man stolpert: es ignoriert Formel-Neuberechnungen

Worksheet_Change feuert bei einer Änderung des Inhalts einer Zelle — ein getippter Wert, ein eingefügter Wert, eine Löschung, ein VBA-Schreibvorgang. Es feuert nicht, wenn eine Zelle lediglich eine neue Zahl anzeigt, weil eine Formel neu berechnet wurde. Ist C1 gleich =A1+B1 und A1 ändert sich, feuert das Ereignis für A1 (die bearbeitete Zelle), nicht für C1 (die neu berechnete).

Wenn Sie auf ein sich änderndes Ergebnis reagieren müssen, ist das ein anderes Ereignis — Worksheet_Calculate —, das bei einer Neuberechnung feuert, Ihnen aber kein Target gibt (Sie müssen die Zellen selbst prüfen). Das falsche zu wählen ist ein stilles Scheitern: Ihr Handler läuft schlicht nie. Die Regel: Change = jemand hat die Zelle bearbeitet; Calculate = die Ausgabe einer Formel hat sich verändert.

Worksheet_Change ist die eine Hälfte des Paars „auf den Benutzer reagieren“. Sein Geschwister, Worksheet_SelectionChange, feuert, wenn sich der Cursor bewegt, statt wenn sich ein Wert ändert — und beide gehören zur selben Ereignisfamilie wie Workbook_Open, das Ereignis, das läuft, wenn die Datei zum ersten Mal geöffnet wird.

Wie ExcelMaster hilft

Ein Makro, das auf Bearbeitungen reagiert, ist trügerisch heikel: richtiges Objekt, Intersect zum Eingrenzen, EnableEvents gegen die Schleife, ein Fehlerhandler, damit ein Absturz nicht jedes Ereignis in Excel lahmlegt. Vergessen Sie das EnableEvents-Paar, frieren Sie die Datei ein; vergessen Sie den Fehlerhandler, zerlegen Sie Ereignisse stillschweigend.

ExcelMaster lässt Sie stattdessen das Verhalten benennen. Sagen Sie „wenn jemand Spalte B bearbeitet, trage die aktuelle Uhrzeit daneben in Spalte C ein“, und es schreibt ein Worksheet_Change im richtigen Blattobjekt — eingegrenzt mit Intersect, abgesichert mit EnableEvents, so umschlossen, dass ein Fehler Ereignisse nicht abgeschaltet zurücklassen kann. Das Blatt und der Code bleiben Ihnen; Sie überspringen das einmalige Ritual, die eigene Arbeitsmappe einzufrieren, um die Regel zu lernen.

Häufig gestellte Fragen

Warum verursacht mein Worksheet_Change eine Endlosschleife oder ein Einfrieren?

Weil Ihr Handler in eine Zelle schreibt, und dieses Schreiben selbst eine Änderung ist, die Worksheet_Change erneut auslöst — endlos. Umschließen Sie jedes Schreiben mit Application.EnableEvents = False davor und Application.EnableEvents = True danach, und aktivieren Sie es stets in einem Fehlerhandler wieder, damit ein Absturz Ereignisse nicht abgeschaltet zurücklassen kann.

Wie sorge ich dafür, dass Worksheet_Change nur läuft, wenn sich eine bestimmte Spalte ändert?

Verwenden Sie Intersect am Anfang des Handlers: If Intersect(Target, Range("B:B")) Is Nothing Then Exit Sub. Das beendet die Prozedur sofort, es sei denn, die Bearbeitung hat Spalte B berührt. Intersect liefert die Überschneidung zwischen dem bearbeiteten Bereich und dem Bereich, der Sie interessiert, oder Nothing, wenn es keine Überschneidung gibt.

Feuert Worksheet_Change, wenn eine Formel neu berechnet wird?

Nein. Es feuert nur, wenn der Inhalt einer Zelle bearbeitet wird — getippt, eingefügt, gelöscht oder von VBA geschrieben. Eine Zelle, die einen neuen Wert anzeigt, weil eine Formel neu berechnet wurde, löst es nicht aus. Verwenden Sie dafür das Ereignis Worksheet_Calculate, das bei einer Neuberechnung feuert, Ihnen aber kein Target gibt.

Wohin gehört Worksheet_Change-Code?

In das Codemodul des betreffenden Arbeitsblatts — doppelklicken Sie im Projekt-Explorer auf das Blatt (z. B. Sheet1) unter „Microsoft Excel Objekte“ und legen Sie dort Private Sub Worksheet_Change(ByVal Target As Range) ab. Aus einem gewöhnlichen Module funktioniert es nicht. Für alle Blätter auf einmal verwenden Sie Workbook_SheetChange in ThisWorkbook.

Meine VBA-Ereignisse funktionieren nicht mehr — wie behebe ich das?

Ein früherer Handler hat wahrscheinlich Application.EnableEvents = False gesetzt und einen Fehler bekommen, bevor er ihn wiederherstellte, sodass Ereignisse global abgeschaltet blieben. Tippen Sie Application.EnableEvents = True im Direktfenster (Strg+G) und drücken Sie die Eingabetaste, oder starten Sie Excel neu. Verhindern Sie es, indem Sie Ereignisse stets in einem Fehlerhandler wieder aktivieren.

Getestet in

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

Verwandte Anleitungen: VBA Worksheet_SelectionChange · VBA Workbook_Open · VBA On Error · VBA Range · VBA For-Schleife