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コードを編集またはコンパイルすると、次のエラーが発生します。

VBA 컴파일 오류: Declare 문 PtrSafe 특성 표시 필요
VBAコンパイルエラー:DeclareステートメントPtrSafe属性の表示が必要

——————————————-
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

Compile error when you edit a VBA macro in the 64-bit version of an Office 2010 program
Compile error when you edit a VBA macro in the 64-bit version of an Office 2010 program

上記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

PtrSafe keyword
PtrSafe キーワード

上記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)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

ja日本語