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

VBA DoEvents in Excel — Verhindern, dass Excel nicht mehr reagiert (und warum es Ihr Makro zweimal laufen lässt)

|

VBA DoEvents in Excel — Verhindern, dass Excel nicht mehr reagiert (und warum es Ihr Makro zweimal laufen lässt)

TL;DRDoEvents pausiert Ihr Makro für den Bruchteil einer Sekunde und lässt Excel die Klicks, Tastenanschläge und Neuzeichnungen abarbeiten, die sich anstauten, während Ihr Code beschäftigt war. Das hält das Fenster davon ab, grau zu werden und auf „Keine Rückmeldung“ zu springen, und es macht eine funktionierende Abbrechen-Schaltfläche möglich. Doch dieselbe Kontrollabgabe gibt die Steuerung mitten im Makro an den Benutzer zurück — sodass er Ihre Schaltfläche erneut anklicken und eine zweite Kopie des Makros innerhalb der ersten starten kann. Sichern Sie diese Re-Entrancy mit einem Lauf-Flag ab und rufen Sie DoEvents in einem Intervall auf, nicht bei jeder Iteration:

Private mRunning As Boolean

Sub LongJob()
    If mRunning Then Exit Sub         ' Re-Entrancy-Schutz - keine zweite Kopie starten
    mRunning = True
    On Error GoTo CleanExit
    Dim i As Long
    For i = 1 To 500000
        ' ... Arbeit an Zeile i ...
        If i Mod 1000 = 0 Then DoEvents   ' ab und zu abgeben, damit Excel am Leben bleibt
    Next i
CleanExit:
    mRunning = False                  ' das Flag immer zuruecksetzen, auch nach einem Fehler
End Sub

Eine lange VBA-Schleife läuft auf Excels einzigem Thread, und während sie läuft, kann Excel nichts anderes tun — nicht neu zeichnen, keinen Klick registrieren, die Titelleiste nicht aktualisieren. Nach ein paar Sekunden entscheidet Windows, dass die Anwendung hängt, und stempelt „Keine Rückmeldung“ darüber, obwohl Ihr Makro einwandfrei arbeitet. DoEvents ist das Überdruckventil. Diese Anleitung ruht auf einer Idee — DoEvents erkauft Reaktionsfähigkeit, indem es die Kontrolle zurückgibt, und „die Kontrolle zurückgeben“ schließt ein, dem Benutzer die Kontrolle zu geben, Dinge kaputtzumachen. Es ist keine kostenlose „mach Excel geschmeidig“-Zeile; es ist ein Tauschgeschäft, und Sie müssen die Re-Entrancy-Seite davon bezahlen.

Was Sie lernen

  • Das mentale Modell — ein Thread, eine Nachrichtenwarteschlange und warum eine Schleife das Fenster einfriert
  • Was DoEvents tatsächlich tut — die Warteschlange leeren, dann fortfahren
  • Die eigentliche Gefahr — Re-Entrancy und der Lauf-Flag-Schutz, der sie stoppt
  • Warum Sie es drosseln müssen — DoEvents bei jeder Iteration kann Ihre Laufzeit dominieren
  • Wie es eine Abbrechen-Schaltfläche ermöglicht und wie das mit einer Statusleiste zusammenhängt
  • Warum DoEvents kein Multithreading ist und wann man es einfach weglässt

Das mentale Modell: ein Thread und eine Warteschlange, die nie gelesen wird

Excel führt Ihr VBA auf demselben einzigen Thread aus, den es für alles andere nutzt — das Raster zeichnen, Ihre Maus verarbeiten, das Menüband auffrischen. Während ein Makro läuft, gehört dieser Thread zu 100 % Ihnen. Jeder Klick und Tastenanschlag des Benutzers verschwindet nicht; er landet in einer Nachrichtenwarteschlange und wartet. Aber niemand liest die Warteschlange, weil der Thread in Ihrer Schleife beschäftigt ist. Der Bildschirm veraltet, die Warteschlange staut sich, und nach ein paar Sekunden malt Windows „Keine Rückmeldung“ über das Fenster.

DoEvents liest die Warteschlange. Wenn Sie es aufrufen, pausiert VBA Ihr Makro, lässt Excel alles Wartende abarbeiten — den Bildschirm neu zeichnen, die Klicks verarbeiten, etwaige ausgelöste Ereignishandler ausführen — und gibt dann die Kontrolle an die Zeile nach DoEvents zurück, sodass Ihr Makro weiterläuft.

' ... Ihre Schleife belegt den Thread; das Fenster ist eingefroren ...
DoEvents   ' Excel leert die Warteschlange: neu zeichnen, Klicks verarbeiten, Handler ausfuehren, dann zurueck
' ... Ihr Makro laeuft hier weiter ...

Das ist wirklich nützlich: Das Fenster bleibt reaktionsfähig, die Statusleiste, die Sie gesetzt haben, zeichnet sich tatsächlich neu, und der Benutzer kann interagieren. Das Problem ist genau dieser letzte Teil.

