ExcelVBAでマクロを作成していると、「この処理が終わってから次の処理に進めたいのに、順番通りに動かない」「セルの値を書き込む前にメッセージが表示されてしまう」といった現象に悩んだことはありませんか?
これは処理の順序制御や同期に関する問題で、初心者だけでなく中級者にとっても意外とつまずきやすいポイントです。
この記事では「vba 処理が終わってから次の処理」というキーワードで検索された方に向けて、以下の内容をわかりやすく解説します。
✅ VBAで処理が途中で進んでしまう原因とは?
✅ 正しい順番で処理を実行するための基本構文
✅ DoEventsの使い方と「処理待ち」の考え方
✅ 外部処理やファイル操作が絡む場合の待機制御
✅ 実務で役立つサンプルコードとトラブル対策
目次
- ✅ VBAは「上から順に実行される」が完了を待たないケースもある
- ・ ただし、次のような処理では「完了を待たずに進む」ことがある
- ✅ 処理が終わってから次の処理に進めるための基本的な方法
- ・ 順番通りに処理される通常パターン(セル代入など)
- ・DoEventsを使って処理完了を保証する
- ・ 条件付きループで処理完了を待つ(監視型)
- ✅ 外部処理の終了を待ってから次へ進むには?
- ・印刷が終わるのを待ってから次へ進む方法
- ・Shellで起動したアプリが終了してから次に進む方法
- ・IEやWebブラウザ操作の処理完了を待つ方法
- ■ 処理の順番を保証するための構文テクニック
- ■ よくあるミスとその対策
- ・ 無限ループでExcelがフリーズ
- ・ Waitを使いすぎて処理が止まりすぎる
- ・ モデルレスフォームの制御ミス
- ■ まとめ|VBAで「処理が終わってから次へ進める」方法は安定動作の鍵
- ・ 本記事のまとめポイント
✅ VBAは「上から順に実行される」が完了を待たないケースもある
基本的に、VBAのコードは上から順番に1行ずつ実行されます。以下のようなコードは、意図通りに動作します。
Sub Sample()
Range("A1").Value = "完了"
MsgBox "次の処理へ"
End Sub
この場合、セルA1に「完了」と書き込まれてからメッセージボックスが表示されます。
・ ただし、次のような処理では「完了を待たずに進む」ことがある
- 印刷(
PrintOut
) - ファイル保存(
SaveAs
)や外部ブック読み込み - Shell関数によるアプリ起動
- モデルレスフォームの表示
- Internet Explorer や Chromeの自動制御
- セルの再計算・画面の更新が未完了の場合
これらは命令が完了する前に次の行へ処理が進んでしまうため、「処理が終わってから次へ進める」ための工夫が必要になります。
✅ 処理が終わってから次の処理に進めるための基本的な方法
・ 順番通りに処理される通常パターン(セル代入など)
Range("B1").Value = "データ取得中"
Call GetData
MsgBox "データ取得が完了しました"
このように、処理が明確に順番通りで完結している場合は特別な制御は不要です。
【VBA】変数にまとめて代入する方法|複数代入・配列・オブジェクトの扱いも解説
・DoEventsを使って処理完了を保証する
DoEvents
は、VBAが実行を一時的に止めて、Windowsの他の処理(再描画・入力受付など)に制御を渡す命令です。
Range("A1").Calculate
DoEvents
MsgBox "計算後の処理を開始します"
DoEventsを入れることで、再描画やセル計算、フォームの更新などが完了した後に次の処理を実行できます。
「前の処理が終わってから」次へ進める方法|同期制御・DoEvents・待機の基本を徹底解説
・ 条件付きループで処理完了を待つ(監視型)
Do
DoEvents
Loop Until Range("A1").Value = "完了"
MsgBox "A1セルの処理完了を検知しました"
このように、処理の結果(セルの値など)を監視して、完了後に次の処理に移るという構成が有効です。
✅ 外部処理の終了を待ってから次へ進むには?
Excel以外の操作(外部ファイル、印刷、他アプリなど)では、VBAが命令を出した時点で完了と見なすため、追加の制御が必要です。
・印刷が終わるのを待ってから次へ進む方法
ActiveSheet.PrintOut
Application.Wait Now + TimeValue("00:00:03") ' 3秒だけ待機
MsgBox "印刷完了想定で次の処理へ"
時間に余裕を持って Application.Wait
で「処理待ち」のように見せる方法です。
・Shellで起動したアプリが終了してから次に進む方法
Declare PtrSafe Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Declare PtrSafe Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Sub RunAndWait()
Dim pid As Long
pid = Shell("notepad.exe", vbNormalFocus)
Dim hProcess As Long
hProcess = OpenProcess(&H100000, False, pid)
Call WaitForSingleObject(hProcess, &HFFFFFFFF)
MsgBox "メモ帳が閉じられました"
End Sub
このように、Shellで起動したアプリのプロセス終了を待つAPI呼び出しも、処理の同期には有効です。
・IEやWebブラウザ操作の処理完了を待つ方法
Do While ie.Busy Or ie.ReadyState <> 4
DoEvents
Loop
Webページの読み込みが完了するまで待機する構文です。
■ 処理の順番を保証するための構文テクニック
方法 | 説明 |
---|---|
DoEvents | 他の処理の完了を許可・反映させる |
Application.Wait | 一定時間だけ止める(完全停止) |
条件付きDoLoop | 値や状態を確認してから次へ進む |
Shell+APIでプロセス監視 | 外部アプリケーションの終了を検知 |
イベント処理(フォームなど) | 入力完了や操作完了をトリガーにする処理構成 |
■ よくあるミスとその対策
・ 無限ループでExcelがフリーズ
Do
Loop Until Range("A1").Value = "OK"
→ DoEvents
を入れないと応答不能になります
・ Waitを使いすぎて処理が止まりすぎる
Application.Wait Now + TimeValue("00:01:00")
→ イベント処理が無効になるため、キャンセル操作が効かない
【VBA】処理が終わるまで待機させる【Sleep関数・Application.Waitメソッド】
・ モデルレスフォームの制御ミス
UserForm1.Show vbModeless
' 次の処理がすぐ動いてしまう
→ 対策:DoEventsを使うか、フォームの完了を検知する構成に変更
■ まとめ|VBAで「処理が終わってから次へ進める」方法は安定動作の鍵
VBAマクロを安定して動かすには、「今の処理が終わったことを確認してから次の処理を開始する」構成がとても重要です。意図せず進んでしまう処理を防ぐことで、エラーや不具合を減らすことができます。
・ 本記事のまとめポイント
- VBAは基本的に順番に処理されるが、一部の処理は非同期動作する
DoEvents
は再描画や入力受付を許可する命令- 条件付きループ(Do Loop)で処理待ちを実現できる
- 印刷やShell実行などの外部処理はAPIやWaitで制御可能
- 無限ループやWaitの乱用には注意が必要