Contents
この記事でできること
- VBAの
Application.OnTimeを使って、指定した時刻にマクロを自動実行できる - 毎時・毎日の繰り返し実行も設定できる
- 停止ボタン付きで、不要になったらワンクリックで予約をキャンセルできる
対象: Excel 2016以降 / Microsoft 365、Windows 10/11
完成イメージ(Before / After)
Before(手動実行):
- 毎朝9時に自分で集計マクロを実行する
- 忘れると午後の会議でデータが古いまま
- 出張中は誰も実行してくれない
After(自動実行):
- 朝イチでExcelを開いてマクロを1回実行するだけ
- 9:00になると集計マクロが自動で走る
- 繰り返し設定すれば毎時・毎日の定期実行も可能
- 停止ボタンでいつでも予約をキャンセルできる
毎朝9時に集計マクロを実行する。たったそれだけのことなのに、つい忘れる。自分も出張中に集計マクロの実行を忘れて、午後の会議でデータが古いまま報告してしまったことがある。上司に「この数字、今朝の分じゃないよね?」と指摘されて冷や汗をかいた。
「毎朝の定型作業を忘れずに実行する」。人間がやると忘れるが、Excelに任せれば確実に動く。Application.OnTime を使えば、「9時になったらこのマクロを実行して」とExcelに予約できる。コードは3行。設定後はExcelを開いておくだけでいい。
この記事では、指定時刻にマクロを1回だけ自動実行する最小版と、毎時・毎日の繰り返し実行+停止ボタン付きの実務版を紹介する。出張中でも安心できる仕組みを作ろう。
セルの値が変わったときに自動実行する方法は セルの値が変わったら自動実行(Worksheet_Change) で解説している。今回は「時刻」をトリガーにする方法。
実行前の準備
バックアップを取る
既存のデータが入っているExcelファイルで試す場合は、先にファイルをコピーしてバックアップを取る。OnTime自体がデータを壊す操作ではないが、呼び出すマクロの内容次第ではデータが変わるため、習慣として推奨する。
バックアップの自動化については ファイルをバックアップする方法 も参考にしてほしい。
Excelをマクロ有効ブック(.xlsm)で保存する
拡張子が .xlsx のままだとマクロが保存されない。
- 「ファイル」→「名前を付けて保存」
- ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
- 保存
手順(コピペ → 実行まで約5分)
VBE(コードを書く画面)を開く
- Excelで
Alt + F11を押す - VBE(Visual Basic Editor)が開く
標準モジュールを挿入する
- VBEのメニュー →「挿入」→「標準モジュール」
- 白い画面(コードウィンドウ)が表示される
コードを貼り付けて実行する
- コードウィンドウに、下のコードをそのままコピペする
Alt + F8→ScheduleOnce(最小版)またはStartSchedule(実務版)を選んで「実行」
コード(最小版)– 指定時刻に1回だけ自動実行
'============================================================
' ■ 指定時刻にマクロを1回だけ自動実行(最小版)
' → Application.OnTime で予約し、指定時刻に処理を実行
'============================================================
Sub ScheduleOnce()
'--- ★書き換えポイント ---
Dim runTime As String
runTime = "09:00:00" '← 実行したい時刻(24時間表記)
Dim macroName As String
macroName = "MyTask" '← 実行したいマクロ名
'--- ★ここまで ---
'--- 指定時刻にマクロを予約
Application.OnTime TimeValue(runTime), macroName
MsgBox runTime & " に " & macroName & " を実行予約しました。" & vbCrLf & _
"Excelを開いたままにしておいてください。", vbInformation
End Sub
'============================================================
' ■ 自動実行されるマクロ(テスト用)
' → 本番ではここに集計処理などを書く
'============================================================
Sub MyTask()
MsgBox "指定時刻になりました!" & vbCrLf & _
"現在時刻: " & Format(Now, "yyyy/mm/dd hh:nn:ss"), vbInformation
End Sub
書き換えポイント
| 変数 | 説明 | 初期値 |
|---|---|---|
| `runTime` | 自動実行する時刻(24時間表記) | `”09:00:00″` |
| `macroName` | 実行するマクロの名前 | `”MyTask”` |
コードの流れ
TimeValue(runTime)で時刻文字列をDate型に変換Application.OnTimeで指定時刻にマクロを予約- 指定時刻になると
MyTaskが自動で実行される
まずはテスト用の MyTask(メッセージ表示)で動作確認する。 実行時刻を1〜2分後に設定して、自動でメッセージが表示されることを確認してから、本番の処理に書き換えるとよい。
指定時刻がすでに過ぎている場合は、即座に実行される(エラーにはならない)。テスト時はこの性質を利用すると便利。
コード(実務版)– 繰り返し実行+停止ボタン付き
実務では「毎朝9時に実行」「1時間ごとに実行」のように繰り返しが必要になる。最小版は1回限りなので、繰り返し実行+停止機能を追加した実務版を用意した。
停止ボタンの設置方法は マクロをボタン1つで実行する方法 を参考にしてほしい。
'============================================================
' ■ 繰り返し自動実行+停止機能(実務版)
' → 指定間隔で繰り返しマクロを自動実行
' → 停止ボタン or StopSchedule で予約をキャンセル
'============================================================
'--- モジュールレベル変数(予約時刻の保持用)
Dim nextRunTime As Date
'--- ★書き換えポイント ---
Const INTERVAL_HOURS As Long = 1 '← 繰り返し間隔(時間)。0にする場合はINTERVAL_MINUTESを設定
Const INTERVAL_MINUTES As Long = 0 '← 繰り返し間隔(分)。テスト時は1〜2分に設定すると確認しやすい
Const TASK_MACRO As String = "MyTask" '← 実行するマクロ名
'--- ★ここまで ---
'============================================================
' ■ スケジュール開始
'============================================================
Sub StartSchedule()
'--- 次回の実行時刻を計算
nextRunTime = Now + TimeSerial(INTERVAL_HOURS, INTERVAL_MINUTES, 0)
'--- OnTime で予約
Application.OnTime nextRunTime, "RunAndReschedule"
MsgBox "スケジュールを開始しました。" & vbCrLf & _
"次回実行: " & Format(nextRunTime, "yyyy/mm/dd hh:nn:ss") & vbCrLf & _
"間隔: " & INTERVAL_HOURS & "時間" & INTERVAL_MINUTES & "分" & vbCrLf & _
"停止するには StopSchedule を実行してください。", vbInformation
End Sub
'============================================================
' ■ 処理実行+次回予約(自動で呼ばれる)
'============================================================
Sub RunAndReschedule()
'--- 本体の処理を実行
Application.Run TASK_MACRO
'--- 次回を予約(繰り返し)
nextRunTime = Now + TimeSerial(INTERVAL_HOURS, INTERVAL_MINUTES, 0)
Application.OnTime nextRunTime, "RunAndReschedule"
'--- 状態をステータスバーに表示
Application.StatusBar = "次回実行: " & Format(nextRunTime, "hh:nn:ss") & _
" (停止するには StopSchedule を実行)"
End Sub
'============================================================
' ■ スケジュール停止
'============================================================
Sub StopSchedule()
On Error Resume Next
Application.OnTime nextRunTime, "RunAndReschedule", , False
On Error GoTo 0
Application.StatusBar = False '← ステータスバーをリセット
MsgBox "スケジュールを停止しました。", vbInformation
End Sub
'============================================================
' ■ 自動実行されるマクロ(テスト用)
' → 本番ではここに集計処理などを書く
'============================================================
Sub MyTask()
'--- ★ここに本番の処理を書く ---
' 例: 複数シートの集計、PDF出力、メール送信など
'--- テスト用: A1に実行日時を記録
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(1)
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row + 1
ws.Cells(lastRow, 1).Value = "自動実行"
ws.Cells(lastRow, 2).Value = Now
End Sub
書き換えポイント
| 変数 | 説明 | 初期値 |
|---|---|---|
| `INTERVAL_HOURS` | 繰り返し間隔(時間) | `1`(1時間ごと) |
| `INTERVAL_MINUTES` | 繰り返し間隔(分) | `0` |
| `TASK_MACRO` | 実行するマクロ名 | `”MyTask”` |
※ 「毎朝9時に1回だけ」にしたい場合は INTERVAL_HOURS = 24 にする。
コードの流れ
- StartSchedule: 次回の実行時刻を計算し、
Application.OnTimeで予約 - RunAndReschedule: 指定時刻になるとマクロを実行し、さらに次回を予約(繰り返し)
- StopSchedule:
Schedule:=Falseで予約をキャンセル。On Error Resume Nextでキャンセル済みでもエラーにならない - MyTask: 実際に実行される処理。テスト用にA列に実行日時を記録する
複数シートの集計処理を定時で回すなら 複数シートを一括処理する方法 のコードを
MyTaskの中に組み込める。日付判定で「平日だけ実行」にしたい場合は 日付・曜日の判定で月末処理を自動化 の Weekday 関数を使う。
停止ボタンの設置
StopSchedule を実行するボタンをシート上に設置しておくと、ワンクリックで停止できて安全。ボタンの設置方法は マクロをボタン1つで実行する方法 を参照。
よくある落とし穴5選
1. 指定時刻にマクロが実行されない
原因: Excelを閉じている or PCがスリープ状態。
OnTimeはExcelのプロセス内で動くため、Excelが起動していないと実行されない。PCがスリープ中も同様。
対策: 自動実行したい時間帯はExcelを開いたままにしておく。PCのスリープ設定も確認する。確実に動かしたい場合はWindowsの「タスクスケジューラ」との併用を検討する(本記事の範囲外)。
2. OnTimeの繰り返しが止まらない
原因: StopScheduleを実行していない。
自分もこれでやらかした。OnTimeの繰り返し処理を止め忘れてExcelを閉じたら、次回起動時にエラーが連発した。「実行時エラー 1004」が出続けて、何が起きたか分からなかった。原因はOnTimeの予約が残っていたこと。
対策: 実務版コードの StopSchedule を必ず実行してから閉じる。または、Workbook_BeforeCloseイベントで自動停止する(FAQ参照)。
3. 「実行時エラー 1004」でマクロが動かない
原因: Schedule:=False でキャンセルするとき、予約時と異なる時刻を指定している。
対策: キャンセルには「予約したときと同じ時刻」が必要。実務版コードでは nextRunTime 変数で時刻を保持しているため、この変数を使えばOK。変数を使わずに手入力するとズレてエラーになる。
4. Timer関数とDo…LoopでExcelがフリーズする
最初は自分もTimer関数と Do…Loop で無理やり待機処理を書いていたが、Excel全体がフリーズしてまったく使い物にならなかった。OnTimeを知ってからは、こんなに簡単にできるのかと驚いた。
対策: 時刻を待つ処理には必ず Application.OnTime を使う。Do…Loop + Timer や Sleep はExcelが操作不能になるため使わない。
5. マクロ名を間違えて「マクロが見つかりません」
原因: OnTimeに指定するマクロ名のスペルミス or モジュールが複数あるとき。
対策: マクロ名はVBEで確認する。Sub の後ろに書いてある名前をそのまま使う。標準モジュールが複数あるなら "Module1.MyTask" のようにモジュール名を含める。
FAQ
Q1: Excelを閉じてもマクロを定時実行できる?
OnTimeはExcelが起動している必要がある。Excelを閉じた状態で定時実行したい場合は、Windowsの「タスクスケジューラ」でExcelファイルを開くバッチを組む方法がある(本記事の範囲外)。
Q2: Excelを閉じるとき自動で停止する方法は?
ThisWorkbookモジュールに以下のコードを追加する:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Call StopSchedule
End Sub
VBEの左側で「ThisWorkbook」をダブルクリックして、コードウィンドウに貼り付ける。これで、ブックを閉じるときに自動でOnTimeの予約がキャンセルされる。
Q3: 平日だけ実行したい場合は?
MyTask の先頭に曜日判定を入れる:
Sub MyTask()
'--- 土日ならスキップ
If Weekday(Now, vbMonday) >= 6 Then Exit Sub
'--- ここに本番の処理 ---
End Sub
曜日判定の詳細は 日付・曜日の判定で月末処理を自動化 を参照。
Q4: 「毎朝9:00ちょうど」に実行したい場合は?
StartSchedule の時刻計算を変更する:
Sub StartScheduleAt9()
Dim targetTime As Date
targetTime = Date + TimeValue("09:00:00")
'--- もう9時を過ぎていたら翌日の9時に設定
If targetTime <= Now Then
targetTime = targetTime + 1
End If
nextRunTime = targetTime
Application.OnTime nextRunTime, "RunAndRescheduleDaily"
End Sub
Q5: 定時実行でPDF出力やメール送信もできる?
できる。MyTask の中身を差し替えるだけ。
- PDF出力: ExcelファイルをPDFに一括変換 のコードを組み込む
- メール送信: Excelからメール自動作成(Outlook連携) のコードを組み込む
OnTimeはあくまで「指定時刻にマクロを呼び出す」仕組み。呼び出すマクロの中身は何でもよい。
まとめ
Application.OnTimeで指定時刻にマクロを自動実行できる- 最小版は3行。テスト用マクロで動作確認してから本番に入れ替える
- 繰り返し実行は「処理の最後に次回を予約」するパターン
- 停止処理(StopSchedule)は必須。止め忘れるとExcel終了時にエラーが出る
- Excelを開いたままにしておく必要がある(PCのスリープにも注意)
関連記事
- セルの値が変わったら自動実行(Worksheet_Change) — 「セル変更」をトリガーにする自動実行
- マクロをボタン1つで実行する方法 — 停止ボタンの設置に使える
- 複数シートを一括処理する方法 — 定時実行で呼び出す集計処理
- 日付・曜日の判定で月末処理を自動化 — 平日だけ実行する条件分岐
- ファイルをバックアップする方法 — 定時バックアップの自動化
次にやりたくなること
- ExcelファイルをPDFに一括変換: 定時にPDF出力。日次報告書の自動生成に直結する
- Excelからメール自動作成(Outlook連携): 定時にメールを自動作成。集計結果を毎朝メールで配信する仕組みが作れる
定時実行を仕込んでおけば、出張中も安心。まずは最小版で「Excelが勝手に動く」感覚を体験してみてほしい。


コメント