VBA でWaitやSleepを使う際の問題
VBAには、そのものずばりの Wait もしくは Sleep がありません。
Application.Wait
Application.Wait は指定した「時間」の停止ではなく、指定した「時刻」まで処理を停止するというよく分からない仕様です。そして何より、Application.Waitは動作が安定していません。
試しに次のようなプロシージャーを実行してみます。
Dim uStart
uStart = Timer
uWait 1
Debug.Print Timer - uStart '経過時間を表示
End Sub
結果は次の通りで、全く安定しません。
私の使い方が悪いのかバグがあるのか。
Timer 関数
そこで、Timer関数を使って次のようなプロシージャーを書いて見ました。
参考にしたのは、次のページです。
4回実行した結果は、次のとおり概ね正確です。
1.001953
1.001953
1.001953
こちらを使った方が良さそうです。
Timer 関数は午前0時からの経過時間を返す関数なので、午前0時を超えてしまうと時間がリセットされ0に戻ってしまいます。なので、午前0時を超えた時の処理を入れてあるけれど、動作は未確認です。
Win 32 API の Sleep
次のように、Win32 APIのSleepが紹介されているサイトも多いです。
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As LongPtr)
これを試したところ、上記のTimerによるプロシージャーと同様に正確でした。
Sleepの方が宣言を書くだけなので簡単ですが、どうも Declare で外部プロシージャーを呼び出すのは好きになれません。
そして、Microsoft 365 Defender for Business では、次のルールを有効化することが推奨されています。
Block Win32 API calls from Office macros
Attack surface reduction rules reference - Microsoft Defender for Endpoint | Microsoft Learn
これを有効にしたら、Win 32 APIを使っているマクロは動かなくなってしまうのではないかと思います。
将来を考えると、Win 32 APIを使うのは避けておいた方が良さそうな気がします。
コメント
コメントを投稿