TL;DR —
Application.OnTimestartet keinen Timer. Es trägt eine Reservierung in Excels Warteschlange ein: zu dieser Uhrzeit dieses Makro ausführen. Ihr Code endet sofort, und Excel bleibt bedienbar; ist die Zeit gekommen und Excel bereit, läuft das Makro. Die Reservierung wird an der exakten Uhrzeit und dem Makronamen erkannt. Um sie abzubrechen, müssen Sie also beides noch einmal übergeben — und dafür die Zeit in einer Variablen auf Modulebene aufbewahren. Bei einer wiederkehrenden Aufgabe bucht das Makro seinen nächsten Lauf selbst. Brechen Sie inWorkbook_BeforeCloseab, denn das Schließen der Arbeitsmappe bricht gar nichts ab: Excel öffnet die Datei wieder, um den Termin einzuhalten.
Private mNextRun As Date ' die Reservierung, die Sie evtl. abbrechen muessen
Sub StartRefresh()
mNextRun = Now + TimeSerial(0, 5, 0) ' fuenf Minuten ab jetzt
Application.OnTime mNextRun, "RefreshPrices"
End Sub
Sub StopRefresh()
On Error Resume Next ' Fehler 1004, wenn nichts gebucht ist
Application.OnTime mNextRun, "RefreshPrices", Schedule:=False
On Error GoTo 0
End Sub
Dies ist der zweite Artikel einer Reihe über Makros, die Excel für Sie startet. Die
Anleitung zu Tastenkombinationen behandelt Makros, die über die Tastatur starten,
die SendKeys-Anleitung vorgetäuschte Tastenanschläge. Die verbindende Idee: Keiner
dieser Wege ruft Ihr Makro direkt auf. Jeder legt eine Anforderung in Excels Warteschlange, und Excel führt sie
aus, wenn es untätig und bereit ist. Bei OnTime hängt an der Anforderung eine Uhrzeit, und sie bleibt in
der Warteschlange, bis sie läuft oder bis Sie sie mit exakt denselben Angaben wieder entfernen.
Was Sie lernen
- Das mentale Modell: eine Reservierung, kein laufender Timer
- Ein Makro zu einer Uhrzeit ausführen, und alle N Minuten
- Warum das Abbrechen scheitert, und welche Variable das behebt
- Der Timer, den Sie nach einem Zurücksetzen des Codes nicht mehr stoppen können
- Warum Excel eine geschlossene Arbeitsmappe wieder öffnet
- Beschäftigtes Excel,
LatestTimeund ein Zeitplan, der wegdriftet - Wann
OnTimedas falsche Werkzeug ist
Das mentale Modell: eine Reservierung, kein Timer
Vergleichen Sie OnTime mit einer Schleife, die wartet:
' Blockiert Excel: fuenf Minuten lang passiert nichts anderes
Application.Wait Now + TimeSerial(0, 5, 0)
RefreshPrices
' Bucht eine Reservierung und kehrt sofort zurueck: Excel bleibt bedienbar
Application.OnTime Now + TimeSerial(0, 5, 0), "RefreshPrices"
Application.Wait und Sleep halten Ihr Makro am Laufen und Excel
eingefroren. OnTime reicht Excel einen Zettel und ist fertig. Zwischen jetzt und dem reservierten Zeitpunkt
läuft überhaupt kein VBA-Code; der Benutzer arbeitet ganz normal weiter.
Excel führt eine Liste dieser Reservierungen. Jeder Eintrag hat zwei Schlüssel, ein Datum mit Uhrzeit und einen Prozedurnamen, und Excel findet einen Eintrag nur, wenn beide passen. Alles Weitere in diesem Artikel folgt daraus: Sie können mehrere buchen, Sie brechen einen ab, indem Sie ihn exakt benennen, und die Liste gehört Excel, nicht Ihrer Arbeitsmappe.
Ein Makro zu einer bestimmten Uhrzeit ausführen
Übergeben Sie OnTime ein vollständiges Datum mit Uhrzeit, damit keine Frage offen bleibt, welcher Tag gemeint
ist:
Sub BookDailyExport()
Dim runAt As Date
runAt = Date + TimeSerial(17, 0, 0) ' heute um 17:00
If runAt <= Now Then runAt = runAt + 1 ' schon vorbei: morgen um 17:00
Application.OnTime runAt, "DailyExport"
End Sub
Viele Beispiele übergeben nur TimeValue("17:00:00"). Wenn Sie das Datum selbst zusammensetzen, steht die Regel
sichtbar im Code: Ist die Uhrzeit schon vorbei, kommt der nächste Lauf morgen, nicht sofort. Die
Now-Anleitung erklärt, warum Date plus eine Uhrzeit einen echten Datums-Zeit-Wert ergibt,
und TimeSerial hält die Rechnung frei von Problemen mit Ländereinstellungen — gerade auf deutschen Systemen,
wo Datumsangaben als Text gern anders gelesen werden als gedacht.
Ein Makro alle N Minuten ausführen
Eine Wiederholungsoption gibt es nicht. Eine wiederkehrende Aufgabe ist ein Makro, das am Ende seinen nächsten Lauf selbst bucht:
Private mNextRun As Date
Private Const INTERVAL_MIN As Long = 5
Sub StartRefresh()
mNextRun = Now + TimeSerial(0, INTERVAL_MIN, 0)
Application.OnTime mNextRun, "RefreshPrices"
End Sub
Sub RefreshPrices()
ThisWorkbook.Worksheets("Prices").Range("A1").CurrentRegion.Calculate
' ... die eigentliche Arbeit ...
StartRefresh ' den naechsten Lauf buchen
End Sub
StartRefresh startet die Kette, und RefreshPrices hält sie in Gang. Um die Kette zu stoppen, müssen Sie die
eine Reservierung entfernen, die gerade gebucht ist — und genau dort scheitert der meiste OnTime-Code.
Abbrechen: die exakte Uhrzeit, sonst Fehler 1004
Zum Abbrechen rufen Sie OnTime erneut mit Schedule:=False auf. Excel sucht dann einen Eintrag mit derselben
Uhrzeit und demselben Prozedurnamen. Folgendes sieht richtig aus und funktioniert nicht:
' Falsch: Now ist weitergelaufen, diese Zeit passt zu keiner Reservierung
Application.OnTime Now + TimeSerial(0, 5, 0), "RefreshPrices", Schedule:=False
Zu dieser neuen Uhrzeit gibt es keine Reservierung, also meldet Excel Run-time error 1004: Method 'OnTime' of
object '_Application' failed (deutsch: Laufzeitfehler '1004': Die Methode 'OnTime' für das Objekt
'_Application' ist fehlgeschlagen.), und die echte Reservierung bleibt gebucht. Deshalb lebt die Uhrzeit in
einer Variablen auf Modulebene (oben mNextRun). Damit buchen, damit abbrechen — und die Angaben stimmen immer
überein.
Das On Error Resume Next in StopRefresh ist Absicht und deckt genau eine Zeile ab: Ist nichts gebucht, etwa
weil das Makro schon gelaufen ist, löst das Abbrechen 1004 aus, und daran ist nichts zu ändern. Die
On-Error-Anleitung erklärt, warum ein solcher Handler so eng wie möglich bleiben
sollte.
Der Timer, den Sie nicht mehr stoppen können
Die Variable hat eine Schwachstelle. Variablen auf Modulebene werden geleert, sobald das VBA-Projekt
zurückgesetzt wird: wenn Sie auf die Schaltfläche Zurücksetzen klicken, wenn ein unbehandelter Fehler den Code
beendet, wenn Code End ausführt oder wenn Sie Code bearbeiten, während er angehalten ist. Die
Anleitung zu globalen Variablen listet alle Fälle auf.
Nach einem Zurücksetzen ist mNextRun gleich 0. Die Reservierung steht weiterhin in Excels Liste, aber Ihr Code
kennt ihre Uhrzeit nicht mehr, und StopRefresh bricht nichts ab. Das Makro läuft weiter alle fünf Minuten und
bucht sich jedes Mal neu.
Bewahren Sie eine Kopie der Uhrzeit an einem Ort auf, der ein Zurücksetzen übersteht, etwa in einer Zelle auf einem ausgeblendeten Einstellungsblatt:
Sub StartRefresh()
mNextRun = Now + TimeSerial(0, INTERVAL_MIN, 0)
ThisWorkbook.Worksheets("Settings").Range("B2").Value = mNextRun
Application.OnTime mNextRun, "RefreshPrices"
End Sub
Sub StopRefresh()
If mNextRun = 0 Then mNextRun = ThisWorkbook.Worksheets("Settings").Range("B2").Value
On Error Resume Next
Application.OnTime mNextRun, "RefreshPrices", Schedule:=False
On Error GoTo 0
mNextRun = 0
End Sub
Läuft Ihnen beim Entwickeln trotzdem ein Timer davon: Wenn Sie Excel vollständig beenden, ist die Liste leer.
Das Schließen der Arbeitsmappe bricht nichts ab
Die Reservierung gehört Excel, nicht der Arbeitsmappe. Schließt der Benutzer Ihre Arbeitsmappe und bleibt Excel offen, dann öffnet Excel die Arbeitsmappe zur gebuchten Zeit wieder, um das Makro auszuführen. Für den Benutzer taucht eine Datei, die er geschlossen hat, wie von Geisterhand wieder auf — und wenn das Makro den nächsten Lauf bucht, passiert das immer wieder.
Jede Arbeitsmappe, die einen Lauf bucht, muss ihn deshalb beim Schließen abbrechen:
' Im Modul ThisWorkbook
Private Sub Workbook_BeforeClose(Cancel As Boolean)
StopRefresh
End Sub
Bricht der Benutzer das Schließen anschließend bei der Speichern-Abfrage ab, bleibt die Arbeitsmappe offen,
aber der Timer ist gestoppt. Wenn das eine Rolle spielt, starten Sie ihn in Workbook_Activate neu. Die
BeforeClose-Anleitung behandelt diesen Fall.
Beschäftigtes Excel, LatestTime und ein Zeitplan, der wegdriftet
Hier gilt die Regel der Reihe: Excel führt die Reservierung nur aus, wenn es bereit ist. Tippt der Benutzer um 17:00 gerade in einer Zelle, hat er einen Dialog offen oder läuft ein anderes Makro, wartet Ihr Makro, bis das vorbei ist.
Das dritte Argument, LatestTime, begrenzt diese Wartezeit. Kann Excel das Makro bis dahin nicht ausführen,
verfällt die Reservierung:
' Um 17:00 ausfuehren, oder gar nicht, wenn Excel um 17:05 noch beschaeftigt ist
Application.OnTime runAt, "DailyExport", runAt + TimeSerial(0, 5, 0)
Das Warten erklärt auch, warum eine wiederkehrende Aufgabe wegdriftet. Now + 5 Minuten, gemessen am Ende jedes
Laufs, schlägt die Laufzeit und jede Verzögerung auf jedes Intervall drauf. Wollen Sie Läufe um :00, :05, :10,
buchen Sie den nächsten Lauf stattdessen ausgehend von der vorherigen Reservierung und überspringen Zeiten, die
schon vorbei sind:
Sub BookNext()
mNextRun = mNextRun + TimeSerial(0, INTERVAL_MIN, 0)
Do While mNextRun <= Now ' Excel war beschaeftigt: verpasste Termine ueberspringen
mNextRun = mNextRun + TimeSerial(0, INTERVAL_MIN, 0)
Loop
Application.OnTime mNextRun, "RefreshPrices"
End Sub
OnTime arbeitet sekundengenau, nicht feiner. Für alles Schnellere ist es das falsche Werkzeug; die
Timer-Anleitung behandelt das Messen kurzer Intervalle.
Die Abwägung: OnTime ist kein Zeitplaner
OnTime führt ein Makro aus, solange diese Arbeitsmappe in irgendjemandes Excel geöffnet ist. Es ist das
richtige Werkzeug für ein Dashboard, das sich alle paar Minuten aktualisiert, eine Erinnerung ans Speichern
oder eine Statusmeldung, die sich selbst wieder ausblendet. Es ist das falsche Werkzeug für jede Nacht um
2 Uhr den Export laufen lassen: Um diese Zeit ist niemandes Excel offen, ein Laptop im Energiesparmodus
verpasst den Termin, und ein einziges Zurücksetzen oder ein Absturz beendet die Kette spurlos.
Für Aufgaben, die laufen müssen, ob jemand am Schreibtisch sitzt oder nicht, öffnen Sie die Arbeitsmappe über
die Windows-Aufgabenplanung und lassen Workbook_Open die Arbeit erledigen, wie in der
Workbook_Open-Anleitung beschrieben. Behalten Sie OnTime für Zeitsteuerung
innerhalb einer Sitzung — und geben Sie jeder Reservierung einen Weg, wieder abgebrochen zu werden.
Wie ExcelMaster hilft
OnTime-Fehler zeigen sich später und an anderer Stelle: eine geschlossene Datei, die mittags wieder aufgeht,
eine Aktualisierung, die nicht mehr aufhört, ein Timer, der nur verrücktspielt, nachdem jemand auf
Zurücksetzen geklickt hat.
ExcelMaster liest den Code der Arbeitsmappe,
findet jede OnTime-Reservierung, prüft, ob es zu jeder ein passendes Abbrechen mit derselben gespeicherten
Uhrzeit gibt, und kann den Aufräumcode in Workbook_BeforeClose ergänzen, der verhindert, dass sich die Datei
von selbst wieder öffnet.
Häufig gestellte Fragen
Wie führe ich in Excel-VBA ein Makro alle 5 Minuten aus?
Buchen Sie den ersten Lauf mit Application.OnTime Now + TimeSerial(0, 5, 0), "MyMacro", und buchen Sie am
Ende von MyMacro den nächsten Lauf auf dieselbe Weise. Speichern Sie jede gebuchte Uhrzeit in einer Variablen
auf Modulebene, damit Sie sie abbrechen können.
Wie stoppe ich Application.OnTime?
Rufen Sie Application.OnTime mit derselben Uhrzeit und demselben Prozedurnamen auf, die Sie gebucht haben,
plus Schedule:=False. Die Uhrzeit muss exakt übereinstimmen — nehmen Sie also die gespeicherte Variable,
keine neue Berechnung mit Now.
Warum meldet OnTime beim Abbrechen Fehler 1004?
Keine Reservierung passt zu der Uhrzeit und dem Prozedurnamen, die Sie übergeben haben — meist, weil die
Uhrzeit neu berechnet wurde oder die Reservierung schon gelaufen ist. Brechen Sie mit der gespeicherten Uhrzeit
ab und umschließen Sie das Abbrechen mit einem einzeiligen On Error Resume Next.
Warum öffnet sich meine Arbeitsmappe von selbst wieder?
Eine mit OnTime gebuchte Reservierung stand noch in Excels Liste, als die Arbeitsmappe geschlossen wurde, also
hat Excel die Datei wieder geöffnet, um das Makro auszuführen. Brechen Sie die Reservierung in
Workbook_BeforeClose ab.
Läuft OnTime auch, wenn Excel geschlossen ist?
Nein. Die Reservierung existiert nur im laufenden Excel. Um ein Makro bei geschlossenem Excel auszuführen,
planen Sie die Arbeitsmappe über die Windows-Aufgabenplanung ein und legen die Arbeit in Workbook_Open.
Getestet in
Getestet in: Excel 365 (Windows 11), VBA 7.1 — zuletzt geprüft am 03.10.2026.
Verwandte Anleitungen: VBA Shortcut Key · VBA SendKeys · VBA Wait · VBA Sleep · VBA Timer · VBA Now · VBA Global Variable · VBA Workbook_BeforeClose
