VBAのWait・Sleep・DoEventsを使い分ける

VBAのWait・Sleep・DoEventsを使い分ける

待機処理を「止められる待機」「眠らせる待機」「イベントを処理する待機」に分けて理解する

Copyright © 2026 LWP 山中 一弘

本資料は、出典を明記いただければ、商用・非商用を問わず、ご自由に複製・改変・再配布していただけます。なお、著作権表示は改変せず、そのまま記載してご利用くださいますようお願いいたします。

記事要約

 VBAで一定時間待つ処理を書くとき、よく出てくる選択肢が Application.Wait、Windows APIの Sleep、そして DoEvents です。どれも「待つ」ために使われますが、実際には待ち方、CPU負荷、中断のしやすさ、ユーザー操作への反応が大きく違います。

 この記事では、Wait、Sleep、DoEventsを同じ待機命令として並べず、それぞれの性質を分けて整理します。WaitはExcel側で待機しながらキー入力を見ている待機、SleepはOSにプロセスを眠らせる待機、DoEventsは待機そのものではなくイベント処理を挟むための命令として扱います。

 最終的な判断は単純です。初心者や安全側に倒したい処理ではWaitを優先します。CPU負荷を抑え、指定ミリ秒だけ確実に止めたい処理ではSleepを検討します。ただし、Sleepは中断しにくく、宣言も必要です。DoEventsはWaitの挙動を補正できますが、中断性や速度に別の副作用が出るため、無条件に入れるものではありません。

本記事の対象とゴール

想定読者

  • VBAで一定時間待つ処理を書きたい人

  • Application.Wait と Sleep の違いを、実務上の安全性で判断したい人

  • DoEvents を待機処理に入れるべきか迷っている人

  • ESCキーやCtrl+Breakで止められるかどうかを重視している人

本記事で得られること

  1. Wait、Sleep、DoEventsを同じ「待つ命令」として混同しなくなります。

  2. CPU負荷、待機精度、中断性、書きやすさで使い分けられます。

  3. 待機処理でExcelを固めるリスクを事前に避けられます。

本記事で扱わないこと

  • Windows APIの詳細仕様を網羅すること

  • マルチスレッドやOSスケジューラの内部動作を断定的に説明すること

  • すべてのExcelバージョンで同じ実測結果を保証すること

先に結論

 VBAの待機処理は、まずWaitを基準に考えるのが安全です。WaitはCPU負荷や精度の面で弱点がありますが、ESCキーやCtrl+Breakで中断しやすく、誤った指定をしても復帰できる可能性が残ります。

 SleepはCPU負荷を抑え、ミリ秒単位で指定しやすい一方、待機中にExcelが眠っているため、ユーザー操作で自発的に目覚めることは期待できません。大きな値を誤って渡すと、その時間が過ぎるまで中断できないリスクがあります。

 DoEventsは、待機中にExcelへイベント処理の機会を渡すための命令です。Waitと組み合わせるとESCを離した後に次のWaitが回復するなどの効果がありますが、処理速度が落ちたり、ESCでの中断感が変わったりします。待機処理を何でもDoEventsで解決しようとすると、別の不安定さを持ち込みます。

第1章(WaitとSleepは待ち方が違う)

 この章では、WaitとSleepを「どちらも待つ命令」としてではなく、待機の仕組みが逆に近いものとして整理します。

1.1(WaitはExcel側で待ち続ける)

 Application.Wait は、ExcelのApplicationオブジェクトが持つ待機処理です。指定した時刻になるまでExcel側で待ちます。

 元まとめでは、Waitは無限ループする関数を実行しているような状態として説明されています。実際の内部実装をここで断定するわけではありませんが、体感上は「Excelが動いたまま、時刻を見ながら待っている」状態に近く見えます。

 そのため、Wait中はExcelがフリーズしているように見えることがあります。また、CPU使用率が上がることがあります。ただし、待機中にキー入力を監視しているため、ESCキーやCtrl+Breakによる中断が効く場面があります。

1.2(SleepはOSに眠らせてもらう)

 Sleep は、Excel固有の命令ではありません。Windows APIを呼び出し、指定したミリ秒数だけ現在の処理を眠らせます。

 Sleep中は、Excelが自分から起きて処理を進めることはできません。OSに眠らされている状態なので、ユーザーがExcelに対して何か操作しても、指定時間が過ぎるまでVBA側が自発的に復帰することは期待しにくくなります。

 その代わり、CPUを消費し続けません。待っている間にPCへ余計な負荷をかけにくく、他のアプリケーションを操作しながら待たせる用途では安定しやすい場合があります。

