Win32 API 64ビット完全対応:PtrSafeとLongPtrによるVBAの堅牢化
【背景と目的】
32bitから64bit版Excel移行時に発生するAPIコンパイルエラーを解消し、動作速度の計測やシステム制御を安全かつ高速に実現します。
【処理フロー図】
graph TD
A["VBAマクロ開始"] --> B{"VBAバージョン/ビット数判定"}
B -->|VBA7 以上| C["PtrSafe属性を付与して宣言"]
B -->|VBA6 以前| D["従来のDeclare文で宣言"]
C --> E{"データ型の選択"}
E -->|ポインタ・ハンドル| F["LongPtr を使用"]
E -->|32bit整数値| G["Long を使用"]
F --> H["API関数の実行"]
G --> H["API関数の実行"]
H --> I["終了"]
【実装:VBAコード】
以下のコードは、システムのミリ秒単位の稼働時間を取得する GetTickCount 関数を例に、32/64ビット両対応の宣言と、画面更新停止による高速化を組み込んだ実装例です。
Option Explicit
' --- [Win32 API 宣言セクション] ---
' VBA7(Office 2010以降)の場合は PtrSafe を付与
#If VBA7 Then
' 64bit環境でも安全に呼び出せる宣言
Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
' ポインタやハンドルを扱う場合は LongPtr を使用する(この例は戻り値がLongのためLongでOK)
#Else
' 旧バージョン(32bit)用の宣言
Private Declare Function GetTickCount Lib "kernel32" () As Long
#End If
'''
''' 処理時間を正確に計測し、高速に処理を実行するサンプル
'''
Public Sub HighSpeedProcessExample()
Dim startTime As Long
Dim endTime As Long
Dim i As Long
Dim targetSheet As Worksheet
' 1. 高速化設定:画面更新とイベント発生を停止
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
.EnableEvents = False
End With
On Error GoTo ErrorHandler
' 2. APIを使用して開始時間を取得
startTime = GetTickCount()
' 3. メイン処理(例:大量のデータ書き込み)
Set targetSheet = ThisWorkbook.ActiveSheet
For i = 1 To 10000
targetSheet.Cells(i, 1).Value = "Data_" & i
Next i
' 4. APIを使用して終了時間を取得
endTime = GetTickCount()
' 5. 結果表示(ミリ秒を秒に変換)
MsgBox "処理が完了しました。" & vbCrLf & _
"実行時間: " & (endTime - startTime) / 1000 & " 秒", vbInformation
CleanUp:
' 6. 設定を元に戻す(必ず実行されるようにする)
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
.EnableEvents = True
End With
Exit Sub
ErrorHandler:
MsgBox "エラーが発生しました: " & Err.Description, vbCritical
Resume CleanUp
End Sub
【技術解説】
VBA7 コンパイラ定数:
#If VBA7を使用することで、Office 2010以降(32/64bit問わず)とそれ以前のバージョンを分岐させます。PtrSafe キーワード: 64bit版OfficeではAPI宣言にこのキーワードが必須です。「この宣言は64bit環境で動作することを確認済みである」とコンパイラに伝える役割を持ちます。
LongPtr 型: 実行環境に応じて「32bit環境では4バイト、64bit環境では8バイト」に自動的にサイズが調整される型です。ウィンドウハンドル(HWND)やメモリポインタを扱う変数は、必ず
LongではなくLongPtrで宣言する必要があります。Long 型の維持: APIの引数が「32ビット整数」として定義されている場合(今回の
GetTickCountの戻り値など)は、64bit環境であってもLongのままにするのが正解です。
【注意点と運用】
型の取り違え: すべてを
LongPtrにすれば良いわけではありません。APIの仕様書(MSDN等)を確認し、それが「アドレス/ハンドル(LongPtr)」なのか「数値(Long)」なのかを見極める必要があります。強制終了のリスク: APIの宣言ミス(引数の数や型の不一致)は、通常のVBAエラーにならずExcel自体が即座にクラッシュ(強制終了)する原因となります。保存していないデータは失われるため、実行前の保存は必須です。
条件付きコンパイルの徹底: 開発環境が64bitであっても、配布先のユーザーが32bit版を使用しているケースは多々あります。必ず
#If VBA7による分岐を記述してください。
【まとめ】
VBA7以降は
PtrSafeを宣言に必須付与する。ハンドルやポインタには
LongPtrを、純粋な数値にはLongを使い分ける。API実行時は必ず
On Error処理とApplication状態の復元処理をセットで実装する。
この記事の更新履歴
この記事は、生成AIを活用した自動レビュー・更新フローにより内容を見直し、必要な修正を反映しています。
2026年9月20日
- 削除冒頭のGeminiの出力をプロンプト工学で整理した旨の未検証ドラフト表記を除去しました。

