TL;DR —
Worksheet_Changeist 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 alsTarget, 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 SchreibenWorksheet_Changeerneut 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
Targetreicht - 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
Intersecteingrenzen, damit er nicht bei jeder Bearbeitung läuft - Warum es Formel-Neuberechnungen ignoriert — und wann Sie stattdessen
Worksheet_Calculatebrauchen
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
Blatts — Sheet1 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
