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

VBA Sleep in Excel — der Windows-API-Aufruf, die 64-Bit-PtrSafe-Falle und Wait vs. Sleep

|

VBA Sleep in Excel — der Windows-API-Aufruf, die 64-Bit-PtrSafe-Falle und Wait vs. Sleep

TL;DRSleep ist kein Teil von VBA. Es ist eine Windows-API-Funktion, die Ihr Makro eine Anzahl von Millisekunden pausiert, und Sie müssen es deklarieren, bevor Sie es aufrufen können. Auf 64-Bit-Excel muss diese Deklaration das PtrSafe-Attribut tragen, verpackt in einen #If VBA7-Schutz, damit sie überall kompiliert:

#If VBA7 Then
    Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
    Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If

Sub PauseQuarterSecond()
    Sleep 250            ' 250 Millisekunden = eine Viertelsekunde
End Sub

Man greift zu Sleep, wenn Application.Wait nicht reicht — wenn man einen Sekundenbruchteil pausieren muss, nicht eine ganze Sekunde. Und das Allererste, was passiert, ist ein Kompilierfehler, denn Sleep ist gar kein VBA-Befehl — es wohnt in Windows. Diese Anleitung ruht auf dieser einen Idee — Sleep ist eine Millisekunden-Pause, die Sie sich vom Betriebssystem leihen —, denn sie erklärt die Deklaration, die 64-Bit-Falle und warum Sleep Ihnen dennoch keine reaktionsfähige Pause geben kann.

Was Sie lernen

  • Das mentale Modell — Sleep ist eine Windows-kernel32-Funktion, die Sie sich leihen, kein VBA-Schlüsselwort
  • Die 64-Bit-PtrSafe-Falle — der genaue Kompilierfehler und der genaue #If VBA7-Fix
  • Millisekunden, keine Sekunden — die Genauigkeit unter einer Sekunde, die der ganze Grund ist, Sleep zu nutzen
  • Warum „Millisekunden“ nicht „präzise“ heißt — die Scheduler-Untergrenze des Betriebssystems von ~15 ms
  • Warum Sleep Excel dennoch einfriert und wann Sie stattdessen Wait oder eine DoEvents-Schleife nutzen

Das mentale Modell: eine Pause, die Sie sich von Windows leihen

Application.Wait ist Excels eigenes Werkzeug. Sleep ist es nicht — es gehört zu Windows, in einer Systembibliothek namens kernel32. Um es zu nutzen, greifen Sie mit einer Declare-Anweisung über VBA hinaus, die sinngemäß sagt: „In kernel32 gibt es eine Funktion namens Sleep; hier ist ihre Form; lass mich sie aufrufen.“ Erst dann können Sie Sleep 250 schreiben.

Dieses „von Windows leihen“ ist das mentale Modell, und alles Umständliche an Sleep folgt daraus. Ein natives VBA-Schlüsselwort würde einfach funktionieren. Eine geliehene API-Funktion muss deklariert werden, muss der Aufrufkonvention des Betriebssystems entsprechen und — entscheidend — muss auf 32-Bit- und 64-Bit-Windows unterschiedlich deklariert werden. An diesem letzten Punkt bleiben fast alle hängen.

Die 64-Bit-PtrSafe-Falle: der Fehler und der Fix

Das ist das Sleep-Problem Nummer eins, und es ist der Grund, warum ein Makro, das „auf dem alten Rechner lief“, plötzlich den Dienst verweigert. Die klassische Deklaration, die Sie in altem Code und alten Forenbeiträgen finden, lautet:

Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)   ' Stil vor 2010

Führen Sie das in modernem 64-Bit-Excel aus, und noch bevor eine einzige Zeile ausgeführt wird, hält VBA an mit:

Compile error: The code in this project must be updated for use on 64-bit systems. Please review and update Declare statements and then mark them with the PtrSafe attribute.

Der Fix hat zwei Teile. Erstens, ergänzen Sie das Schlüsselwort PtrSafe, das VBA mitteilt, dass die Deklaration auf 64-Bit-Zeigersicherheit geprüft wurde. Zweitens, verpacken Sie sie in einen #If VBA7-Block zur Bedingungskompilierung, damit dieselbe Datei auch auf uralten Excel-Versionen kompiliert, die es vor PtrSafe gab:

#If VBA7 Then
    ' Excel 2010 und spaeter - 64-Bit-sicher
    Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
    ' Excel 2007 und frueher - das Schluesselwort PtrSafe existiert nicht
    Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If

