一定時間だけ処理を止めるには

VBAの処理中に一定時間だけ処理を止めたいことがあります。方法としてWin32APIのSleep関数とApplication.Waitメソッドが挙げられます。

どちらを使ってもいいのですが、引数に一時停止時間をミリ秒で指定するだけのSleep関数の方が直感的で使いやすいです。Application.Waitメソッドは「いつまで止めるか(いつから再開するか)」という時刻を指定する方法になります。

以下ではSleep関数とWaitメソッドの使い方を紹介します。

なお、一時停止の途中でSleepをやめることができるWin32APIのSleepEx関数もありますが、そこまで厳密な一時停止処理はVBAではまず用途が無いと思いますのでここでは省略します。


Sleep関数の構文

64bit版です。モジュールに以下の構文をそのまま書いておくと利用できます。一般的には標準モジュールの先頭に書くことが多いです。

Declare PtrSafe Sub Sleep Lib “kernel32” Alias “Sleep” (ByVal dwMilliseconds As Long)

dwMilliseconds:ミリ秒で指定します。1秒=1000ミリ秒のため、1秒止めたい場合は1000を指定します。マイナス値を指定するとVBAから応答が返ってこなくなり、Excelをタスクマネージャなどで強制終了することになります。

戻り値はありません。


Sleep関数のサンプルコード

Sleep関数の使い方は単純です。何ミリ秒止めるかを引数で指定するだけです。Declareの行を忘れずに書いてください。

実行結果
2021/09/21 0:51:42
2021/09/21 0:51:43
2021/09/21 0:51:44
2021/09/21 0:51:45
2021/09/21 0:51:46
2021/09/21 0:51:47


Application.Waitメソッドの構文

Function Wait(Time) As Boolean

Time いつまで停止するかをDate型に変換できる時分秒の時刻で指定します。”00:00:00″形式で指定するか、TimeValue関数で”00:00:00″形式で指定するか、TimeSerial関数で時分秒を指定すると、正しい引数として認識されます。
戻り値 指定した時刻に達するとTrueを返します。



Application.Waitメソッドのサンプルコード

以下のコードはApplication.Waitメソッドの引数のパターンを変えてます。文字列で”00:00:00″形式で時刻を指定する方法と、現在日時にTimeValue関数で1秒を”00:00:00″形式で加算する方法です。

実行結果
2021/09/21 0:53:01
2021/09/21 0:53:02
2021/09/21 0:53:03
2021/09/21 0:53:04
2021/09/21 0:53:05
2021/09/21 0:53:06
2021/09/21 0:53:07


一時停止の用途

処理を一時停止する用途は、大きく分けて2つあります。

1つは、VBAから他のプログラムの操作を行い、その処理の待ち時間として利用する場合です。

例えばVBAからバッチファイルを実行し、その処理が終わるまでの時間が10秒だとしたら余裕を見て待ち時間としてSleep関数で20秒間停止したり、インターネットからURLを変えながら情報を取得する際に、一定時間置いてから再度アクセスしてサーバーの負荷を上げないようにするための待ち時間などです。

もう1つは、恒常ループや無限ループと言われるような同じ処理を繰り返し行う場合に、CPUを休ませる目的で使います。ただ、最近のPCはコア数やスレッド数が複数あるのが一般的ですので、「VBAがCPUを独占しているため他のプログラムが動かない」、なんて話はほぼ無くなってはいます。


Sleep関数とWaitメソッドのどちらを使えばよいか

Sleep関数とWaitメソッドは用途が異なります。

どちらも同じような使い方は出来ますが、処理中に一時的にVBAの処理を止めたい場合はSleep関数を利用し、処理を再開する時刻を指定する場合はApplication.Waitメソッドを利用した方が、あとから見たときに何をしたいコードなのか分かりやすくなります。