Die eigentliche Gefahr: Re-Entrancy

Hier ist der Fehler, der DoEvents gefährlich statt bloß langsam macht. Ihr Makro wird von einer Schaltfläche gestartet. Auf halbem Weg rufen Sie DoEvents auf. Excel verarbeitet die eingereihte Eingabe — und der Benutzer hat, weil das Makro „eine Weile braucht“, dieselbe Schaltfläche erneut angeklickt. Dieser Klick wird nun während Ihres DoEvents verarbeitet, sodass Excel einen zweiten Lauf des Makros startet, während der erste noch in der Schleife pausiert. Zwei Kopien verzahnen sich jetzt auf denselben Daten.

Die Folgen reichen von falsch bis katastrophal: doppelt verarbeitete Zeilen, ein Zähler, der doppelt zählt, eine von beiden Läufen geschriebene Datei oder ein glatter Fehler, wenn der zweite Lauf einen Zustand ändert, den der erste als stabil annahm. Das ist Re-Entrancy, und es ist der DoEvents-Bug Nummer eins — dieselbe Fehlerfamilie wie ein Ereignishandler, der sich selbst auslöst.

Der Schutz ist ein Flag auf Modulebene, das einen zweiten Eintritt verweigert:

Private mRunning As Boolean

Sub LongJob()
    If mRunning Then Exit Sub    ' laeuft bereits - den zusaetzlichen Klick ignorieren
    mRunning = True
    On Error GoTo CleanExit
    ' ... Schleife mit DoEvents ...
CleanExit:
    mRunning = False             ' bei Erfolg UND bei Fehler loeschen, sonst sperren Sie sich aus
End Sub

Beachten Sie, dass die CleanExit-Wiederherstellung auch hier nicht optional ist: Überspringt ein Fehler mRunning = False, bleibt das Flag True, und das Makro weigert sich, jemals wieder zu laufen, bis Sie das Projekt zurücksetzen. Dieselbe On Error-Disziplin wie bei jedem Schalter in diesem Cluster.

Drosseln Sie es: DoEvents ist nicht kostenlos

Auch ohne Re-Entrancy hat DoEvents seinen Preis. Die Nachrichtenwarteschlange zu leeren und an das Betriebssystem abzugeben kostet echte Zeit — oft weit mehr als das winzige Stück Arbeit in einer Schleifeniteration. Rufen Sie es bei jeder Iteration einer engen Schleife auf, und Sie können aus einem 2-Sekunden-Makro ein 30-Sekunden-Makro machen, das die meiste Zeit mit Abgeben statt mit Arbeiten verbracht hat.

Rufen Sie es also in einem Intervall auf — alle 1.000 Zeilen oder jede Viertelsekunde per Timer — nicht bei jedem Durchgang:

For i = 1 To n
    ' ... Arbeit ...
    If i Mod 1000 = 0 Then DoEvents   ' reaktionsfaehig genug, ohne bei jeder Zeile zu zahlen
Next i

Das Intervall ist ein Regler: häufiger bedeutet ein flotteres Fenster und eine reaktionsfreudigere Abbrechen-Schaltfläche; seltener bedeutet höheren reinen Durchsatz. i Mod 1000 ist ein guter Ausgangspunkt für schnelle Arbeit pro Zeile; stimmen Sie es darauf ab, wie lange jede Iteration dauert.

Die Abbrechen-Schaltfläche, die es ermöglicht

Die positive Seite, die Ihnen die Re-Entrancy offenbart, ist zugleich die Funktion, die man sich am meisten wünscht: Weil DoEvents Excel mitten im Lauf Klicks verarbeiten lässt, kann ein Benutzer eine Abbrechen-Schaltfläche anklicken, und sie wird registriert, während das Makro noch in der Schleife ist. Verdrahten Sie ein öffentliches Flag mit der Schaltfläche und prüfen Sie es nach jedem DoEvents:

Public gCancel As Boolean          ' vom Klick-Handler einer Abbrechen-Schaltflaeche auf True gesetzt

Sub LongJob()
    Dim i As Long
    For i = 1 To 500000
        ' ... Arbeit ...
        If i Mod 1000 = 0 Then
            DoEvents
            If gCancel Then Exit For   ' der Klick kam durch - sauber stoppen
        End If
    Next i
End Sub

Ohne DoEvents sitzt der Abbrechen-Klick nur in der Warteschlange, bis das Makro von selbst fertig ist — nutzlos. Mit ihm funktioniert die Schaltfläche. Kombinieren Sie sie mit einer Statusleisten-Meldung, damit der Benutzer den Fortschritt sehen und ihn stoppen kann.

Warum es kein Multithreading ist — und wann man es weglässt

DoEvents führt Ihr Makro nicht im Hintergrund oder auf einem anderen Thread aus. Alles läuft weiterhin seriell auf dem einen Thread; DoEvents verzahnt lediglich Excels anstehende Arbeit zwischen Ihren Arbeitsabschnitten. Ihre Schleife wird nicht schneller — wenn überhaupt, wird sie langsamer — es hört nur auf, die UI zu blockieren. Wenn Sie wirklich brauchen, dass Arbeit parallel läuft, ist das ein ganz anderes Werkzeug (ein separater Prozess oder eine Sprache, die Threads beherrscht), nicht DoEvents.

