VBA(Visual Basic for Applications)でループ処理や時間のかかる処理を行っていると、Excelがフリーズしたように見えることがあります。そんなときに活躍するのが DoEvents
という命令です。DoEvents
を使えば、VBAの実行中でも画面更新や他の操作への応答が可能になります。本記事では、DoEvents
の基本的な役割から、実際の使用例、注意点、応用方法までを詳しく解説します。VBA初心者にも分かりやすく説明していますので、ぜひ最後までお読みください。
DoEventsとは何か?
DoEvents
は、VBAのコード実行中にOS(Windows)に処理を一時的に渡す命令です。これにより、VBAの実行中でも以下のような動作が可能になります。
- ユーザーがウィンドウを移動したり、サイズ変更したりする
- メッセージボックスの操作ができる
- 「キャンセルボタン」を押すなどの中断操作を受け付ける
- スクロールや再描画が行える
ExcelのVBAでは、特にループ処理や時間のかかる処理において、DoEvents
を適切に挟むことで「応答不能な状態」を回避できます。
なぜDoEventsが必要なのか?
通常、VBAコードは順次処理されていき、完了するまでユーザーの操作を受け付けません。たとえば、以下のようなコードを実行すると、Excelが一切の操作を受け付けなくなります。
Sub EndlessLoop()
Do While True
' 無限ループ
Loop
End Sub
このような場合に DoEvents
を加えると、ループの途中でもOSに処理が戻るため、強制終了したり、UIを操作できたりします。
Sub SafeLoop()
Do While True
DoEvents ' 処理を一時的にOSに渡す
Loop
End Sub
DoEvents
は、一時的にOSに制御を渡してメッセージキューを処理させるような動きです。結果として、Excelの画面更新やユーザー操作への反応が可能になります。
DoEventsの基本的な使い方
最も一般的な使い方は、ループ処理の中に DoEvents
を挟むことです。以下に、典型的な例を示します。
Sub カウント表示()
Dim i As Long
For i = 1 To 10000
Cells(1, 1).Value = i
DoEvents ' ユーザーが操作可能になる
Next i
End Sub
このコードは、セルA1に1から10000まで順番に表示していく処理です。DoEvents
を入れなければ、処理が完了するまで画面が固まり、途中の変化は一切見えません。しかし DoEvents
を入れることで、リアルタイムに値が変化していくのが確認できます。
DoEventsの活用例:処理の途中でキャンセルボタンを使う
ユーザーに処理を中断させるボタンを設ける場合、DoEvents
は必須です。次のように「キャンセルボタン付きフォーム」と組み合わせるのがよくある使い方です。
手順例:
- ユーザーフォーム(UserForm1)を作成し、「キャンセル」ボタン(CommandButton1)を設置
- グローバル変数でキャンセルフラグを保持
- ループ中に
DoEvents
を入れて、ボタン操作を検知
コード例:
' モジュールレベルで宣言
Public CancelFlag As Boolean
Sub StartProcess()
CancelFlag = False
UserForm1.Show vbModeless
Dim i As Long
For i = 1 To 10000
If CancelFlag = True Then
MsgBox "処理を中断しました。"
Exit For
End If
Cells(1, 1).Value = i
DoEvents
Next i
Unload UserForm1
End Sub
' フォームのキャンセルボタンのクリックイベント
Private Sub CommandButton1_Click()
CancelFlag = True
End Sub
このように DoEvents
を活用することで、VBAの処理を柔軟に制御できます。
DoEventsを使う際の注意点
DoEvents
は便利ですが、以下の点に注意しなければなりません。
1. 処理速度が遅くなる
DoEvents
を頻繁に呼び出すと、OSとのやりとりが発生するため、処理が重くなる可能性があります。数万回のループに DoEvents
を毎回入れると、顕著に遅くなる場合があります。
2. 意図しない操作を受け付ける
DoEvents
により、他のマクロや操作も途中で割り込む可能性があります。誤操作や再実行など、想定外の動作を引き起こさないよう、ユーザーの操作範囲を制限するなどの対策も必要です。
3. エラー処理と併用するときの工夫
DoEvents
の使用中にエラーが発生することもあります。適切な On Error
処理や、フラグ管理が重要になります。
DoEventsの代替案と最新の考え方
近年では、DoEvents
に頼らない方法も模索されています。たとえば以下のような代替手段があります。
1. タイマーを使った分割処理
処理を一括で行うのではなく、一定間隔で分割して実行するように設計します。これはユーザーフォーム+タイマーイベントで可能です。
2. ワークシート関数や非同期VBAとの併用
あまり一般的ではありませんが、Excel 365以降ではVBA以外の方法で非同期処理や更新制御を行う手段も検討されています。
とはいえ、シンプルかつ柔軟に使える DoEvents
は、現在でも多くのシーンで活躍しています。
まとめ
DoEvents
は、VBA実行中の応答性を確保する非常に便利な命令です。
- 長いループや大量処理中にユーザー操作を可能にする
- キャンセルボタンや画面更新に対応できる
- 使いすぎには注意が必要
正しく使えば、ユーザーに優しいアプリケーションをVBAで構築することができます。VBAの自動化をより柔軟に、かつ安定的に行いたい方は、ぜひ DoEvents
を理解して活用してみてください。