VBA DoEvent

関数

1. DoEventsとは?

DoEvents は、VBAの処理中に オペレーティングシステムに制御を一時的に返す 命令です。これにより、VBAが何らかのループや時間のかかる処理を実行している最中でも、他のイベントや操作(たとえば画面の再描画、ユーザーの操作、フォームの更新など)を受け付けることができるようになります。

通常、VBAのコードが実行されている間は、処理が完了するまで他の処理(UIの操作やイベントの発火など)はブロックされます。これはVBAが 単一スレッド で動作しており、一度に一つの処理しか実行できないためです。しかし DoEvents を使うことで、一時的にVBAの制御をシステムに返し、保留中のイベント(たとえば画面の再描画や他のマクロイベントなど)を処理させることができます。


2. 使用例

(1) ループ処理中の画面更新

Sub カウントアップ()
Dim i As Long
For i = 1 To 10000
Cells(1, 1).Value = i
DoEvents ' ユーザーが画面を操作できるようにする
Next i
End Sub

このような処理では、DoEvents を入れないと、ループが完了するまでExcelの画面が更新されません。DoEvents を入れることで、画面に即座に数値が表示されるようになります。


(2) フォームのボタンで処理の中断を可能にする

ユーザーに処理を中断させたいときにも DoEvents は役立ちます。

Dim StopFlag As Boolean

Sub 長い処理()
Dim i As Long
StopFlag = False
For i = 1 To 1000000
If StopFlag Then Exit For
' 処理内容
DoEvents
Next i
End Sub

Sub 中断ボタン_Click()
StopFlag = True
End Sub

このように、DoEvents を使用することで、UIイベント(ボタンのクリックなど)を受け付けることが可能になり、ユーザーによる中断が実現できます。


3. 利点

  • UIが固まらない
    長時間処理中でもExcelやAccessの画面がフリーズせず、ユーザーは現在の状況を確認しやすくなります。
  • イベントが実行される
    他のフォーム操作やキー操作などのイベントを処理できるようになります。
  • 画面描画の反映
    ループ中にラベルやセルに値を表示するなど、動的な表示更新が可能になります。

4. 注意点と落とし穴

(1) パフォーマンスへの影響

DoEvents を頻繁に呼び出すと、パフォーマンスが低下します。これは、毎回Windowsメッセージループを処理するためにリソースを消費するからです。ループの中で毎回呼び出すのではなく、適切なタイミングや回数に制限を設けるとよいでしょう。

例:

If i Mod 100 = 0 Then DoEvents

(2) 副作用の可能性

DoEvents を使うと、ユーザーが他の操作(保存・閉じるなど)をしてしまう可能性があるため、意図しない動作につながることがあります。また、フォームが操作可能になるため、処理の整合性が崩れることもあります。

(3) スレッド制御と勘違いしないこと

DoEvents はマルチスレッド化するものではありません。処理が中断して他の処理が並列に進むわけではなく、「一時的にOSやExcelの他の処理に譲る」という意味です。


5. 代替案や補助的な手法

VBAでは非同期処理やスレッドは基本的にサポートされていませんが、進捗バーやユーザーキャンセル対応を実装したい場合は、次のような工夫がされます。

  • プログレスバー付きフォームと組み合わせる
  • Application.OnTime を使った擬似的な非同期処理
  • 処理の分割とタイマー実行

まとめ

項目内容
目的イベント処理や画面更新の実現
メリットフリーズ回避、UI反応、ユーザー操作受付
デメリットパフォーマンス低下、副作用の可能性
使用上の注意点頻繁に使わず適切な場所に使う、ユーザー操作への配慮

DoEvents はVBAの処理フローの中で非常に便利な存在ですが、使い方を誤るとプログラムが不安定になったり、予期しない動作につながるリスクもあります。効果と影響を理解したうえで、適切なタイミングと頻度で使用することが重要です。

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