
VBA【DoEvents】使い方・VBAが「応答なし」で固まる時の対策【使いすぎには要注意】

VBAの関数「DoEvents」の使い方とVBAの「DoEvents」とは、なにかを解説します。
Windows7、Windows10、Windows11など、OSに関係なく
エクセルのVBA(マクロ)を実行し、重い処理をしていると、マクロが遅くてエクセルが「応答なし」にしたくないのに固まる事がありますよね。
いわゆる、フリーズですね。マクロ実行中にVBAがフリーズ・・・考えるだけで嫌になりますね。
Excelマクロが「応答なし」になる原因は複数ありますが、VBAの「応答なし」対策と原因を紹介します。
エクセル マクロ 実行中の「応答なし」 を回避、改善対策を知りたい方は、ぜひ、読んでください。
では、VBAの「DoEvents」の使い方と「DoEvents」とはなにかを紹介していきます。
< ---目次--- >
◆VBA「応答なし」の対策
DoEvents
VBAでは「DoEvents」とたったこれだけを記述するだけで、マクロ実行中の「応答なし」を回避できます。
ですが、VBAにおける「DoEvents」の注意事項や「DoEvents」の高速化について記載がありますので、最後までお読みになることをオススメします。
VBAの「DoEvents」とは、VBAからOSにエクセルはちゃんと動作していますよーと返事して、エラーで固まっていない事を報告しています。
厳密には少し違いますが、挙動はこんな感じです。詳細はこちら(VBA「DoEvents」とは?)
それによってVBAの応答なしを回避し、VBAが固まる対策ができます。
エクセルマクロが「応答なし」になるような、遅い処理をしていても、適切なタイミングで「DoEvents」を使うことで応答なしを回避できます。
「DoEvents」 を使うと
VBAのデバッグ時に「Ctrl」+「Pause」( 「Ctrl」+「Break」 )で、コードの中断ができやすくなり、VBAが応答なしにならないです。
DoEventsの使い方は簡単ですが、注意点もあるので、下部に記載していきます。
そもそも「応答なし」の状況すら発生させたくないって方は、マクロを高速化し、PCの負荷を減らすべきです。
VBAを高速化したい方はこちらをご覧ください。
◆「DoEvents」使い方・使う時
・エクセルが「応答なし」になるマクロ(VBA)を実行している時
VBA実行中にエクセルが「応答なし」になるような時に
「DoEvents」使用すると「応答なし」になりません。
・ステータスバー(Application.Statusbar)が固まる事で更新されない時
VBAから制御できるステータスバーが正しく更新されない時に
「DoEvents」使用すると正しく更新表示されます。
ただし、あまりにも重い処理だったりすると、効果はありません。
・VBA実行中の「Ctrl」+「Break」が効かない
VBA実行中に「Ctrl」+「Pause」が効かない、又は、「Ctrl」+「Break」が 効かない時に
処理が重い箇所に適切に「DoEvents」使用すると、VBAを一時停止ができるようになります。
「Ctrl」+「Break」が 効かない対策として、かなり便利です。
◆使用時の注意点
・使用回数
「DoEvents」 自体が少し重いので、使用回数を減らすことで、「DoEvents」使用時のマクロの高速化に繋がります。
なので、VBAでステータスバーが固まる対策として、For Nextなどで繰り返し処理中に使用し、毎回更新するのはオススメしません。
◆「DoEvents」の高速化について
VBA「DoEvents」は元々素早い処理ではありませんので高速化をできません。
ですが、「DoEvents」の使用回数を減らすことでVBAの高速化になりますので
どうしても、使うのであれば、指定回数毎に実行すれば、VBAの「DoEvevts」で高速化できると思います。
VBA「DoEvents」の高速化するサンプルコードは、下記コードです。
500回毎に「DoEvents」 が実行されます。500回っていう回数は、参考なので、処理の重さとPCに合わせてお好みに変更してくださいね。
ステータスバー更新後の表示をしたいがために、低頻度で実行していると、「DoEvents」せいでけっこう重くなりがちなので注意してください。
僕が普段書いているコードでは、1000~10000回の間で実行しています。
Sub DoEvents_Test()
For i = 1 To 10000
If i Mod 500 = 0 Then DoEvents ': Application.StatusBar = "i = " & i & " の時にDoevents実行"
'処理
Next i
End Sub
そもそもマクロが重い場合は、「DoEvents」 の使用回数を減らしてもVBA高速化にはつながらないと思います。
VBAで「DoEvents」を使っても高速化したい方はこちら(VBA高速化の常識)をご覧ください。
◆VBA「応答なし」の原因一覧
・大量データの処理をしている
大量データでも配列を使えば、一瞬で処理できたりします。
詳細は下記リンクをご覧ください。
・「マクロの記録」で作ったVBAをそのまま使用している
「マクロの記録」で作ったVBAは、VBAの処理速度は気にせず、生成されていますので
処理を重くしている部分があれば、そのコードを改変する必要があります。
「マクロの記録」で作ったVBAを少しだけ使う分には、VBAが「応答なし」になりませんが
色々、流用していたら、VBAが「応答なし」になりがちですのでお気を付けください。
「DoEvents」を使う前にVBAのコードを見直して高速化しましょう。
◆VBA「DoEvents」とは
VBA「DoEvents」とは、OSに制御権を渡します。かなり要約するとそんな感じです。
・解説
VBAの「DoEvents」関数は、 開かれているフォームの数を返します。 他のすべてのアプリケーションでは、「DoEvents」はゼロを返します。
開かれているフォームが無い場合は「0」を返します。
ですが、値を使うことは、まずないでしょう。
今回の記事のように、VBAが「応答なし」の時に使用して
「応答なし」を回避する時に使用する事が大半だと思います。
VBAで「DoEvents」を使用する時は、処理が重くて、エクセルが固まってしまう時やファイルの検索などで処理が開始された後で
VBA実行中に「Ctrl」+「Pause」が効かない、又は、「Ctrl」+「Break」が 効かない対策として
VBAを一時停止ができるようにする時に使用してください。
◆まとめ
この記事を読んで、理解すれば、エクセルが応答なしになる対策も把握できますし、適切な「DoEvents」の使い方を知ることができますね。
◆「あなたへ」のおすすめリンク
マクロを高速化したいあなたへ~VBA高速化の常識~
マクロでできることをおさらい