#If VBA7 wird zur Kompilierzeit geprüft, nicht zur Laufzeit, sodass jede Excel-Version immer nur die eine Deklaration sieht, die sie versteht. Setzen Sie diesen Block an den Anfang eines Standardmoduls, über jede Prozedur, und Sleep kompiliert und läuft auf jedem modernen Excel. Wenn Sie ausschließlich 64-Bit-Excel 365 anvisieren, genügt die PtrSafe-Zeile allein — doch die abgesicherte Variante ist das gefahrlose Kopieren-und-Einfügen.

Millisekunden, keine Sekunden — der Grund, warum es Sleep gibt

Sleep nimmt Millisekunden. Sleep 250 ist eine Viertelsekunde; Sleep 1000 ist eine Sekunde; Sleep 50 ist ein Fünfzigstel. Das ist der ganze Grund, Sleep gegenüber Application.Wait vorzuziehen, das nur in ganzen Sekunden pausieren kann. Wenn Sie eine Schleife auf ein paar Mal pro Sekunde drosseln, API-Anfragen entzerren oder kurz warten müssen, bis sich etwas gesetzt hat, ist Sleep das Werkzeug mit der richtigen Auflösung.

Do
    ' ... pruefen, ob die Exportdatei aufgetaucht ist ...
    If Dir(exportPath) <> "" Then Exit Do
    Sleep 200        ' fuenfmal pro Sekunde abfragen, statt die Platte zu haemmern
Loop

Aber „Millisekunden“ heißt nicht „präzise“

Verwechseln Sie feine Einheiten nicht mit feiner Genauigkeit. Windows plant Threads in einem Takt von etwa 15,6 Millisekunden ein, sodass Sleep 1 nicht eine Millisekunde schläft — es schläft bis zum nächsten Scheduler-Takt, typischerweise um die 15 ms. Sleep garantiert „mindestens so lange“, nie „genau so lange“, und die tatsächliche Pause wird auf die Granularität des Schedulers aufgerundet. Für Drosselung und Taktung, wo Sie nur „ungefähr so oft“ wollen, ist das in Ordnung. Es ist das falsche Werkzeug, wenn Sie präzises Timing oder eine genaue Messung brauchen — zum Messen verstrichener Zeit nutzen Sie Timer; für hochpräzises Timing würden Sie zu QueryPerformanceCounter greifen.

Sleep friert Excel dennoch ein

Hier ist die Falle, die sich Sleep mit Application.Wait teilt: Während es pausiert, ist Excel eingefroren. Sleep parkt Excels einzigen Thread für die Dauer und arbeitet die Nachrichtenwarteschlange nicht ab, sodass sich der Bildschirm nicht neu zeichnet, Klicks nicht bearbeitet werden und ein hinreichend langes Sleep — oder viele kurze in einer Schleife — das Fenster auf „Keine Rückmeldung“ springen lässt. Genauigkeit unter einer Sekunde ändert daran nichts; eine Pause ist eine Pause, und ein blockierter Thread ist ein eingefrorenes Excel.

Sleep ist also, wie Wait, das falsche Werkzeug, wenn der Sinn der Pause darin besteht, den Benutzer etwas sehen oder tun zu lassen. Eine Pause, bei der Excel am Leben bleibt, ist eine Schleife, die mit DoEvents abgibt:

' Reaktionsfaehige Taktung unter einer Sekunde - Excel bleibt zwischen den Takten am Leben
Dim nextBeat As Double
nextBeat = Timer + 0.25
Do While Timer < nextBeat
    DoEvents
Loop

Das ehrliche Urteil: Wait, Sleep oder eine DoEvents-Schleife

Stellen Sie die drei danach auf, was Sie wirklich brauchen:

  • Eine Ganzsekunden-Pause, ohne AufhebensApplication.Wait Now + TimeValue(...). Kein Declare, kein PtrSafe, nichts, was man falsch machen kann. Greifen Sie hier zuerst zu für „etwa 2 Sekunden warten“.
  • Eine Pause unter einer SekundeSleep, denn Application.Wait kommt nicht unter eine Sekunde. Nehmen Sie die Declare/PtrSafe-Zeremonie als Preis für die Millisekunden-Auflösung in Kauf.
  • Eine Pause, bei der Excel reaktionsfähig bleiben muss — eine DoEvents-Schleife, denn sowohl Wait als auch Sleep frieren das Fenster ein. Das ist die, die man am häufigsten braucht und am seltensten wählt.

