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

VBA Workbook_BeforeClose in Excel — das Schließen abbrechen, zum Speichern auffordern und wo der Code liegen muss

|

VBA Workbook_BeforeClose in Excel — das Schließen abbrechen, zum Speichern auffordern und wo der Code liegen muss

TL;DRWorkbook_BeforeClose ist 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 Sie Cancel = 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 im ThisWorkbook-Objekt liegen, und wenn Sie Ihre eigene Speicheraufforderung zeigen wollen, ohne dass Excel zusätzlich fragt, setzen Sie ThisWorkbook.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 BeforeClose niemals 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