<p><style_analysis>
キーワード:VBA, Win32 API, GetTickCount, パフォーマンス計測, 高速化, 64bit対応
視点:Excel/Accessの実務における「重い処理」のボトルネックを可視化し、改善を促す技術者・開発者向け。
トーン:論理的、実用的、かつ安全性を重視したプロフェッショナルな解説。
構成:定義、可視化、実装、理論、運用の5段構え。
</style_analysis></p>
<p>本記事は<strong>Geminiの出力をプロンプト工学で整理した業務ドラフト(未検証)</strong>です。</p>
<h1 class="wp-block-heading">VBAでミリ秒単位の処理時間を計測!Win32 APIを用いた高精度パフォーマンス測定</h1>
<h2 class="wp-block-heading">【背景と目的】</h2>
<p>VBA標準のTimer関数では不十分な10ミリ秒単位の実行速度を計測し、マクロのボトルネックを特定して処理の最適化を図ることを目的とします。(68文字)</p>
<h2 class="wp-block-heading">【処理フロー図】</h2>
<div class="wp-block-merpress-mermaidjs diagram-source-mermaid"><pre class="mermaid">
graph TD
A["計測開始"] --> B["Win32 APIで現在時刻取得"]
B --> C["メイン処理実行"]
C --> D["Win32 APIで終了時刻取得"]
D --> E["差分計算/ミリ秒単位"]
E --> F["計測結果を表示"]
</pre></div>
<h2 class="wp-block-heading">【実装:VBAコード】</h2>
<pre data-enlighter-language="generic">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 MeasurePerformance()
Dim startTime As Long
Dim endTime As Long
Dim totalTime As Double
' 1. 高速化のためのExcel設定変更(描画停止・自動計算停止)
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
.EnableEvents = False
End With
On Error GoTo ErrorHandler
' 2. 計測開始
startTime = GetTickCount()
' --- [ここからメイン処理] ---
Dim i As Long
Dim tmpValue As Variant
' 大量ループによる負荷テスト例(配列処理を推奨するが、ここでは負荷をかけるためセル操作)
For i = 1 To 10000
Cells(i, 1).Value = "Test " & i
Next i
' --- [ここまでメイン処理] ---
' 3. 計測終了
endTime = GetTickCount()
' 4. 結果の計算(ミリ秒を秒に変換して表示)
totalTime = (endTime - startTime) / 1000
MsgBox "処理が完了しました。" & vbCrLf & _
"実行時間: " & totalTime & " 秒", vbInformation, "計測結果"
CleanUp:
' 5. 設定を元に戻す
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
.EnableEvents = True
End With
Exit Sub
ErrorHandler:
MsgBox "エラーが発生しました: " & Err.Description, vbCritical
Resume CleanUp
End Sub
</pre>
<h2 class="wp-block-heading">【技術解説】</h2>
<ol class="wp-block-list">
<li><p><strong>GetTickCount APIの採用</strong>:
VBA標準の <code>Timer</code> 関数は1秒未満の精度が低く、環境によって精度が異なります。Win32 APIの <code>GetTickCount</code> を使用することで、OSレベルのミリ秒単位(約10〜16ms間隔)の精度で実行時間を把握できます。</p></li>
<li><p><strong>PtrSafe 宣言</strong>:
現代のOffice環境(64bit版)で動作させるには <code>PtrSafe</code> キーワードが必須です。<code>#If VBA7</code> 定数を使用することで、古いバージョンのExcelとの互換性を保っています。</p></li>
<li><p><strong>環境負荷の制御</strong>:
マクロの真の処理速度を測るには、Excel特有のオーバーヘッド(画面更新やイベント検知)を <code>Application</code> オブジェクトの設定で一時的に停止させることが鉄則です。</p></li>
</ol>
<h2 class="wp-block-heading">【注意点と運用】</h2>
<ul class="wp-block-list">
<li><p><strong>カウントのオーバーフロー</strong>:
<code>GetTickCount</code> はシステム起動から約49.7日が経過すると値が0に戻ります。数日間にわたるような長時間の計測には適していません。その場合は <code>GetTickCount64</code>(Windows Vista以降)の使用を検討してください。</p></li>
<li><p><strong>精度の限界</strong>:
ミリ秒単位で値が返りますが、実際の分解能はシステムタイマーに依存するため、厳密に1ms単位の精度を保証するものではありません。より高精度な計測には <code>QueryPerformanceCounter</code> APIが必要になります。</p></li>
<li><p><strong>エラーハンドリング</strong>:
処理中にエラーで中断した場合でも、<code>ScreenUpdating</code> 等の設定を必ず元に戻すよう <code>Try-Catch</code> 的な構造(<code>On Error GoTo</code>)を構築してください。</p></li>
</ul>
<h2 class="wp-block-heading">【まとめ】</h2>
<ul class="wp-block-list">
<li><p><strong>APIを活用して標準機能の限界(1秒単位)を超えた計測を行う。</strong></p></li>
<li><p><strong>計測時は画面更新停止などの「高速化設定」をセットで行う。</strong></p></li>
<li><p><strong>64bit環境を意識した <code>PtrSafe</code> 宣言により、組織内の多様なPC環境に対応させる。</strong></p></li>
</ul>
キーワード:VBA, Win32 API, GetTickCount, パフォーマンス計測, 高速化, 64bit対応
視点:Excel/Accessの実務における「重い処理」のボトルネックを可視化し、改善を促す技術者・開発者向け。
トーン:論理的、実用的、かつ安全性を重視したプロフェッショナルな解説。
構成:定義、可視化、実装、理論、運用の5段構え。
本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
VBAでミリ秒単位の処理時間を計測!Win32 APIを用いた高精度パフォーマンス測定
【背景と目的】
VBA標準のTimer関数では不十分な10ミリ秒単位の実行速度を計測し、マクロのボトルネックを特定して処理の最適化を図ることを目的とします。(68文字)
【処理フロー図】
graph TD
A["計測開始"] --> B["Win32 APIで現在時刻取得"]
B --> C["メイン処理実行"]
C --> D["Win32 APIで終了時刻取得"]
D --> E["差分計算/ミリ秒単位"]
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 MeasurePerformance()
Dim startTime As Long
Dim endTime As Long
Dim totalTime As Double
' 1. 高速化のためのExcel設定変更(描画停止・自動計算停止)
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
.EnableEvents = False
End With
On Error GoTo ErrorHandler
' 2. 計測開始
startTime = GetTickCount()
' --- [ここからメイン処理] ---
Dim i As Long
Dim tmpValue As Variant
' 大量ループによる負荷テスト例(配列処理を推奨するが、ここでは負荷をかけるためセル操作)
For i = 1 To 10000
Cells(i, 1).Value = "Test " & i
Next i
' --- [ここまでメイン処理] ---
' 3. 計測終了
endTime = GetTickCount()
' 4. 結果の計算(ミリ秒を秒に変換して表示)
totalTime = (endTime - startTime) / 1000
MsgBox "処理が完了しました。" & vbCrLf & _
"実行時間: " & totalTime & " 秒", vbInformation, "計測結果"
CleanUp:
' 5. 設定を元に戻す
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
.EnableEvents = True
End With
Exit Sub
ErrorHandler:
MsgBox "エラーが発生しました: " & Err.Description, vbCritical
Resume CleanUp
End Sub
【技術解説】
GetTickCount APIの採用:
VBA標準の Timer 関数は1秒未満の精度が低く、環境によって精度が異なります。Win32 APIの GetTickCount を使用することで、OSレベルのミリ秒単位(約10〜16ms間隔)の精度で実行時間を把握できます。
PtrSafe 宣言:
現代のOffice環境(64bit版)で動作させるには PtrSafe キーワードが必須です。#If VBA7 定数を使用することで、古いバージョンのExcelとの互換性を保っています。
環境負荷の制御:
マクロの真の処理速度を測るには、Excel特有のオーバーヘッド(画面更新やイベント検知)を Application オブジェクトの設定で一時的に停止させることが鉄則です。
【注意点と運用】
カウントのオーバーフロー:
GetTickCount はシステム起動から約49.7日が経過すると値が0に戻ります。数日間にわたるような長時間の計測には適していません。その場合は GetTickCount64(Windows Vista以降)の使用を検討してください。
精度の限界:
ミリ秒単位で値が返りますが、実際の分解能はシステムタイマーに依存するため、厳密に1ms単位の精度を保証するものではありません。より高精度な計測には QueryPerformanceCounter APIが必要になります。
エラーハンドリング:
処理中にエラーで中断した場合でも、ScreenUpdating 等の設定を必ず元に戻すよう Try-Catch 的な構造(On Error GoTo)を構築してください。
【まとめ】
APIを活用して標準機能の限界(1秒単位)を超えた計測を行う。
計測時は画面更新停止などの「高速化設定」をセットで行う。
64bit環境を意識した PtrSafe 宣言により、組織内の多様なPC環境に対応させる。
ライセンス:本記事のテキスト/コードは特記なき限り
CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。
コメント