Windows API Importで32bit、64bit Excelをすべて使用するようにPtrSafeを指定
Windows API PtrSafe宣言について学びます。 Excel VBAでコーディングしてみると、Windows APIをImportして使用しているときに遭遇するPtrSafe関連のエラーの原因と解決方法を確認することができる。
1. Windows API PtrSafeエラーの発生例コード
Windows API Sleep、OutputDebugStringをimportして宣言するコードです。
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Private Declare Sub OutputDebugString Lib "kernel32" Alias "OutputDebugStringA" (ByVal lpOutputString As String)
(注:上記のコードは Logging パターン: OutputDebugString , DebugView 活用 – 生産性 Skill (prodskill.com) で紹介したコードです。)
2. Windows API PtrSafeのエラーメッセージ
VBAコードを編集またはコンパイルすると、次のエラーが発生します。
——————————————-
Microsoft Visual Basic for Applications
——————————————-コンパイルエラーです:
このプロジェクトのコードを更新するまで、64ビットシステムで使用できます。 Declareステートメントを確認して更新し、PtrSafe属性としてマークします。
3. Windows API PtrSafeエラーの原因
MS-Office 2010から64bitをサポートしており、これ以降の64bit ExcelでWindows APIをImprtするときにPtrSafeキーワードを指定する必要があるために発生します。
参照: The code in this project must be updated for use on 64-bit systems – Office | Microsoft Docs
上記URLの資料内容の一部を抜粋して下に貼り付ける。
Symptoms
Consider the following scenario:
- You write a Microsoft Visual Basic for Applications (VBA) macro code that uses Declare statements.
- Your VBA macro code uses compilation constants. For example, your macro code uses one the following compilation constants:
- #If VBA7
- #If Win64
- You use an #Else block in a conditional block. In the #Else block, you use syntax for a Declare statement designed to run in Microsoft Visual Basic for Applications 6.0.
- You edit the code in a 64-bit version of a Microsoft Office 2010 program.
- You try to change the Declare statement in the #Else block.
In this scenario, you receive the following error message:
Microsoft Visual Basic for Applications Compile error: The code in this project must be updated for use on 64-bit systems. Please review and update Declare statements and then mark them with the PtrSafe attribute.
4. Windows API PtrSafeエラーの解決方法
MS-Office 2010のVBAバージョンは7.0で、以前は6.xです。 VBA 7.0 から PtrSafe キーワードが必要なので、VBA バージョンが 7.0 以降かどうかによって Windows API import コードを分けて宣言すればよい。
参照: PtrSafeキーワード(VBA)| Microsoft Docs
上記URLの資料内容の一部を抜粋して下に貼り付ける。
PtrSafe キーワード
- Article
- 09/14/2021
- 2 minutes to read
- 5 contributors
The PtrSafe keyword is used in this context: Declare statement.
Declare statements with the PtrSafe keyword is the recommended syntax. Declare statements that include PtrSafe work correctly in the VBA7 development environment on both 32-bit and 64-bit platforms only after all data types in the Declare statement (parameters and return values) that need to store 64-bit quantities are updated to use LongLong for 64-bit integrals or LongPtr for pointers and handles.
To ensure backwards compatibility with VBA version 6 and earlier, use the following construct:
#If VBA7 Then Declare PtrSafe Sub... #Else Declare Sub... #EndIf
When running in 64-bit versions of Office, Declare statements must include the PtrSafe キーワード。 The PtrSafe keyword asserts that a Declare statement is safe to run in 64-bit development environments.
Adding the PtrSafe keyword to a Declare statement only signifies that the Declare statement explicitly targets 64-bits。 All data types within the statement that need to store 64-bits (including return values and parameters) must still be modified to hold 64-bit quantities by using either LongLong for 64-bit integrals or LongPtr for pointers and handles.
「VBA7」定数または「Win64」定数が定義されているかどうかを判断すればよく、このときコンパイラ指示子(Compiler Directive)#If構文を使用する。
コードは次のように構成します。
'방법1 #If VBA7 Then '64bit Windows API import #Else '32bit Windows API import #End If '방법2 #If Win64 Then '64bit Windows API import #Else '32bit Windows API import #End If '방법1, 방법2는 동일한 효과가 있으므로 한 방법을 선택하면 됨
5. Windows API PtrSafeエラー解決の例コード
5.1。 32bit、64bit Excelで混用して使用される場合
#If VBA7 Then 'For 64 Bit Systems Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr) Private Declare PtrSafe Sub OutputDebugString Lib "kernel32" Alias "OutputDebugStringA" (ByVal lpOutputString As String) #Else 'For 32 Bit Systems Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Private Declare Sub OutputDebugString Lib "kernel32" Alias "OutputDebugStringA" (ByVal lpOutputString As String) #End If
5.2。 64bit Excelでのみ使用される場合
64bit Excelでのみ使用されるという保証がある場合は、PtrSafeキーワードを指定した1つの構文のみを使用してください。
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr) Private Declare PtrSafe Sub OutputDebugString Lib "kernel32" Alias "OutputDebugStringA" (ByVal lpOutputString As String)