【Excel VBA】Win32 APIによる高精度ミリ秒計測と処理高速化の実装

Tech

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

【Excel VBA】Win32 APIによる高精度ミリ秒計測と処理高速化の実装

【背景と目的】

大量のデータ処理や複雑な計算を行うマクロにおいて、標準のTimer関数(1秒単位)ではボトルネックの特定が困難です。本稿ではWin32 APIを利用し、ミリ秒単位での精密な計測手法を解説します。

【処理フロー図】

graph TD
A["計測開始"] --> B["Win32 APIで開始時刻を取得"]
B --> C["メイン処理実行"]
C --> D["Win32 APIで終了時刻を取得"]
D --> E["差分を計算しミリ秒単位で出力"]
E --> F["終了"]

【実装:VBAコード】

64bit/32bit両環境に対応したPtrSafe宣言を行い、配列処理と描画停止を組み合わせた実戦的なコード例です。

Option Explicit

' --- Win32 API 宣言 (64bit環境を考慮したPtrSafeを使用) ---
#If VBA7 Then

    ' システム起動後の経過時間をミリ秒単位で取得
    Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
#Else

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

''' <summary>
''' 高精度な処理時間計測と高速化を適用したサンプルプロシージャ
''' </summary>
Sub HighPrecisionMeasure()
    Dim startTime As Long
    Dim endTime As Long
    Dim processTime As Double
    Dim i As Long
    Dim dataArr As Variant

    ' --- 高速化設定:画面更新と自動計算の停止 ---
    With Application
        .ScreenUpdating = False
        .Calculation = xlCalculationManual
        .EnableEvents = False
    End With

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

    ' --- メイン処理:ここでは配列を使用したデータ操作の例 ---
    ' セルへの直接アクセスを避け、メモリ上で処理することで高速化
    dataArr = Range("A1:A10000").Value

    For i = 1 To UBound(dataArr, 1)
        ' サンプル処理(例:値を加工)
        dataArr(i, 1) = dataArr(i, 1) * 1.1
    Next i

    Range("B1:B10000").Value = dataArr
    ' --------------------------------------------------

    ' 2. 計測終了時刻の取得
    endTime = GetTickCount()

    ' --- 高速化設定の解除 ---
    With Application
        .ScreenUpdating = True
        .Calculation = xlCalculationAutomatic
        .EnableEvents = True
    End With

    ' 3. 結果の計算と表示 (endTime - startTime)
    processTime = (endTime - startTime) / 1000 ' 秒単位に変換

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

【技術解説】

  1. GetTickCountの優位性: VBA標準のTimer関数はWindowsのシステム時刻に依存し、精度が不十分(約15.6ms単位)な場合がありますが、GetTickCountはシステム起動時からの経過ミリ秒を直接参照するため、より高精度な計測が可能です。

  2. PtrSafe宣言: Officeのビット数(32/64bit)にかかわらず動作させるための必須記述です。

  3. ボトルネックの解消: ScreenUpdating(画面更新停止)や配列への一括格納を利用することで、Excel-VBA間のオーバーヘッドを最小化しています。計測はこの高速化手法の効果を定量化するために必須となります。

【注意点と運用】

  • オーバーフローの境界: GetTickCountが返すLong型は、システムを約49.7日間連続稼働させると値がループ(0に戻る)します。サーバーOS等で長時間連続稼動している端末では注意が必要ですが、通常の事務作業端末では問題になりません。

  • デバッグ時の注意: ScreenUpdating = Falseのままエラーで中断すると、Excelの操作ができなくなる(描画されない)ため、必ずErrハンドラ内で設定を戻す処理を記述することを推奨します。

【まとめ】

  1. ミリ秒単位の可視化: Win32 APIにより、微細なコード修正によるパフォーマンスの変化を数値で捉えることができます。

  2. 高速化の定石: 描画停止・自動計算停止・配列処理の3点セットを、API計測とセットで導入しましょう。

  3. 互換性の確保: #If VBA7による条件分岐を使い、あらゆる社内環境で動作する堅牢なツールを目指します。

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

コメント

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