Und die ehrliche Grundregel: Wenn ein Makro in unter ein, zwei Sekunden fertig ist, löst es nie „Keine Rückmeldung“ aus, sodass DoEvents Kosten und Re-Entrancy-Risiko ohne jeden Nutzen hinzufügt — lassen Sie es weg. Greifen Sie nur dann dazu, wenn der Lauf lang genug ist, dass ein eingefrorenes Fenster ein echtes Problem ist, und wenn Sie es tun, sichern Sie die Re-Entrancy ab und drosseln Sie die Aufrufe. Ein schnelles Makro mit über die Schleife verstreuten DoEvents ist langsamer und fragiler als dasselbe Makro ohne sie.

Wie ExcelMaster hilft

DoEvents gut einzusetzen ist ein Bündel von Ermessensentscheidungen: nur bei langen Läufen, in einem Intervall statt bei jeder Iteration, hinter einem Re-Entrancy-Schutz, mit dem in einem Fehlerhandler zurückgesetzten Flag und kombiniert mit einer Abbrechen-Prüfung und einer Fortschrittsmeldung. Machen Sie eines davon falsch, bekommen Sie ein Makro, das zweimal läuft, oder eines, das kriecht, oder eine Abbrechen-Schaltfläche, die nie auslöst.

ExcelMaster trifft diese Entscheidungen für Sie. Bitten Sie es um „einen langen Import, der reaktionsfähig bleibt und abgebrochen werden kann“, und es fügt ein Lauf-Flag hinzu, um Re-Entrancy zu blockieren, ruft DoEvents in einem sinnvollen Intervall auf, prüft direkt danach ein Abbrechen-Flag und setzt alles in einem CleanExit-Handler zurück — so bekommen Sie ein reaktionsfähiges, unterbrechbares Makro statt eines eingefrorenen Fensters oder eines Doppellaufs.

Häufig gestellte Fragen

Was macht DoEvents in Excel VBA?

DoEvents pausiert Ihr Makro kurz und lässt Excel die Eingabe- und Neuzeichenarbeit abarbeiten, die sich anstaute, während Ihr Code lief — Klicks, Tastenanschläge, Bildschirm-Neuzeichnungen und etwaige ausgelöste Ereignishandler. Dann gibt es die Kontrolle an die nächste Zeile zurück, und Ihr Makro läuft weiter. Es ist das, was ein langes Makro davon abhält, das Excel-Fenster in „Keine Rückmeldung“ einzufrieren.

Warum zeigt Excel „Keine Rückmeldung“ an, während mein Makro läuft?

Weil Ihr Makro Excels einzigen Thread nutzt, sodass Excel nicht neu zeichnen oder Eingaben verarbeiten kann, bis das Makro abgibt. Nach ein paar Sekunden markiert Windows die Anwendung als hängend — obwohl das Makro einwandfrei arbeitet. DoEvents in einem Intervall in Ihrer Schleife lässt Excel durchatmen, und die Bezeichnung „Keine Rückmeldung“ verschwindet.

Ist DoEvents gefährlich?

Das kann es sein, durch Re-Entrancy. Weil DoEvents Excel mitten im Lauf Klicks verarbeiten lässt, kann ein Benutzer dasselbe Makro erneut starten (indem er seine Schaltfläche noch einmal anklickt), während der erste Lauf pausiert, sodass zwei Kopien gleichzeitig laufen und sich gegenseitig die Arbeit beschädigen. Sichern Sie sich dagegen mit einem „Lauf“-Flag auf Modulebene ab, das das Makro beenden lässt, wenn es bereits läuft, und setzen Sie das Flag in einem Fehlerhandler zurück.

Soll ich DoEvents in jeder Schleifeniteration aufrufen?

Nein — drosseln Sie es. DoEvents hat echten Overhead, und es bei jeder Iteration einer engen Schleife aufzurufen kann Ihre Laufzeit dominieren und das Makro weit langsamer machen. Rufen Sie es stattdessen in einem Intervall auf, etwa If i Mod 1000 = 0 Then DoEvents, und stimmen Sie das Intervall darauf ab, wie lange jede Iteration dauert.

Macht DoEvents mein Makro multithreaded oder schneller?

Nein. Alles läuft weiterhin seriell auf einem Thread; DoEvents verzahnt lediglich Excels anstehende UI-Arbeit zwischen Abschnitten Ihres Codes. Ihre Schleife wird nicht schneller — meist wird sie leicht langsamer — sie hört nur auf, die Oberfläche zu blockieren. Für echte parallele Arbeit brauchen Sie einen separaten Prozess, nicht DoEvents.

Getestet in

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

Verwandte Anleitungen: VBA StatusBar · VBA DisplayAlerts · VBA ScreenUpdating · VBA EnableEvents · VBA On Error