EXCEL VBA 応答なしを回避・実行中のプログラムを中断・停止させる(DoEvents関数)
EXCEL VBA 応答なしを回避・実行中のプログラムを中断・停止させる(DoEvents関数)
今回説明するのは、ループ処理などを利用して複雑な処理を実行すると、プログラムの実行中に【応答なし】と表示され、プログラムが固まっているのか、動作中なのか分からなくなります。DoEvents関数をプログラムの処理途中に追記する事で、プログラム実行中の【応答なし】を回避する事が出来ます。DoEvents関数は、オペレーティングシステムに一時的に制御を移すための関数です。なお、プログラム内にDoEvents関数を多用すると全体的な処理時間が掛かってしまうので、処理内容に応じて実行回数を含めて調整する必要があります。それでは、サンプルプログラムを交えて順番に説明いたします。
●【DoEvents関数については、下記を参照して下さい】(Microsoft社 様)】
https://docs.microsoft.com/ja-jp/office/vba/api/excel.formatconditions
● DoEvents関数を利用するには、下記の通りに設定を行います。
【使用例】
DoEvents
※プログラム内部に設置する。引数なし
【使用例】:DoEvents関数無し
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
' ' Sub DoEvents00() 'DoEvents関数の利用なし Dim I, L As Long For I = 1 To 100000 For L = 1 To 10 Cells(L, "A") = I Next L Next I End Sub ' |
【プログラム実行中】:DoEvents関数無し
【使用例】:DoEvents関数有り
1 2 3 4 5 6 7 8 9 10 11 12 13 |
' ' Sub DoEvents01() 'DoEvents関数の利用あり Dim I, L As Long For I = 1 To 100000 For L = 1 To 10 Cells(L, "A") = I Next L DoEvents 'オペレーティングシステムへ一時的に制御を移す(応答なし回避) Next I End Sub ' |
【プログラム実行中】:DoEvents関数有り
【注意点】
・DoEvents関数を多用すると全体的に処理が遅くなります。
(ループ処理の場合は、100ループに1回DoEvents関数を使うなど処理内容に応じて調整が必要です)
EXCEL VBA 応答なしを回避・ステースクバー実行中の状況を表示させる(DoEvents関数)
下記のサンプルプログラムは、ループ処理内にDoEvents関数を設置し、プログラム実行中の応答無しの回避とステースクバーにより、処理状況を確認する事のできるサンプルプログラムです。なお、下記のプログラムでは、2重ループの構造となっており、ループ①が10万回ループするうちの1万回ごとに、DoEvents関数を実行出来る様に設置して応答なしを回避しています。
【プログラムの流れ】
① ループ①10万回ループします。
② ループ②10回ループします。
③ セル(A1~A10)に数値を記入します。 ※処理部分
④ ループ①で1万回に1回に、ステータスバーに処理状況とDoEvents関数(オペレーティングシステムへ制御を一時的に移す)で「応答なし」を回避します。
⑤ ステータスバーの【■】を加算します。
⑥ ループ①②⇒終了後、ステータスバーを元に戻す。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
' ' Sub DoEvents02() 'DoEvents関数・ステースクバーを表示 Dim I, L As Long Dim Sber As String Sber = "" For I = 1 To 100000 'ループ① For L = 1 To 10 'ループ② Cells(L, "A") = I Next L If I Mod 10000 = 0 Then 'ループ①の10000回に1回処理を行う。 Sber = Sber & "■" '■を加算する。 Application.StatusBar = Sber 'ステースクバーの状況を表示【 ■ 】 DoEvents 'オペレーティングシステムへ一時的に制御を移す(応答なし回避) End If Next I Application.StatusBar = False 'ステースクバーを元の状態に戻す。 End Sub ' |
(画面クリックして拡大)
EXCEL VBA 応答なしを回避・キー操作によりプログラムを一時停止・再開させる(DoEvents関数)
下記のサンプルプログラムは、サンプル①の応用になります。今回のサンプルプログラムは、「ESC」キーを押すことで、処理の実行中に対して中断又は一時停止を行う事ができます。実行処理に時間が掛かるループ処理を行う場合に、一時停止などをする事ができるので、便利だと思います。サンプルプログラム①と同様ループ処理内にDoEvents関数とステースクバーをプログラム内に設置し、処理状況を確認する事もできます。
【プログラムの流れ】
① ループ①10万回ループします。
② ループ②10回ループします。
③ セル(A1~A10)に数値を記入します。 ※処理部分
④ ループ①で1万回に1回に、ステータスバーに処理状況とDoEvents関数(オペレーティングシステムへ制御を一時的に移す)で「応答なし」を回避します。ステータスバーの【■】を加算します。
⑤ キーボードの「ESC」押すと一時停止し、「プログラムを中断しますか?」のメッセージが表示します。
(はい…プログラム停止・いいえ・・そのままプログラム実行)
⑥ ループ①②⇒終了後、ステータスバーを元に戻す。
★【サンプルプログラム】
下記のリンク先よりサンプルプログラムをダウンロードする事ができます。
● DoEvents03(サンプルプログラム)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
' ' Declare PtrSafe Function GetAsyncKeyState Lib "User32.dll" (ByVal vKey As Long) As Long ' Sub DoEvents03() 'DoEvents関数・ステースクバーを表示・プログラムを一時停止・再開 Dim I, L, Ans As Long Dim Sber As String Sber = "" For I = 1 To 100000 'ループ① For L = 1 To 10 'ループ② Cells(L, "A") = I Next L If I Mod 10000 = 0 Then 'ループ①の10000回に1回処理を行う。 Sber = Sber & "■" '■を加算する。 Application.StatusBar = Sber 'ステースクバーの状況を表示【 ■ 】 DoEvents 'オペレーティングシステムへ一時的に制御を移す(応答なし回避) End If If GetAsyncKeyState(27) <> 0 Then 'ESCキーでプログラム一時停止 Ans = MsgBox("プログラムを中断しますか?", vbYesNo) 'メッセージを表示します。 If Ans = vbYes Then Exit Sub 'プログラムを中断します。 End If Next I Application.StatusBar = False 'ステースクバーを元の状態に戻す。 End Sub ' |
(画面クリックして拡大)
また、VBAに関するテクニックや便利な手法などをこのサイトに掲載していきますので、定期的に参照していただけると幸いです。