本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
【VBA】64bit版Excelで発生するWin32 APIコンパイルエラーを解決するPtrSafe・LongPtr移行ガイド
【背景と目的】
Excelの64bit化に伴い、従来のWin32 API宣言でコンパイルエラーが発生します。本稿ではPtrSafeとLongPtrを用いた安全な64bit対応手順を解説します。
【処理フロー図】
graph TD
A["VBA処理開始"] --> B{"VBA7環境判定"}
B -->|VBA7 64bit/32bit| C["PtrSafe宣言・LongPtr型を使用"]
B -->|旧VBA6| D["従来のDeclare宣言を使用"]
C --> E["画面描画停止等の高速化適用"]
D --> E
E --> F["API呼び出しと一括配列処理"]
F --> G["設定の復元と終了"]
※上記フローは、32bit/64bit双方のOffice環境で安全にWin32 API(アクティブウィンドウのポインタ取得等)を呼び出すための分岐と処理手順を示しています。
【実装:VBAコード】
Option Explicit
' --- Win32 APIの宣言 (64bit/32bit環境の互換性確保) ---
#If VBA7 Then
' Office 2010以降(VBA7)環境用:PtrSafeキーワードとLongPtr型を使用
Private Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr
Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
#Else
' 旧Office(VBA6以前)環境用
Private Declare Function GetActiveWindow Lib "user32" () As Long
Private Declare Function GetTickCount Lib "kernel32" () As Long
#End If
' メイン処理マクロ
Public Sub ExecuteWin32ApiSample()
' 高速化設定のための状態退避変数
Dim originalScreenUpdating As Boolean
Dim originalCalculation As XlCalculation
' 現在の設定を保存
originalScreenUpdating = Application.ScreenUpdating
originalCalculation = Application.Calculation
On Error GoTo ErrorHandler
' 高速化処理:画面更新と自動計算を一時停止
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
' API呼び出し:メモリポインタやハンドルを扱うため LongPtr 型を使用
Dim hwnd As LongPtr
hwnd = GetActiveWindow()
' API呼び出し:時間の計測開始
Dim startTime As Long
Dim endTime As Long
startTime = GetTickCount()
' 配列を用いた高速データ処理の実装(1万件のデータ生成)
Dim dataArray(1 To 10000, 1 To 1) As Variant
Dim i As Long
For i = 1 To 10000
dataArray(i, 1) = "データ項目_" & i
Next i
' セルへの一括書き込み(高速化)
ThisWorkbook.Sheets(1).Range("A1:A10000").Value = dataArray
' 時間の計測終了
endTime = GetTickCount()
' 処理結果のメッセージ表示(ポインタ情報と実行時間)
MsgBox "ウィンドウハンドル (LongPtr): " & CStr(hwnd) & vbCrLf & _
"処理時間: " & CStr(endTime - startTime) & " ms", vbInformation, "処理完了"
CleanExit:
' 必ず元の設定に復元(例外発生時も含む)
Application.Calculation = originalCalculation
Application.ScreenUpdating = originalScreenUpdating
Exit Sub
ErrorHandler:
MsgBox "エラーが発生しました: " & Err.Description, vbCritical, "処理エラー"
Resume CleanExit
End Sub
【技術解説】
PtrSafeキーワード: 64bit環境のVBA7において、API関数が安全に実行可能であることをコンパイラに伝える宣言文言です。これを付与しない場合、「コンパイルエラー: Declareステートメントに、PtrSafe属性を設定してください」が発生します。LongPtr型の採用: 実行環境(32bit / 64bit)に応じて自動的にデータ型サイズが変化する特殊な型です。32bit環境では32bit(4バイト)、64bit環境では64bit(8バイト)の長整数として動作し、メモリポインタやウィンドウハンドル(HWND等)を安全に保持できます。条件付きコンパイル (
#If VBA7): 旧バージョンのVBA環境(VBA6以下)との後方互換性を維持しつつ、最新のVBA7仕様を記述するための構文です。処理高速化の考慮: 大量データを取り扱う際は、
ScreenUpdating = Falseによる描画停止と、セルへ直接繰り返し書き込まずメモリ上の配列に代入してから一括転記する手法を組み合わせてパフォーマンスを最大化しています。
【注意点と運用】
数値の引数とポインタの混同に注意: すべての
Long型をLongPtrに変更してはいけません。ポインタやハンドルを表す引数のみをLongPtrに変更し、単なる数値(サイズやフラグなど)はLong型のまま維持する必要があります。誤って変更するとメモリリークや強制終了(クラッシュ)を引き起こします。データ型
LongLongの制限: 64bit整数のLongLong型は64bit版Officeでのみ利用可能です。32bit環境とコードを共有する場合は直接使用せず、原則としてLongPtrを使用してください。
【まとめ】
API宣言には必ず
PtrSafeを付与し、ポインタ系変数にはLongPtr型を使用する。#If VBA7を活用し、旧環境でもエラーにならない互換コードを記述する。API呼び出し処理前後では描画停止と配列一括処理を併用し、高速化を維持する。

