【VBA】WaitとSleepで処理を一時停止・タイミング制御する方法(コピペOK)

VBA
スポンサーリンク

記事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

スポンサーリンク
  1. この記事でわかること
    1. どんな場面で使う?
  2. 完成イメージ(Before / After)
  3. 実行前の準備
    1. バックアップを取る
    2. Excelをマクロ有効ブック(.xlsm)で保存する
  4. 手順(コピペ → 実行まで約5分)
    1. VBE(コードを書く画面)を開く
    2. 標準モジュールを挿入する
    3. コードを貼り付けて実行する
  5. コード(基本版1)– Application.Waitで指定秒数だけ待つ(VBA標準)
    1. 書き換えポイント
  6. コード(基本版2)– Sleep APIで指定ミリ秒だけ待つ(Windows API)
    1. 書き換えポイント
  7. Application.Wait vs Sleep API 比較表
  8. コード(実務版)– 待機付きループでデータ取得を安定化(エラー処理付き)
    1. 書き換えポイント
  9. よくある落とし穴5選
    1. 1. Declare文をSub内に書いてコンパイルエラー
    2. 2. Application.Waitに秒数を直接渡して動かない
    3. 3. Sleep中にExcelが「応答なし」になって焦る
    4. 4. 64ビット版ExcelでDeclare文がコンパイルエラー
    5. 5. DoEventsループでTimer関数が深夜0時にリセットされる
    6. VBAのApplication.Waitで指定した秒数だけ待てないときの対処法
    7. VBAのSleepでExcelが応答なしになるときの対処法
  10. FAQ
    1. Q1: WaitとSleepはどう使い分ける?
    2. Q2: 0.5秒だけ待ちたい場合はどうする?
    3. Q3: ループの中で毎回Waitを入れると遅くなる?
    4. Q4: Application.OnTimeとの違いは?
    5. Q5: MacでSleep APIは使える?
  11. まとめ
    1. 関連記事
  12. 次にやりたくなること

この記事でわかること

  • 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 のままだとマクロが保存できない。

  1. 「ファイル」→「名前を付けて保存」
  2. ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
  3. 保存

手順(コピペ → 実行まで約5分)

VBE(コードを書く画面)を開く

  1. Excelで Alt + F11 を押す

標準モジュールを挿入する

  1. VBEのメニュー →「挿入」→「標準モジュール」

コードを貼り付けて実行する

  1. コードウィンドウに、下のコードをそのままコピペする
  2. Sleep APIを使う場合: Declare文がモジュールの一番上(Subの前)にあることを確認する
  3. 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は避ける

関連記事

---

次にやりたくなること

コメント

タイトルとURLをコピーしました