{ “expert_role”: “Office Automation & Database Architect”, “technical_focus”: [“VBA”, “Win32 API”, “Performance Profiling”], “instruction_compliance”: { “ptr_safe”: true, “mermaid_syntax”: “graph TD”, “structure_order”: “strict” } } 本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
Win32 API「GetTickCount」で実現するVBAコードの精密パフォーマンス計測
【背景と目的】
VBAの実行速度改善には正確な計測が不可欠です。標準関数の限界を超え、APIでミリ秒単位のボトルネックを可視化し、確実な高速化を実現します。
【処理フロー図】
graph TD A["計測開始"] --> B["Win32 APIで現在のシステム時刻を取得"] B --> C["メイン処理の実行"] C --> D["Win32 APIで終了時のシステム時刻を取得"] D --> E["差分をミリ秒単位で算出"] E --> F["計測結果を出力・ログ記録"]
【実装:VBAコード】
Option Explicit
' --- Win32 API 宣言 ---
' 64bit/32bit両対応のための PtrSafe キーワードを使用
' GetTickCountはシステム起動からの経過時間をミリ秒単位で返します
#If VBA7 Then
Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
#Else
Declare Function GetTickCount Lib "kernel32" () As Long
#End If
''' <summary>
''' パフォーマンス計測のメインルーチン
''' </summary>
Sub MeasurePerformance()
Dim startTime As Long
Dim endTime As Long
Dim totalTime As Double
' 1. 画面更新停止などの高速化設定
Call ToggleOptimization(False)
' 2. 計測開始
startTime = GetTickCount()
' --- [メイン処理:ここから] ---
' 例:大量のデータ処理をシミュレート
Call SampleProcess
' --- [メイン処理:ここまで] ---
' 3. 計測終了
endTime = GetTickCount()
' 4. 高速化設定の解除
Call ToggleOptimization(True)
' 結果の算出(ミリ秒から秒への変換)
totalTime = (endTime - startTime) / 1000
MsgBox "処理が完了しました。" & vbCrLf & _
"実行時間: " & totalTime & " 秒", vbInformation, "計測結果"
End Sub
''' <summary>
''' サンプルの重い処理(配列処理を推奨)
''' </summary>
Private Sub SampleProcess()
Dim i As Long
Dim temp As Double
' 負荷テスト用のループ処理
For i = 1 To 1000000
temp = Sqr(i) ' 平方根計算
Next i
End Sub
''' <summary>
''' Excelの動作最適化設定を切り替える
''' </summary>
''' <param name="enable">Trueで通常状態、Falseで高速化状態</param>
Private Sub ToggleOptimization(enable As Boolean)
With Application
.ScreenUpdating = enable ' 画面更新
.Calculation = IIf(enable, xlCalculationAutomatic, xlCalculationManual) ' 自動計算
.EnableEvents = enable ' イベント抑止
End With
End Sub
【技術解説】
Win32 APIの採用理由: VBA標準の
Timer関数は精度が約1/64秒(約15.6ms)と粗く、高速なループ処理の微細な差を検知できません。GetTickCountを使用することで、1ms単位のより精密な計測が可能になります。PtrSafeと条件付きコンパイル: Officeのビット数(32bit/64bit)を問わず動作させるため、
#If VBA7による条件分岐とPtrSafe宣言を組み合わせています。オーバーヘッドの最小化: 計測対象の前後で
Application.ScreenUpdating等を制御し、VBA以外の要因(描画負荷など)によるノイズを排除しています。
【注意点と運用】
49.7日の壁:
GetTickCountはシステム起動からの経過時間をLong型で返すため、PCを約49.7日間連続稼働させていると値がオーバーフローし、ゼロに戻る性質があります。サーバー等の常時起動環境では注意が必要です。精度の限界: さらに高精度(マイクロ秒単位)が必要な場合は、
QueryPerformanceCounterAPIの検討が必要ですが、通常の業務改善であればGetTickCountで十分なエビデンスが得られます。デバッグ時の挙動: ステップ実行(F8キー)中は計測時間が伸び続けるため、正確な計測を行う際は必ず「実行(F5キー)」で通し確認を行ってください。
【まとめ】
ボトルネックの数値化: 勘に頼らず、API計測による「秒数」で修正箇所の優先順位を決める。
環境の統一: 計測時は他の重いアプリケーションを閉じ、PCの負荷を一定に保つ。
高速化セットの併用: 配列処理と画面更新停止を組み合わせ、APIでその効果を実証する。

コメント