結論から記述する(PREP法)
専門用語は平易に解説するか、文脈で補完する
コードブロックは「実務での再利用性」を最優先する
曖昧な表現を避け、具体的な数値や型を提示する
本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
VBA高速化の鍵:Win32 APIを用いたミリ秒単位の処理時間計測
【背景と目的】
VBAのボトルネック特定には、標準のTimer関数では精度が不足します。APIを活用し、ミリ秒単位で正確な実行時間を可視化・最適化します。(63文字)
【処理フロー図】
graph TD A["計測開始:GetTickCount取得"] --> B["画面更新・自動計算の停止"] B --> C["メイン処理:配列を用いたデータ加工等"] C --> D["画面更新・自動計算の再開"] D --> E["計測終了:GetTickCount取得"] E --> F["差分計算:ミリ秒単位で結果表示"]
【実装:VBAコード】
Option Explicit
' --- Win32 API 宣言 (64bit/32bit 両対応) ---
#If VBA7 Then
' システム起動後の経過時間をミリ秒単位で取得
Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
#Else
Private Declare Function GetTickCount Lib "kernel32" () As Long
#End If
''' <summary>
''' 高速処理と精密な時間計測を両立したサンプルマクロ
''' </summary>
Public Sub MeasureProcessingTime()
Dim startTime As Long
Dim endTime As Long
Dim processTime As Double
' 1. 計測開始
startTime = GetTickCount()
' 2. 高速化設定(お約束の最適化)
With Application
.ScreenUpdating = False ' 画面更新停止
.Calculation = xlCalculationManual ' 自動計算停止
.EnableEvents = False ' イベント抑止
End With
On Error GoTo ErrorHandler
' 3. メイン処理(例:大量のセル転記を配列で高速化)
Dim dataArray() As Variant
Dim i As Long
Const MAX_ROW As Long = 100000
ReDim dataArray(1 To MAX_ROW, 1 To 1)
For i = 1 To MAX_ROW
dataArray(i, 1) = "Sample_" & i
Next i
' セルへの一括書き出し
ActiveSheet.Range("A1").Resize(MAX_ROW, 1).Value = dataArray
' 4. 計測終了
endTime = GetTickCount()
' 5. 後処理(設定の復元)
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
.EnableEvents = True
End With
' 実行時間の算出 (ミリ秒 -> 秒)
processTime = (endTime - startTime) / 1000
MsgBox "処理が完了しました。" & vbCrLf & _
"実行時間: " & Format(processTime, "0.000") & " 秒", vbInformation, "計測結果"
Exit Sub
ErrorHandler:
' エラー時も必ず設定を戻す
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
.EnableEvents = True
End With
MsgBox "エラーが発生しました: " & Err.Description, vbCritical
End Sub
【技術解説】
GetTickCountの活用: 標準の
Timer関数は「午前0時からの経過秒数」を返すため、日付をまたぐ処理や、1秒未満の精密な計測(分解能 約15.6ms)には不向きです。APIを使用することでミリ秒単位の精度が得られます。PtrSafe 宣言: 64bit版Officeでは API 宣言に
PtrSafeが必須です。条件付きコンパイル(#If VBA7)を用いることで、旧環境との互換性を維持しています。配列処理による高速化:
Rangeオブジェクトへの個別アクセスは非常に低速です。メモリ上の配列(Variant型)で一括処理してからセルに書き戻すことで、API計測の恩恵を感じるレベルの高速化が実現します。
【注意点と運用】
49.7日の壁:
GetTickCountは戻り値が32ビット符号付き整数(Long)の範囲を扱うため、PCを起動し続けて約49.7日が経過すると、カウントがリセット(オーバーフロー)されます。サーバー稼働環境では注意が必要です。フロー制御の徹底:
ScreenUpdatingなどを停止した場合、エラー発生時にTrueに戻さないと、Excelがフリーズしたように見えます。必ずOn Error GoToで復旧処理を記述してください。高精度が必要な場合: さらに高い精度(マイクロ秒単位)が必要な場合は、
QueryPerformanceCounterAPIの使用を検討してください。
【まとめ】
ミリ秒計測は Win32 API (
GetTickCount) を使い、ボトルネックを正しく把握する。計測の前提条件として、画面更新停止や配列処理などの高速化手法を併用する。
例外処理を組み込み、万が一の際もExcelの設定(画面更新等)を確実に復旧させる。


コメント