TL;DR —
Workbook_BeforeCloseist ein Ereignis, das Excel in dem Augenblick auslöst, in dem jemand die Arbeitsmappe zu schließen versucht — bevor irgendein Fenster abgebaut wird. Es reicht Ihnen ein einziges Argument,Cancel, und genau darin liegt der ganze Sinn: Setzen SieCancel = True, und das Schließen wird abgeblasen, die Datei bleibt offen. Das ist also kein Abschiedsgruß, den Sie im Hinausgehen ausführen — es ist ein Kontrollpunkt, der den Benutzer an der Tür umkehren lassen kann. Der Code muss imThisWorkbook-Objekt liegen, und wenn Sie Ihre eigene Speicheraufforderung zeigen wollen, ohne dass Excel zusätzlich fragt, setzen SieThisWorkbook.Saved = True, um sein eingebautes Dialogfeld verstummen zu lassen.
' Liegt in ThisWorkbook — NICHT in einem Module.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If ThisWorkbook.Sheets("Form").Range("Approved").Value <> "Yes" Then
MsgBox "Set Approved = Yes before closing this file.", vbExclamation
Cancel = True ' <-- das Schließen abblasen; die Arbeitsmappe bleibt offen
End If
End Sub
Die meisten Makros laufen, wenn ein Benutzer danach verlangt — eine Schaltfläche, ein
Tastenkürzel. Workbook_BeforeClose läuft, wenn ein Benutzer zu gehen versucht, und
dieser Zeitpunkt ist es, der es zu gleichen Teilen nützlich und gefährlich macht. Es ist
das Ereignis hinter „Sie haben ungespeicherte Änderungen“, erzwungenen Freigaben,
Aufräumen-beim-Beenden und „protokollieren, wer die Datei geschlossen hat“. Es ist
zugleich das Ereignis, das die Leute am häufigsten falsch verdrahten — weil sie es als
Benachrichtigung behandeln, wo Excel ihnen in Wahrheit ein Veto anbietet.
Was Sie lernen
- Das mentale Modell — ein Türsteher-Ereignis, das Ihnen ein
Cancel-Veto reicht, nicht nur einen Hinweis - Wie Sie ein Schließen tatsächlich stoppen (und warum eine
vbYesNo-Abfrage allein das nicht tut) - Die Doppel-Dialog-Falle — und der Hebel
ThisWorkbook.Saved = True, der sie behebt - Warum
BeforeCloseniemals Ihr Sicherheitsnetz für die Datenintegrität sein darf (Abstürze überspringen es) - Eine Datei schließen gegenüber Excel beenden — und wo der Code liegen muss
Das mentale Modell: ein Türsteher, kein Abschiedsgruß
Workbook_BeforeClose feuert in dem Moment, in dem ein Schließen angefordert wird — das
X des Fensters, Datei ▸ Schließen, Application.Quit oder ein anderes Makro, das
.Close aufruft — und es feuert bevor Excel irgendetwas Unwiderrufliches tut.
Entscheidend ist: Es übergibt einen einzelnen Boolean per Referenz namens Cancel.
Sie rufen dieses Sub nie auf; Excel ruft Sie auf, wartet, bis Sie fertig sind, und sieht
dann nach, worauf Cancel gesetzt ist.
Dieses eine Argument stellt alles auf den Kopf. Lassen Sie Cancel unangetastet, läuft
das Schließen ganz normal weiter. Setzen Sie Cancel = True, bricht Excel das
Schließen ab, und die Arbeitsmappe bleibt genau so offen, wie sie war. Der Handler ist
also ein Türsteher: Er kann den Benutzer durchwinken, oder er kann ihn aufhalten und
zurückschicken, um etwas in Ordnung zu bringen. Lesen Sie es als „benachrichtige mich
vor dem Schließen“, und Ihnen entgeht die ganze Kraft des Ereignisses.
Die Signatur ist fest und der Ort nicht verhandelbar:
Private Sub Workbook_BeforeClose(Cancel As Boolean), im Codemodul von
ThisWorkbook — doppelklicken Sie im Projekt-Explorer unter „Microsoft Excel
Objekte“ auf ThisWorkbook. Legen Sie es in ein gewöhnliches Module, feuert es nie —
dieselbe Regel „wo der Code liegt“ wie bei Workbook_Open.
Die wichtigste Regel: eine Abfrage ohne Cancel ist reine Show
Hier ist der Fehler, den fast jeder zuerst macht. Sie wollen vor dem Schließen eine Bestätigung, also schreiben Sie:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
MsgBox "Are you sure you want to close?", vbYesNo ' fragt ... und ignoriert die Antwort
End Sub
Das Dialogfeld erscheint, der Benutzer klickt Nein — und die Arbeitsmappe schließt
trotzdem. Nichts in diesem Code berührt Cancel, also macht Excel weiter. Die Abfrage
war reine Show. Die Regel: Eine Entscheidung, die Sie durchsetzen wollen, muss zurück
in Cancel geschrieben werden. Fangen Sie die Antwort ab und handeln Sie danach:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If MsgBox("Close without exporting the report?", vbYesNo + vbQuestion) = vbNo Then
Cancel = True ' Benutzer hat Nein gesagt -> das Schließen abbrechen
End If
End Sub
Jetzt hält „Nein“ die Datei tatsächlich offen. Das ist der Unterschied zwischen einem
Ereignis, das informiert, und einem, das bewacht: Die Wache ist nur echt, wenn
Cancel = True erreichbar ist.
Die Falle, die Benutzer nervt: Excel fragt zweimal nach dem Speichern
Der zweite klassische Bug taucht in dem Moment auf, in dem Ihr Handler speichert. Sie fügen einen Schritt „vor dem Gehen speichern“ hinzu, und nun erzeugt das Schließen einer geänderten Arbeitsmappe zwei Dialoge: Ihre Abfrage und danach Excels eigene „Möchten Sie Ihre Änderungen speichern?“ Der Grund ist, dass Sie und Excel beide denselben ungespeicherten Zustand behandeln wollen.
Der Hebel ist die Saved-Eigenschaft der Arbeitsmappe. Saved ist Excels Flag für „es
gibt keine ungespeicherten Änderungen“. Setzen Sie es auf True, teilen Sie Excel mit,
die Datei sei sauber — also schließt sie ohne die eigene Speicheraufforderung,
selbst wenn es tatsächlich Änderungen gibt. Erledigen Sie das Speichern selbst und legen
Sie dann Saved um:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim answer As VbMsgBoxResult
answer = MsgBox("Save changes before closing?", vbYesNoCancel + vbQuestion)
If answer = vbCancel Then
Cancel = True ' gar nicht schließen
ElseIf answer = vbYes Then
ThisWorkbook.Save ' speichern, dann das Schließen fortsetzen lassen
Else ' vbNo
ThisWorkbook.Saved = True ' verwerfen: Excel sagen, es sei sauber, damit es nicht erneut fragt
End If
End Sub
Saved = True zu setzen speichert nichts — es unterdrückt die Abfrage, indem es
behauptet, die Arbeitsmappe sei bereits gespeichert. Setzen Sie es bewusst ein: Es ist
der Schalter, der Ihre eigene Speicherlogik zur einzigen macht, die der Benutzer zu
sehen bekommt.
Die Regel, die Ihre Daten schützt: BeforeClose ist kein Sicherheitsnetz
Workbook_BeforeClose feuert bei jedem geordneten Schließen — dem X, Datei ▸
Schließen, .Close, Application.Quit. Es feuert nicht, wenn Excel abstürzt, wenn
der Prozess abgeschossen wird oder bei einem Stromausfall. Das macht eine Versuchung
gefährlich: Machen Sie BeforeClose niemals zur einzigen Instanz, die Ihre Daten
speichert. Liegt die Logik „speichere die einzige Kopie“ hier und Excel stirbt, ist die
Kopie weg. Behandeln Sie BeforeClose als Höflichkeit (auffordern, aufräumen,
protokollieren), und halten Sie die echte Persistenz an einem ausdrücklichen Speichern
oder einem zeitgesteuerten AutoSave fest, nicht am Ausgangspfad.
Ein weiterer Grenzfall, den Sie kennen sollten: Beendet der Benutzer Excel selbst mit
mehreren geöffneten Arbeitsmappen, bekommt jede Arbeitsmappe ihr eigenes BeforeClose.
Cancel = True in einer von ihnen zu setzen hält diese Arbeitsmappe vom Schließen ab,
doch Geschwister, deren Handler bereits gelaufen ist, können sich in einem halb
geschlossenen Zustand befinden. Brauchen Sie „alles oder nichts“ beim Beenden,
koordinieren Sie sparsam aus Workbook_BeforeClose heraus und testen Sie den Fall mit
mehreren Dateien.
Die Unterscheidung, über die man stolpert: BeforeClose gegenüber BeforeSave
BeforeClose bewacht den Ausgang; sein Geschwister
Workbook_BeforeSave bewacht das Speichern und
reicht Ihnen dieselbe Art Cancel-Veto (plus ein SaveAsUI-Flag). Sie passen von Natur
aus zusammen — beim Speichern prüfen, beim Schließen bestätigen — und beide teilen die
goldene Regel der Ereignisfamilie: Schreibt ein Handler in Zellen oder speichert er,
umschließen Sie diese Aktion mit Application.EnableEvents = False … = True und stellen
Sie ihn in einem Fehlerhandler wieder her, genau wie es
Worksheet_Change tut, damit Ihr eigenes Schreiben die
Maschinerie nicht erneut auslöst.
Wie ExcelMaster hilft
Eine Schließen-Wache besteht aus vier kleinen Entscheidungen, die man leicht auf subtile
Weise falsch trifft: der Code in ThisWorkbook (nicht in einem Module), das Schreiben in
Cancel, das das Schließen wirklich stoppt, das Umlegen von Saved = True, das den
Doppel-Dialog vermeidet, und die Ermessensfrage, was man dem Ausgangspfad nicht
anvertrauen sollte.
ExcelMaster
lässt Sie stattdessen das Verhalten beschreiben. Sagen Sie „bevor diese Datei schließt,
halte das Schließen an und weise den Benutzer darauf hin, falls die Zelle Approved nicht
auf Yes steht“, und es schreibt ein Workbook_BeforeClose in ThisWorkbook, das
Cancel korrekt setzt, die Speicheraufforderung ohne Verdopplung behandelt und jedes
Schreiben absichert. Die Arbeitsmappe und der Code bleiben Ihnen; Sie überspringen das
Ausprobieren, welcher Hebel was bewirkt.
Häufig gestellte Fragen
Wie verhindere ich in VBA, dass eine Arbeitsmappe geschlossen wird?
Setzen Sie das Argument Cancel innerhalb von Workbook_BeforeClose auf True:
Private Sub Workbook_BeforeClose(Cancel As Boolean) … Cancel = True. Excel übergibt
Cancel per Referenz und prüft es, nachdem Ihr Handler gelaufen ist; True bricht das
Schließen ab, und die Datei bleibt offen. Ein MsgBox allein bewirkt nichts — Sie
müssen die Entscheidung zurück in Cancel schreiben.
Warum fragt Excel mich beim Schließen zweimal nach dem Speichern?
Weil Ihr BeforeClose-Handler zum Speichern auffordert und Excel weiterhin annimmt,
es gebe ungespeicherte Änderungen, also zeigt es zusätzlich sein eigenes Dialogfeld.
Erledigen Sie das Speichern selbst und setzen Sie dann ThisWorkbook.Saved = True, um
Excel mitzuteilen, die Arbeitsmappe sei sauber — das unterdrückt seine eingebaute
Abfrage „Möchten Sie speichern?“.
Wohin gehört Workbook_BeforeClose-Code?
In das Codemodul von ThisWorkbook — doppelklicken Sie im Projekt-Explorer unter
„Microsoft Excel Objekte“ auf ThisWorkbook und fügen Sie dort
Private Sub Workbook_BeforeClose(Cancel As Boolean) ein. Aus einem gewöhnlichen
Module feuert es nicht, und Makros müssen aktiviert sein.
Läuft Workbook_BeforeClose, wenn Excel abstürzt?
Nein. Es feuert nur bei einem geordneten Schließen — dem Fenster-X, Datei ▸ Schließen,
.Close oder Application.Quit. Ein Absturz, ein abgeschossener Prozess oder ein
Stromausfall überspringt es vollständig. Verlassen Sie sich niemals auf BeforeClose
als die einzige Instanz, die Ihre Daten speichert.
Wie unterscheidet sich BeforeClose von Workbook_BeforeSave?
BeforeClose feuert, wenn die Datei geschlossen wird, und lässt Sie das Schließen
abbrechen; Workbook_BeforeSave feuert, wenn die Datei gespeichert wird, und lässt Sie
das Speichern abbrechen. Das Schließen einer geänderten Datei löst meist eine
Speicheraufforderung aus, daher treten die beiden oft zusammen auf, doch es sind
getrennte Ereignisse mit getrennten Cancel-Flags.
Getestet in
Getestet in: Excel 365 (Windows 11), VBA 7.1 — zuletzt geprüft am 05.08.2026.
Verwandte Anleitungen: VBA Workbook_BeforeSave · VBA Worksheet_Activate & Deactivate · VBA Workbook_Open · VBA Worksheet_Change · VBA On Error
