Windows起動後の経過時間の取得方法

VBAには経過時間をミリ秒で取得できるTimer関数がありますが、0時になると0ミリ秒にリセットされるため、日付を超える場合は利用できません。

Windowsを起動してからどれぐらいの時間が経っているかを調べるには、Win32API(Windows API)のGetTickCount関数やGetTickCount64関数を利用します。

GetTickCount64関数を使えるのであればそちらをお勧めします。


構文

64bit版です。

Declare PtrSafe Function GetTickCount Lib “kernel32” () As Long
Declare PtrSafe Function GetTickCount64 Lib “kernel32” () As LongLong

GetTickCount戻り値 Windowsが起動してからどれだけ経過したかをミリ秒で返します。約49.7日まで扱えます。
GetTickCount64戻り値 Windowsが起動してからどれだけ経過したかをミリ秒で返します。通常は約2.9億年まで扱えます。

使う方だけを標準モジュールなどの先頭あたりに記述します。


戻り値の範囲

GetTickCount関数は宣言では戻り値がLong型になっていますが、実際の定義では符号なしの32ビットの整数値になります。同様に、GetTickCount64関数の戻り値はLongLong型ですが実際の戻り値は符号なしの64ビットの整数値です。

そのため、扱える値の範囲は以下のようになります。

関数 最小値 最大値 日数・年数換算
GetTickCount 0 4,294,967,296 約49.7日(4,294,967,296÷(1000ms×60s×60m×24h)=49.7102696296日)
GetTickCount64 0 18,446,744,073,709,551,616 約5.8億年(18,446,744,073,709,551,616÷(1000ms×60s×60m×24h×365.2425)=584,554,049.254)

表のとおり、GetTickCount関数とGetTickCount64関数の戻り値は符号なし(マイナス値なし)ですが、VBAのLong型が扱える値の範囲は符号つきの −2,147,483,648 から 2,147,483,647 で、LongLong型は -9,223,372,036,854,775,808 から 9,223,372,036,854,775,807 のため、GetTickCount関数またはGetTickCount64関数の戻り値のほぼ半分の値までしか扱えません。

では、GetTickCount関数で半分(約24.8日)を超えた値が帰ってきた場合どうなるのか、という話になりますが、戻り値をLong型の変数で受け取った場合は2,147,483,647を超えてしまうためオーバーフローとなり異常が発生します。

そこで対応方法としては、戻り値はLong型ではなく64ビットのLongLong型で受け取ればオーバーフローにならずに済みます。LongLong型がないバージョンのExcelであればDouble型でも代用できます。ただ、そういうことを考えるのが面倒であればGetTickCount64関数を使うことをお勧めします。

なお、GetTickCount64関数では最大値が約5.8億年で、「PC起動して5.8億年つけっぱなしにしたらオーバーフローで落っこちました」なんてことはありえないため、考慮不要でLongLong型で受け取ってよいと思います。ただし、約5.8億年は符号なしの場合のため、符号ありのLongLong型では半分の約2.9億年が限度になります。


サンプルコード

GetTickCount関数とGetTickCount64関数のサンプルです。比較としてTimer関数も出力しています。

モジュールの先頭あたりにDeclare~の構文を記述します。

先に書いた説明の通り、GetTickCount関数の戻り値を受け取る変数はLong型ではなくLongLong型で設定しています。LongLong型がない場合はDouble型でも構いません。

実行結果
GetTickCount ミリ秒:434636359
GetTickCount64 ミリ秒:434636359
Timer ミリ秒:81633
GetTickCount 秒:434636.359
GetTickCount64 秒:434636.359
Timer 秒:81.633
GetTickCount 分:7243.93931666667
GetTickCount64 分:7243.93931666667
Timer 分:1.36055
GetTickCount 時:120.732321944444
GetTickCount64 時:120.732321944444
Timer 時:2.26758333333333E-02
GetTickCount 日:5.03051341435185
GetTickCount64 日:5.03051341435185
Timer 日:9.44826388888889E-04
GetTickCount 年:1.37730779259036E-02
GetTickCount64 年:1.37730779259036E-02
Timer 年:2.58684679052654E-06