1.3(DoEventsは待つ命令ではない)

 DoEvents は、指定時間だけ待つ命令ではありません。VBAの処理をいったん譲り、WindowsやExcelに溜まっているイベントを処理させるための命令です。

 待機ループの中にDoEventsを入れると、画面更新、キー入力、クリックなどを処理しやすくなります。そのため、Waitや自作待機処理と組み合わせて使われます。

 ただし、DoEventsを入れたから安全になるとは限りません。イベント処理の機会を増やすことは、処理の割り込みや再入の可能性も増やすということです。待機処理の中に入れる場合は、何を回復させたいのかを明確にする必要があります。

第2章(中断できるかどうかで見る)

 この章では、待機処理で実務上いちばん重要になりやすい「止められるか」を見ます。

2.1(WaitはESCやCtrl+Breakで止められる可能性がある)

 Waitの大きな利点は、中断しやすいことです。誤って長い待機時間を指定した場合でも、ESCキーやCtrl+Breakで止められる可能性があります。

 これは、開発中や不安定なVBAを試しているときに大きな意味を持ちます。待機処理の指定を間違えると、Excelが長時間操作不能になります。そこで中断できる余地があるWaitは、安全側の選択になります。

 ただし、ESCだけで常に意図どおり止められるわけではありません。元まとめでは、ESCを押すと本来必要だった待機時間がスルーされ、何ステップも進んでからデバッグモードに入ることがある、という観察が示されています。

2.2(Sleepは待機時間が終わるまで戻りにくい)

 Sleepは、指定した時間を確実に眠るための命令です。これは長所でもあり、短所でもあります。

 たとえば、10秒待つつもりで100秒を指定した場合、その100秒が終わるまでVBAを止められない可能性があります。さらに、秒とミリ秒を間違えて1000倍の値を渡すと、Excelごと強制終了を待つような状況になり得ます。

 Sleepを使う場合は、待機時間の単位を明示し、上限を設ける設計が必要です。値をそのまま渡すのではなく、異常に大きい値を拒否する、短いSleepを繰り返す、キャンセル条件を確認するなどの工夫を検討します。

2.3(DoEventsを入れると中断の感触が変わる)

 Waitのループ中にDoEventsを入れると、ESCを離した後に次のWaitが通常どおり働くようになる場合があります。これは、ESCを一度押した影響が以降のWaitへ残る問題を緩和するために有効です。

 一方で、DoEventsを入れると、ESCを押し続けても思ったように中断されない場合があります。Ctrl+Pause/Breakの知識が必要になることもあります。

 つまり、DoEventsは単純な万能薬ではありません。Waitの連続実行でESCの影響が残る問題を改善できる一方、別の中断しにくさや速度低下を持ち込む可能性があります。

第3章(精度と書きやすさで見る)

 この章では、待機時間の指定しやすさと、コードとしての扱いやすさを整理します。

3.1(Waitはミリ秒単位が書きにくい)

 Waitは、指定した時刻まで待つ命令です。そのため、1秒待つだけなら次のように書けます。

vb

Application.Wait Now() + TimeValue("00:00:01")

 しかし、0.1秒のような短い待機を書こうとすると急に扱いづらくなります。時刻を小数として扱ったり、Excel関数のNOWとVBAのNowの精度差を意識したりする必要が出ます。

 元まとめでは、VBAの Now() は秒までの精度、Excel関数の NOW はより細かい精度を持つという観察が示されています。短い待機を正確に扱いたいなら、この違いを意識する必要があります。

3.2(Sleepはミリ秒指定が素直だが宣言が必要)

 Sleepは、待機時間をミリ秒で指定します。書くときの発想は単純です。待たせたいミリ秒数を渡します。

 ただし、VBAからSleepを使うには、Windows APIの宣言が必要です。開発中にすぐ書こうとすると、この宣言が面倒になります。64bit版Officeでは PtrSafe なども意識する必要があります。

 この手間を避けるため、よく使う宣言や呼び出しの形を辞書登録しておく、共通モジュールに閉じ込める、といった運用が現実的です。

3.3(秒とミリ秒の取り違えに注意する)

 Sleepの指定単位はミリ秒です。1秒は1000ミリ秒です。

 この単位を取り違えると、待機時間が極端に短くなったり、極端に長くなったりします。Waitは時刻指定が書きにくい一方、Sleepは単位の取り違えが起きやすい、という別の難しさを持っています。

 待機処理では、変数名に milliseconds や seconds を含める、引数名を明確にする、必要なら秒を受け取って内部でミリ秒へ変換するなど、単位をコードに残すべきです。

第4章(CPU負荷とExcelの反応で見る)

 この章では、待機中にExcelやPCがどう見えるかを整理します。

4.1(Waitは重く見えることがある)

 Waitは、Excelが動いたまま待っているように見えるため、CPU使用率が上がったり、Excelがフリーズしているように見えたりすることがあります。

 元まとめの2ページ目では、Waitがスレッドを完全に停止しているのではなく、実行権を得るたびに時刻を見て、まだなら実行権を放棄しているのではないか、という推測も示されています。これは内部実装の断定ではありませんが、「なぜ重く見えるのか」を考える観点として有効です。

 実務上は、Waitを大量に繰り返す処理や、短い待機を高頻度で行う処理では、Excel全体の反応が悪くならないか確認する必要があります。

