VBAでミリ秒単位の処理時間を計測!Win32 API(GetTickCount)の実装ガイド

Tech

【執筆作法:プロフェッショナル・実務指向】

  • 導入は結論から入り、冗長な挨拶を省く。

  • メリットだけでなく、実装上のリスクや制約(APIのオーバーフロー等)を併記する。

  • コードは可読性を重視し、変数の命名規則を統一する。

本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。

VBAでミリ秒単位の処理時間を計測!Win32 API(GetTickCount)の実装ガイド

【背景と目的】

VBA標準のTimer関数は秒単位の精度が低く、高速なループ処理のボトルネック特定には不向きです。本稿ではWin32 APIを用い、ミリ秒単位の高精度な計測手法を解説します。

【処理フロー図】

graph TD
A["計測開始:GetTickCount取得"] --> B["Excel/Access最適化:描画停止等"]
B --> C["メイン処理実行:ループ・DB操作"]
C --> D["Excel/Access復旧:描画再開等"]
D --> E["計測終了:GetTickCount再取得"]
E --> F["差分計算・結果表示"]

【実装:VBAコード】

Option Explicit

' --- Win32 API 宣言 (64bit/32bit両対応) ---
#If VBA7 Then

    ' Windows起動後からの経過時間をミリ秒単位で取得
    Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
#Else

    Private Declare Function GetTickCount Lib "kernel32" () As Long
#End If

''' <summary>
''' 高精度な処理時間計測の実行サンプル
''' </summary>
Sub ExecuteTimeMeasurement()
    Dim startTime As Long
    Dim endTime As Long
    Dim processTime As Double
    Dim i As Long

    ' 1. 計測開始時間の取得
    startTime = GetTickCount()

    ' 2. アプリケーションの高速化設定(Excelの場合)
    On Error GoTo ErrorHandler
    With Application
        .ScreenUpdating = False         ' 画面更新停止
        .Calculation = xlCalculationManual ' 自動計算停止
        .EnableEvents = False           ' イベント抑止
    End With

    ' --- 3. メイン処理(例:10万行のダミー処理) ---
    For i = 1 To 100000
        ' ここに実際の業務ロジックを記述
        Cells(i Mod 100 + 1, 1).Value = i
    Next i
    ' ---------------------------------------------

    ' 4. アプリケーション設定の復旧
    Call RestoreSettings

    ' 5. 計測終了時間の取得
    endTime = GetTickCount()

    ' 6. 結果の算出(ミリ秒を秒に変換)
    processTime = (endTime - startTime) / 1000

    MsgBox "処理が完了しました。" & vbCrLf & _
           "実行時間: " & Format(processTime, "0.000") & " 秒", vbInformation, "計測結果"

    Exit Sub

ErrorHandler:
    Call RestoreSettings
    MsgBox "エラーが発生しました: " & Err.Description, vbCritical
End Sub

''' <summary>
''' Excelの設定を元に戻す共通処理
''' </summary>
Private Sub RestoreSettings()
    With Application
        .ScreenUpdating = True
        .Calculation = xlCalculationAutomatic
        .EnableEvents = True
    End With
End Sub

【技術解説】

  1. Win32 APIの活用: GetTickCount はWindowsシステムが起動してからの経過時間をミリ秒(1/1000秒)単位で保持するカウンタを参照します。VBA標準の Timer 関数よりも分解能が高く、パフォーマンスチューニングに不可欠です。

  2. PtrSafe属性と条件付きコンパイル: 64bit版OfficeではAPI宣言に PtrSafe が必須です。#If VBA7 を用いることで、旧バージョンとの互換性を維持しています。

  3. ボトルネックの最小化: 実務では ScreenUpdating(画面更新)の停止が最も効果的です。計測対象の処理だけでなく、その「前後」を含めて最適化コードで囲むのが定石です。

【注意点と運用】

  • 49.7日の壁: GetTickCount は戻り値が Long 型であるため、Windowsを連続起動して約49.7日が経過するとカウンタがゼロに戻り(オーバーフロー)、計測値が負になるリスクがあります。サーバーOS等で利用する場合は注意が必要です。

  • エラーハンドリング: 高速化のために ScreenUpdating を停止させた場合、途中でエラー終了すると画面が固まった状態に見えます。必ず On Error 構文で設定を復旧させるルーチンを組み込んでください。

【まとめ】

  1. 精度向上: ミリ秒単位の計測には標準関数ではなくWin32 API(GetTickCount)を採用する。

  2. 環境配慮: 64bit化が進む実務環境に合わせ、必ず PtrSafe 宣言を行う。

  3. 一貫性: 処理開始直前と直後で取得し、アプリケーション最適化(画面更新停止等)の恩恵も含めて評価する。

ライセンス:本記事のテキスト/コードは特記なき限り CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。

コメント

タイトルとURLをコピーしました