VBA の DoEventsに対する考察

 DoEventsとは

長年その意味が良くわからなかったのがDoEventsです。

DoEvents 関数 (Visual Basic for Applications) | Microsoft Learn


MicrosoftのTimer関数のサンプルコードでは、ループの合間にDoEvents が実行されています。

Do While Timer < Start + PauseTime
    DoEvents    ' Yield to other processes.
Loop

タイマー関数 (Visual Basic for Applications) | Microsoft Learn


これ、何のために実行してるの? と思い、今回改めて調べてみました。とても参考になったのは次のページです。

読んで字の如くDoEvents #VBA - Qiita


なるほど、DoEventsを実行すると、Excelに対して発生していたイベントをExcelに処理させることができるんですね。


ノンプリエンプティブなマルチタスクOS

そこで疑問に思ったのは、上のコードに書かれていたYield to other processes.というコメントです。

他のプロセスにゆずる、と書かれているけど、他のプロセス(Edgeなど)は、そんなことしなくても処理を続行できるのでは?、と思いました。

そして思い出したのは、Windows 3.1など、いにしえのノンプリエンプティブなマルチタスクOSです。

Windows 3.1 系統(95, 98, Me等)のOSは、OSがExcel等のアプリにCPUの使用権を渡すと、アプリが使用権を自発的に返すまで待つという仕組みでした。これだとアプリが使用権を返さないと、他のアプリはもちろん、OSまで停止してしまいます。

実際、昔のWindowsだと、Windowsごとフリーズして、再起動するしかないという事がしばしば起きました。

それに対して、Windows NT系のOS(2000, XP, 7, 8, 10, 11)は、アプリ等の実行時間をOSが管理していて、アプリを強制的に停止して、他のアプリやOSを動かす仕組みです。これだとExcelがマクロを実行中でも、他のアプリ等も実行可能です。

ノンプリエンプティブOSにおけるDoEventsは、Excelにイベントを実行させる、というよりは、むしろOSに制御を返すのが本来の目的だったのかもしれませんし、レファレンスの記述もそうなっています。


DoEventsはできるだけ使わない方がいい?

DoEventsを使うと、マクロを実行しながらExcelの操作ができるという良い面もあるけれど、Excelを操作できてしまうため、不整合を引き起こす原因にもなりかねません。

例えば、A1セルを参照しながら計算処理をするマクロを実行中に、A1セルの値を書き換えてしまったら当然計算は破綻します。

また、リファレンスには、イベントプロシージャー実行中の問題も書かれています。

それを考えると DoEventsはむやみに使わない方が良いのではないかと思っています。


なお、DoEventsを使う事により、応答なしを回避したり、長時間のプロシージャー実行をキャンセルしたりできるようです。

応答なしを回避する例:

時間がかかる処理での「応答なし」を回避するには?:.NET TIPS - @IT (itmedia.co.jp)

キャンセルの例:

パソコンに関するノウハウ備忘録 (onecolor.jp)


コメント

アクセス数の多い投稿

セキュリティ対策ソフトのノートンが詐欺ソフトまがいになってしまってショック

ZIPファイルを開こうとすると、展開を完了できません、と言われる

Excel 2019 クエリが原因で日本語入力の一文字目が勝手に確定する

Excelのテーブルに行や列を挿入する際のエラー

オカムラ家具のOAチェアー、コンテッサを分解清掃

突然滅茶苦茶遅くなったPCがWindows Updateのキャッシュクリアで復活

ChatGPTが日本語からVBAのコードを生成できてたまげる

Windows セキュリティーのビックリマークが消えない

Power Automate Desktopでブラウザでダウンロードしたファイルを処理する

Excel VBAからODBCを使ってデータを簡単に取得する