4.2(SleepはCPU負荷を抑えやすい)

 SleepはOSに眠らせてもらうため、待機中にCPUを使い続けにくくなります。PCに負荷をかけたくない処理では有利です。

 たとえば、外部アプリケーションの処理完了を待つ、ファイル生成を待つ、一定間隔で状態を確認する、といった場面では、Sleepを短く区切って使う方法が考えられます。

 ただし、Sleepを一回で長く取ると、途中で止める機会がありません。安定性のためにSleepを使うなら、短いSleepを繰り返し、その間にキャンセル条件やタイムアウト条件を見る設計が安全です。

4.3(DoEventsは反応を戻すが速度を落とすことがある)

 DoEventsを入れると、Excelがユーザー操作や画面更新に反応しやすくなります。その一方で、処理速度が急激に落ちることがあります。

 元まとめでは、WaitにDoEventsを入れた場合、ESCを離すと待機時間が回復する一方、ESCを押し続けても中断されず、全体の処理速度が落ちるという観察が示されています。

 DoEventsは、固まって見えるExcelに呼吸をさせる命令として便利です。ただし、速度と中断性に影響するため、ループのたびに無条件で入れるのではなく、必要な頻度に絞るほうが安全です。

第5章(実務での使い分け)

 この章では、Wait、Sleep、DoEventsをどの場面で選ぶかを実務向けに整理します。

5.1(まず安全側ならWait)

 VBA初心者や、開発中の不安定な処理ではWaitを優先します。理由は、止められる可能性が残るからです。

 待機時間を誤って長くしても、ESCやCtrl+Breakで止められる可能性があります。Excelを強制終了しなくて済むかもしれない、というだけでも開発中は大きな利点です。

 一方で、Waitは短い待機や高頻度待機には向きにくい場合があります。待機精度やCPU負荷が問題になったら、Sleepや自作待機処理へ進みます。

5.2(CPU負荷とミリ秒指定を重視するならSleep)

 Sleepは、CPU負荷を抑えたい場合や、ミリ秒単位で待機時間を指定したい場合に候補になります。

 ただし、Sleepを直接長時間呼ぶ設計は避けたほうが安全です。たとえば、1秒を一回で待つのではなく、100ミリ秒を10回繰り返し、その間にキャンセル条件やタイムアウト条件を確認する方法があります。

 こうしておけば、Sleepの軽さを使いながら、中断不能になる時間を短くできます。

5.3(DoEventsは反応を戻したいときだけ入れる)

 DoEventsは、待機中にExcelの反応を戻したいときに使います。画面を更新したい、キャンセルボタンを押せるようにしたい、ESCの影響を整理したい、という目的がある場合です。

 ただし、DoEventsを入れると処理の途中で他のイベントが動く可能性があります。フォーム、シートイベント、再実行ボタンなどが絡む処理では、予期しない再入や状態変化に注意が必要です。

 DoEventsを入れるなら、ループの構造、キャンセル条件、再入防止フラグを合わせて設計します。

第6章(最低限の判断表)

 最後に、実務で迷ったときの判断を文章でまとめます。

 安全に止められることを重視するならWaitです。開発中、初心者向け、誤指定から復帰したい処理ではWaitが扱いやすくなります。

 CPU負荷を下げ、指定ミリ秒だけ待ちたいならSleepです。ただし、API宣言と中断不能時間のリスクを受け入れる必要があります。

 Excelの反応を戻したいならDoEventsです。ただし、DoEventsは待機命令ではなく、イベント処理を許す命令です。処理速度や中断性に副作用が出るため、目的を決めて入れます。

 待機処理は、どれが上位という話ではありません。止められること、軽いこと、正確なこと、反応することは同時に満たしにくい条件です。自分の処理で何を優先するかを決めて選びます。

出典メモ

  • 元Togetter URL: https://togetter.com/li/1831807

  • リダイレクト後URL: https://posfie.com/@hoehoe1234/p/mWVz9XN

  • 2ページ目URL: https://posfie.com/@hoehoe1234/p/mWVz9XN?page=2

  • 元まとめタイトル: 2022-01-16 VBA Wait、Sleep、DoEventsの違い

  • 取得日: 2026-05-16

  • 原型として使った範囲: posfieで公開表示された本文2ページ分。広告、ランキング、関連まとめ、コメント欄は記事素材に含めていません。

  • 画像の扱い: 投稿内画像は、Waitの検証コード、DoEvents有無による挙動比較、Sleepの補足コードを示すものとして確認しました。画像そのものは転載せず、本文内で「ESCの影響」「DoEvents有無」「短いSleepの反復」という説明に置き換えました。