Die Mutprobe: Fügen Sie kein Sleep „für alle Fälle“ hinzu, um ein Makro zu verlangsamen. Wenn sich ein Makro ohne künstliche Pause danebenbenimmt, verbirgt die Pause meist einen echten Bug — ein Wert, der gelesen wurde, bevor er bereit war, ein Ereignis, das zweimal feuerte —, und der ehrliche Fix behebt genau das, nicht ein obendrauf gestreutes Sleep 500.

Wie ExcelMaster hilft

Die Sleep-Deklaration ist genau die Art von Boilerplate, die man leicht falsch macht und mühsam richtig hinbekommt — die Lib "kernel32"-Zeichenfolge, das ByVal-Argument, das PtrSafe-Attribut, der #If VBA7-Schutz und dann die Ermessensfrage, ob Sleep überhaupt das Werkzeug war, das Sie wollten, statt Application.Wait oder einer DoEvents-Schleife.

ExcelMaster schreibt Ihnen die korrekte, 64-Bit-sichere Deklaration und wählt, noch wichtiger, die richtige Warte-Konstruktion für das, was Sie beschrieben haben. Bitten Sie um „alle 200 ms nach einer Datei abfragen“, und es gibt Ihnen eine abgesicherte Sleep-Schleife; bitten Sie um „pausieren, aber lass mich abbrechen“, und es gibt Ihnen stattdessen eine DoEvents-Schleife — so verschicken Sie nie den Declare von vor 2010, der auf 64-Bit-Excel abstürzt, und frieren Excel nie ein, wenn Sie es am Leben halten wollten.

Häufig gestellte Fragen

Wie nutze ich Sleep in Excel VBA?

Deklarieren Sie es einmal am Anfang eines Standardmoduls, dann rufen Sie es mit einem Millisekundenwert auf. Nutzen Sie die 64-Bit-sichere Form #If VBA7 Then Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) (mit einem schlichten Declare im #Else-Zweig für altes Excel). Dann pausiert Sleep 250 das Makro für 250 Millisekunden — eine Viertelsekunde.

Warum verursacht mein Sleep-Declare einen Kompilierfehler auf 64-Bit-Excel?

Weil der alte Deklarationsstil älter ist als 64-Bit-Office. Modernes 64-Bit-Excel verlangt das PtrSafe-Attribut an jeder Declare-Anweisung, und ohne es erhalten Sie „The code in this project must be updated for use on 64-bit systems… mark them with the PtrSafe attribute.“ Ergänzen Sie PtrSafe nach Declare und verpacken Sie die Zeile in einen #If VBA7-Block, damit sie auch auf älterem Excel weiterhin kompiliert.

Was ist der Unterschied zwischen Sleep und Application.Wait?

Sleep ist ein Windows-API-Aufruf, den Sie deklarieren müssen; es pausiert für eine Anzahl von Millisekunden und liefert Genauigkeit unter einer Sekunde. Application.Wait ist in Excel eingebaut, braucht keine Deklaration und pausiert bis zu einem Uhrzeit-Moment mit Ganzsekunden-Auflösung. Nutzen Sie Sleep, wenn Sie feiner als eine Sekunde brauchen, und Application.Wait für einfache Ganzsekunden-Pausen. Beide frieren Excel ein, während sie warten.

Reagiert Excel während Sleep nicht mehr?

Ja. Sleep blockiert Excels einzigen Thread für die gesamte Pause und verarbeitet keine Nachrichten, sodass sich das Fenster nicht neu zeichnen oder Klicks bearbeiten kann und „Keine Rückmeldung“ anzeigen kann. Wenn Excel während einer Pause reaktionsfähig bleiben muss — für Fortschritt oder eine Abbrechen-Schaltfläche —, nutzen Sie eine Schleife, die DoEvents aufruft, statt Sleep.

Ist Sleep auf die Millisekunde genau?

Nein. Windows plant Threads in einem Takt von etwa 15,6 ms ein, sodass Sleep 1 tatsächlich rund 15 ms pausiert, und Sleep garantiert nur „mindestens so lange“. Für Drosselung und Taktung ist das in Ordnung, aber nicht für präzises Timing. Um zu messen, wie lange Code braucht, nutzen Sie stattdessen die Timer-Funktion.

Getestet in

Getestet in: Excel 365 (Windows 11, 64-Bit), VBA 7.1 — zuletzt geprüft am 19.08.2026.

Verwandte Anleitungen: VBA Wait · VBA Timer · VBA DoEvents · VBA On Error · VBA ScreenUpdating