記事ID: 101
タイトル: 【VBA】WaitとSleepで処理を一時停止・タイミング制御する方法(コピペOK)
カテゴリ: シート操作
一次キーワード: VBA Wait Sleep 処理待ち
想定読者: VBAで処理の一時停止やタイミング制御が必要な初心者〜初級者(製造/品質/管理/事務)
検索意図: VBAで処理を一定時間止めたい・Application.WaitとSleep APIの違いと使い方を知りたい
読者の悩み(1文): VBAで「○秒待ってから次の処理を実行」したいのに、やり方がわからない
読了後にできること(1文): Application.WaitとSleep APIの使い分けを理解し、処理の一時停止をコピペで実装できる
前提条件:
- Excel版: Excel 2016以降 / Microsoft 365
- OS: Windows 10/11
- 保存形式: .xlsm(マクロ有効ブック)
- 貼り付け場所: 標準モジュール(Sleep APIのDeclare文はモジュール先頭)
- 実行方法: Alt+F8でマクロ実行 / ボタン割り当て
更新日: 2026-03-18
—
この記事でわかること
- Application.Waitで指定秒数だけ処理を一時停止できる
- Sleep APIでミリ秒単位の精密な待機ができる
- WaitとSleepの違いを比較表で理解し、場面に応じて使い分けられる
- DoEventsと組み合わせて、長時間待機中もExcelが固まらない処理が書ける
対象: Excel 2016以降 / Microsoft 365、Windows 10/11
どんな場面で使う?
- Webスクレイピングでページの読み込み完了を待ってからデータを取得するとき
- 外部ファイルの生成を待ってからそのファイルを開くとき
- メール送信後に次のメールまで間隔を空けてサーバー負荷を避けるとき
- バッチファイルの処理完了を待ってから結果を取り込むとき
—
完成イメージ(Before / After)
Before(待機なし):
マクロ実行 → 即座に次の処理 → データ未取得でエラー
After(待機あり):
マクロ実行 → 3秒待機 → データ取得成功 → 次の処理へ
処理の間に「ちょっと待つ」を入れるだけで、外部データの取得やファイル操作が安定する。
—
以前Webスクレイピングのマクロを書いたとき、ページの読み込みを待たずにデータを取りにいって、結果が空っぽだった。何回実行しても同じで、正直焦った。WaitとSleepを覚えてからは、外部データ取得やファイル操作で「ちょっと待つ」を入れるだけで安定して動くようになった。「待つだけ」なのに意外とやり方がわからない。この記事で処理待ちの基本を押さえてもらえればうれしい。
VBAで処理を一時停止するにはApplication.WaitかSleep APIを使う。秒単位ならWait、ミリ秒単位ならSleepが基本。
なお、Webスクレイピングで待機処理を活用する具体例は Webページの表をExcelに自動取得する方法 を参照。
—
実行前の準備
バックアップを取る
実務版コードはシートにデータを書き込む。必ずファイルのコピーを別フォルダに保存してから実行する。
Excelをマクロ有効ブック(.xlsm)で保存する
拡張子が .xlsx のままだとマクロが保存できない。
- 「ファイル」→「名前を付けて保存」
- ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
- 保存
—
手順(コピペ → 実行まで約5分)
VBE(コードを書く画面)を開く
- Excelで
Alt + F11を押す
標準モジュールを挿入する
- VBEのメニュー →「挿入」→「標準モジュール」
コードを貼り付けて実行する
- コードウィンドウに、下のコードをそのままコピペする
- Sleep APIを使う場合: Declare文がモジュールの一番上(Subの前)にあることを確認する
Alt + F8→ マクロ名を選んで「実行」
ボタンに割り当てれば毎回Alt+F8を押さなくて済む。方法は マクロをボタン1つで実行する方法 を参照。
—
コード(基本版1)– Application.Waitで指定秒数だけ待つ(VBA標準)
セルA1に「処理開始」と書き込み、3秒待ってから「処理完了」に書き換える。まずはこれで動きを確認する。
'============================================================
' ■ Application.Waitで3秒待機(基本版)
' → セルA1に「処理開始」を書き込み、3秒後に「処理完了」に書き換え
'============================================================
Sub WaitBasic()
Range("A1").Value = "処理開始"
'--- 3秒間待機(現在時刻 + 3秒後まで待つ)
Application.Wait Now + TimeValue("00:00:03")
Range("A1").Value = "処理完了"
MsgBox "3秒待機しました。", vbInformation
End Sub
書き換えポイント
| 変数・引数 | 説明 | 初期値 |
|---|---|---|
TimeValue("00:00:03") |
待機時間(時:分:秒) | 3秒 |
Range("A1") |
結果を表示するセル | A1 |
ポイント: Application.Waitの引数は「何時何分何秒まで待つか」というシリアル日付値。Now + TimeValue("00:00:03") で「現在時刻から3秒後」を指定している。秒数を直接渡す(Application.Wait 3)と意図しない動作になるので注意。
—
コード(基本版2)– Sleep APIで指定ミリ秒だけ待つ(Windows API)
Sleep APIを使って2000ミリ秒(2秒)待機する例。Declare文はモジュールの一番上に書く。
'============================================================
' ■ Sleep APIで2秒待機(基本版)
' → Declare文はこのモジュールの先頭に記述すること
'============================================================
Option Explicit
'--- ★この宣言はモジュールの一番上(Subの前)に貼り付ける ★
' Excel 2010以降はすべてVBA7=Trueだが、
' 古い環境との互換性のために #If VBA7 分岐を入れている
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
Sub SleepBasic()
Range("A1").Value = "処理開始"
'--- 2000ミリ秒(2秒)待機
Sleep 2000
Range("A1").Value = "処理完了"
MsgBox "2秒待機しました。", vbInformation
End Sub
書き換えポイント
| 変数・引数 | 説明 | 初期値 |
|---|---|---|
Sleep 2000 |
待機時間(ミリ秒) | 2000ms = 2秒 |
注意: Sleep実行中はExcelが完全にフリーズする。タイトルバーに「(応答なし)」と表示されることがあるが、待機が終われば正常に戻る。長時間のSleep(10秒以上など)は避ける。
—
Application.Wait vs Sleep API 比較表
| 項目 | Application.Wait | Sleep API |
|---|---|---|
| 種類 | VBA標準機能 | Windows API(kernel32.dll) |
| 最小単位 | 1秒 | 1ミリ秒 |
| 引数の書き方 | Now + TimeValue("00:00:03") |
Sleep 3000(ミリ秒指定) |
| 待機中のExcel | 応答あり(ただしマクロ操作は不可) | 完全にフリーズ(応答なし) |
| Mac対応 | 対応 | 非対応(Windows限定) |
| Declare文 | 不要 | 必要(モジュール先頭に記述) |
| 64ビット対応 | 対応済み | PtrSafe修飾子が必要 |
| 推奨用途 | 一般的な秒単位の待機 | ミリ秒精度が必要な待機 |
結論: 迷ったらApplication.Wait。ミリ秒単位の精度が必要な場合だけSleep APIを使う。
—
コード(実務版)– 待機付きループでデータ取得を安定化(エラー処理付き)
Webスクレイピングや外部ファイル操作など、相手の応答を待つ必要がある場面で使う。DoEventsを組み合わせてExcelが固まらない待機ループを実装する。
Webスクレイピングのマクロに2秒のWaitを挟むようにしてからは、データ取得の失敗がほぼゼロになった。指定時刻にマクロを自動実行する方法 との組み合わせで定時の自動データ収集もできている。
※ Sheet1のA列・B列にデータを書き込みます。実行前にバックアップを取ってください。
'============================================================
' ■ 待機付きループでデータ取得を安定化(実務版・エラー処理付き)
' → 外部処理の完了を待ちながら、Excelが固まらない待機を実装
' → DoEventsでExcelの応答を維持し、ステータスバーに進捗表示
' → エラー発生時も高速化設定を確実に復帰させる
'============================================================
Option Explicit
'--- Sleep APIを使う場合はこの宣言が必要(モジュール先頭)
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
Sub FetchDataWithWait()
'--- ★書き換えポイント ---
Dim waitSec As Long
waitSec = 2 '← 1回あたりの待機秒数
Dim maxRetry As Long
maxRetry = 5 '← 最大リトライ回数
Dim targetSheet As String
targetSheet = "Sheet1" '← データを書き込むシート名
'--- ★ここまで ---
Dim ws As Worksheet
On Error Resume Next
Set ws = ThisWorkbook.Worksheets(targetSheet)
On Error GoTo 0
If ws Is Nothing Then
MsgBox "シート「" & targetSheet & "」が見つかりません。", vbExclamation
Exit Sub
End If
'--- 高速化設定
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
'--- ★エラー時も高速化設定を確実に復帰させる
On Error GoTo ErrHandler
Dim retryCount As Long
Dim dataOK As Boolean
Dim fetchResult As String
dataOK = False
For retryCount = 1 To maxRetry
'--- ステータスバーに進捗表示
' Application.StatusBarはScreenUpdating=Falseでも更新される
Application.StatusBar = "データ取得中... 試行 " & retryCount & "/" & maxRetry
'--- ★ここに外部データ取得処理を書く(例: XMLHTTP, QueryTables等)
' 以下はデモ用のダミー処理(3回目で成功する想定)
If retryCount >= 3 Then
fetchResult = "取得データサンプル_" & Format(Now, "yyyymmdd_hhnnss")
dataOK = True
Else
fetchResult = ""
dataOK = False
End If
'--- ★ここまでを実際の取得処理に置き換える
If dataOK Then
'--- 取得成功: シートに書き込み
ws.Range("A1").Value = "取得日時"
ws.Range("B1").Value = "データ"
ws.Range("A2").Value = Now
ws.Range("B2").Value = fetchResult
Exit For
End If
'--- 取得失敗: 待機してからリトライ
' DoEventsを挟みながら短いSleepをループすることで
' Excelの応答を維持しつつ待機する
Dim waitEnd As Double
waitEnd = Timer + waitSec
Do While Timer < waitEnd
DoEvents '← Excelの応答を維持
Sleep 100 '← 100ミリ秒ずつ待機(CPU負荷を抑える)
Loop
Next retryCount
CleanUp:
'--- 高速化設定を元に戻す(エラー時もここを通る)
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.StatusBar = False '← ステータスバーをリセット
'--- 結果表示
If dataOK Then
MsgBox "データ取得に成功しました(" & retryCount & "回目)。", vbInformation
Else
MsgBox "データ取得に失敗しました(" & maxRetry & "回試行)。" & vbCrLf & _
"ネットワーク接続を確認してください。", vbExclamation
End If
Exit Sub
ErrHandler:
MsgBox "エラーが発生しました: " & Err.Description, vbCritical
dataOK = False
Resume CleanUp
End Sub
書き換えポイント
| 変数 | 説明 | 初期値 |
|---|---|---|
waitSec |
1回あたりの待機秒数 | 2 |
maxRetry |
最大リトライ回数 | 5 |
targetSheet |
データを書き込むシート名 | "Sheet1" |
| ダミー処理部分 | 外部データ取得の実際の処理 | デモ用(3回目で成功) |
ポイント: Do While Timer < waitEnd: DoEvents: Sleep 100: Loop が「Excelが固まらない待機」の定番パターン。DoEventsで画面描画やユーザー操作に応答し、Sleep 100でCPU使用率を抑えている。
画面更新・再計算を止めてマクロを高速化する方法 のScreenUpdating/Calculationの設定と組み合わせて使うのが実務の基本。エラーが起きたときに高速化設定が戻らないリスクは On Error GoTo ErrHandler + CleanUp ラベルで対策している。エラー処理の詳細は エラー処理(On Error)で止まらないマクロを作る方法 を参照。
---
よくある落とし穴5選
1. Declare文をSub内に書いてコンパイルエラー
自分もこれで地味にハマった。Sleep APIのDeclare文をSub内に書いて「コンパイルエラー」が出て、原因がわからず20分ロスした。Declare文はモジュールの一番上(Sub/Functionの外)にしか書けない。
| # | 症状 | 原因 | 対策 |
|---|---|---|---|
| 1 | コンパイルエラーが出る | Declare文がSub/Function内にある | モジュール先頭(Option Explicitの下、Subの前)に移動する |
2. Application.Waitに秒数を直接渡して動かない
| # | 症状 | 原因 | 対策 |
|---|---|---|---|
| 2 | Application.Wait 3 が一瞬で通過する、または超長時間待機になる |
引数がシリアル日付値(Date型)なのに整数を渡している | Application.Wait Now + TimeValue("00:00:03") と書く |
' NG: 3 はシリアル日付値で「1900年1月3日」の意味になる
Application.Wait 3
' OK: 現在時刻から3秒後まで待つ
Application.Wait Now + TimeValue("00:00:03")
' これでもOK: TimeSerialでも書ける
Application.Wait Now + TimeSerial(0, 0, 3)
3. Sleep中にExcelが「応答なし」になって焦る
| # | 症状 | 原因 | 対策 |
|---|---|---|---|
| 3 | Excelタイトルバーに「(応答なし)」と表示される | SleepはExcelのスレッドを完全に停止するため | Sleepは短時間(数秒以内)に抑える。長時間待機はDoEvents + Sleep 100のループにする |
Sleepに極端に大きい値(例: Sleep 60000 = 1分)を渡すと、その間ずっとExcelがフリーズする。必要な待機時間を明確にしてから指定すること。
4. 64ビット版ExcelでDeclare文がコンパイルエラー
| # | 症状 | 原因 | 対策 |
|---|---|---|---|
| 4 | 「64ビットシステムでは更新が必要です」エラー | PtrSafe修飾子がないDeclare文を64ビットExcelで使っている | #If VBA7 Then ... Declare PtrSafe ... #Else ... #End If で記述する |
' NG: PtrSafeなしの古い書き方(64ビットExcelでエラー)
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
' OK: #If VBA7で32ビット/64ビット両対応
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
5. DoEventsループでTimer関数が深夜0時にリセットされる
| # | 症状 | 原因 | 対策 |
|---|---|---|---|
| 5 | 深夜0時をまたぐ処理で待機ループが終了しない、または一瞬で通過する | Timer関数は0時にリセットされ0に戻る | 深夜に実行する可能性がある場合は、Timer代わりにNow + 待機秒数で比較する |
' 通常はこれで問題ない(日中実行の場合)
waitEnd = Timer + waitSec
Do While Timer < waitEnd
DoEvents: Sleep 100
Loop
' 深夜0時をまたぐ可能性がある場合
Dim dtEnd As Date
dtEnd = Now + TimeSerial(0, 0, waitSec)
Do While Now < dtEnd
DoEvents: Sleep 100
Loop
長時間処理の進捗表示は 処理の進捗をステータスバーに表示する方法 が詳しい。Application.StatusBarはScreenUpdating = Falseの状態でも更新される。一方、セルの表示更新にはScreenUpdating = Trueが必要。
VBAのApplication.Waitで指定した秒数だけ待てないときの対処法
「Application.Wait 3 と書いたのに一瞬で通過する」という場合、原因は引数の書き方だ。Waitの引数はシリアル日付値であり、整数の3は「1900年1月3日」を意味してしまう。Application.Wait Now + TimeValue("00:00:03") のように「現在時刻+秒数」の形式で書くのが正解。
VBAのSleepでExcelが応答なしになるときの対処法
「Sleep実行中にExcelが固まって操作できない」という場合、原因はSleepがExcelのスレッドを完全に停止する仕様だからだ。長時間の待機にはSleep単体を使わず、Do While Timer < waitEnd: DoEvents: Sleep 100: Loop のパターンで100ミリ秒ずつ待機しながらDoEventsで応答を維持するのが定番の対処法。
---
FAQ
Q1: WaitとSleepはどう使い分ける?
| 場面 | おすすめ |
|---|---|
| 一般的な秒単位の待機 | Application.Wait |
| ミリ秒精度が必要 | Sleep API |
| Mac環境で使う | Application.Wait(Sleepは使えない) |
| 長時間待機(10秒以上) | DoEvents + Sleep 100 のループ |
迷ったらApplication.Waitで十分。
Q2: 0.5秒だけ待ちたい場合はどうする?
Application.Waitは1秒未満の指定が不安定(環境によって動作が異なる)。Sleep APIなら Sleep 500 で500ミリ秒(0.5秒)を指定できる。
'--- 0.5秒待機(Sleep API)
Sleep 500
Q3: ループの中で毎回Waitを入れると遅くなる?
なる。ただし、外部データ取得やファイル操作で「相手の応答を待つ」目的であれば、待機時間はむしろ必要なコスト。不要な場面でWaitを入れるのは避ける。
ループ処理の基本は Do While/Do Untilで条件付きループを回す方法 を参照。
Q4: Application.OnTimeとの違いは?
| 項目 | Application.Wait | Application.OnTime |
|---|---|---|
| 用途 | 処理の途中で一時停止 | 指定時刻に別マクロを実行 |
| 待機中の操作 | マクロ停止中(Excel操作不可) | Excelは自由に操作可能 |
| 使い方 | 同じSub内で次の処理を待つ | 別のSubをスケジュール実行 |
「ここで○秒止めてから次へ」→Wait、「○時になったら実行」→OnTime。詳細は 指定時刻にマクロを自動実行する方法 を参照。
Q5: MacでSleep APIは使える?
使えない。SleepはWindows API(kernel32.dll)のため、macOSでは動作しない。Mac環境ではApplication.Waitを使う。
---
まとめ
VBAの処理待ちは「ちょっと待つだけ」だが、やり方を間違えるとExcelがフリーズしたり、待機が効かなかったりする。基本はApplication.Waitで十分。ミリ秒精度が必要なときだけSleep、長時間待機にはDoEventsループと覚えておけば迷わない。
- Application.Wait: VBA標準機能。秒単位の待機に使う。
Application.Wait Now + TimeValue("00:00:03") - Sleep API: Windows API。ミリ秒単位の精密な待機に使う。Declare文はモジュール先頭に記述
- 迷ったらApplication.Wait。ミリ秒精度が必要な場合だけSleep API
- 長時間待機: DoEvents + Sleep 100 のループでExcelの応答を維持する
- 注意: Sleepは実行中にExcelが完全にフリーズする。長時間のSleepは避ける
関連記事
- 指定時刻にマクロを自動実行する方法 -- Wait/Sleepの延長で「定時実行」を自動化
- Webページの表をExcelに自動取得する方法 -- 待機処理の実践的な活用シナリオ
- 画面更新・再計算を止めてマクロを高速化する方法 -- Wait中のScreenUpdating設定
- エラー処理(On Error)で止まらないマクロを作る方法 -- Wait/Sleep中のエラーハンドリング
- 処理の進捗をステータスバーに表示する方法 -- 長時間Wait中の進捗表示
---
次にやりたくなること
- 指定時刻にマクロを自動実行する方法: 「毎日15時にデータを取得」など、定時実行を自動化したい場合。WaitからOnTimeへの発展
- Do While/Do Untilで条件付きループを回す方法: 待機ループを条件付きで繰り返したい場合。リトライ処理の基本パターン
- Webページの表をExcelに自動取得する方法: Wait/Sleepを活用してWebスクレイピングを安定させたい場合


コメント