【VBA入門】Sleep関数(API)やWaitメソッドで処理を止める方法

Sleep関数って使っていますか?

VBAで処理を指定時間止める場合に使用します。Sleep関数はVBAの関数ではなく、Windows APIの関数です。

VBAで指定した時間だけ処理を止める方法はSleep関数を使う以外にも、ApplicationオブジェクトのWaitメソッドを使う方法などがあります。

この記事では、指定した時間だけ処理を止める方法について

  • VBAで処理を指定時間止めるには?
  • Sleep関数の使い方
  • Waitメソッドの使い方
  • 停止時間を実測比較してみよう

など基本的な内容から、応用的な内容についても解説していきます。

今回は指定した時間だけ処理を止める方法について、使い方をわかりやすく解説します!

目次

VBAで処理を指定時間止めるには?

VBAで処理を指定時間止めるにはWindows APIのSleep関数を使うことが多いです。

Sleep関数は処理を止める時間をミリ秒(1秒の1000分の1)単位で指定することができます。

一方で、VBAではApplicationオブジェクトのWaitメソッドで時間を指定して処理を止めることもできます。ただWaitメソッドは多くの方が秒単位でしか停止時間を指定できないと思われているようです。

しかし、実はWaitメソッドでもミリ秒単位で停止時間を指定する方法があります。

Waitメソッドでもミリ秒単位で停止する方法を知らないがために、みなさんWindows APIのSleep関数を使われているのではないでしょうか?

この記事では、Windows APIのSleep関数使い方とVBAのApplicationオブジェクトのWaitメソッドの使い方を詳しく解説し、それぞれの実際の停止時間を計測比較してみましょう。

Sleep関数の使い方

Windows APIのSleep関数を呼び出して使用するには、マクロのエディターの一番上に以下のように記述する必要があります。

Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)

Sleep関数の引数には停止する時間をミリ秒単位で指定します。

Sleep 停止時間

サンプルコードで確認しましょう。

Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)

Sub macro1()
    Dim time As Long
    time = 500
    
    Sleep time
    
    MsgBox time & "ミリ秒後に表示しました"
End Sub

実行結果:
sleep01

このサンプルコードを実行すると、long型変数timeで指定した時間だけ遅れてメッセージボックスが表示されます。

Waitメソッドの使い方

ApplicationオブジェクトのWaitメソッドを秒単位で指定する場合は、以下のように記述します。

Application.Wait Now() + TimeValue("00:00:01")

Application.Waitメソッドは、引数で指定された時刻まで停止します。

Now関数で現在の時刻を取得し、それにTimeValue関数の値を加算することで、停止する時刻を指定します。この例の場合、現在の時刻の1秒後を指定したことになります。

また、Waitメソッドをミリ秒単位で指定する場合は、以下のように記述します。

Application.Wait [Now()] + 500 / 86400000

今度は引数内のNow関数を「[ ]」で囲っています。こうすることでミリ秒単位で停止時間を指定することができます。

この例の場合、現在の時刻の500ミリ秒後を指定したことになります。86400000という数字は1日をミリ秒に換算した値です。

サンプルコードで確認しましょう。

Sub macro2()
    Dim time As Long
    time = 500
    
    Application.Wait [Now()] + time / 86400000
    
    MsgBox time & "ミリ秒後に表示しました"
End Sub

実行結果:
sleep01

ちなみに、Now関数やTimeValue関数の使い方については、こちらで詳しく解説していますので、ぜひ参考にしてくださいね。

停止時間を実測比較してみよう

それではWindows APIのSleep関数とApplication.Waitメソッドで停止時間の精度を比較してみましょう。

停止時間は100ミリ秒で設定しています。時間の取得にはWindows APIのGetTickCountを使用して、ミリ秒単位で取得します。

GetTickCountを使用するには、以下のように記述する必要があります。

Private Declare Function GetTickCount Lib "kernel32" () As Long

以下のサンプルコードで比較します。

Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)
Private Declare Function GetTickCount Lib "kernel32" () As Long

Sub macro3()
    Dim time As Long
    time = 100 '待機時間
    
    Dim newTimer As Long
    Dim t1 As Long, t2 As Long
    
    newTimer = GetTickCount '計測開始
    Sleep time
    t1 = GetTickCount - newTimer '待機時間算出
    
    newTimer = GetTickCount '計測開始
    Application.Wait [Now()] + time / 86400000
    t2 = GetTickCount - newTimer '待機時間算出
    
    MsgBox "Sleep関数で待機: " & t1 & "ミリ秒" & vbCrLf & _
            "Waitメソッドで待機: " & t2 & "ミリ秒"
End Sub

実行結果:
sleep02

このサンプルコードで確認した結果はこのようになりました。

停止時間を100ミリ秒で指定すると、どちらも多少の誤差が生じ精度は同じくらいです。ちなみに停止時間を500ミリ秒で指定すると、どちらも計測結果は500ミリ秒となり、精度に差はありませんでした。

この結果から、Windows APIのSleep関数とApplication.Waitメソッドどちらを使っても構わないと言えるかと思います。

まとめ

ここでは、指定した時間だけ処理を止める方法について説明しました。

Windows APIのSleep関数は関数を呼び出す手間はかかりますが、ミリ秒単位で時間を指定できます。Application.Waitメソッドは秒単位の指定以外にも、ミリ秒単位でも時間を指定できます。

停止時間の精度を実測比較しましたが、どちらも同じような精度でしたので、どちらを使っても構わないと言えます。どちらか使いこなすことができるように、この記事を何度も参考にして下さいね!

この記事を書いた人

熊本在住のフリープログラマ兼ライターです。C/C++/C#、Java、Python、HTML/CSS、PHPを使ってプログラミングをしています。専門は画像処理で最近は機械学習、ディープラーニングにはまっています。幅広くやってきた経験を活かしてポイントをわかりやすくお伝えしようと思います。
お問合せはこちらでも受け付けています。
info@sss-lab.com

目次