엑셀 & VBA/엑셀 VBA 코딩패턴

Windows API Import시 32bit, 64bit Excel 모두 사용하도록 PtrSafe 지정

ProDA 2022. 2. 20.

이 글은 새로운 블로그로 옮겼습니다. 5초후 자동으로 이동합니다.

▶ 새로운 블로그 주소: https://prodskill.com/

▶ 새로운 글 주소: https://prodskill.com/excel-vba-coding-pattern-windows-api-ptrsafe/

엑셀 VBA로 코딩하다 보면 Windows API를 Import하여 사용하다가 간혹 만나는 PtrSafe 관련 오류의 원인과 해결방법을 정리하여 포스팅한다.


목차

     

    1. 오류 발생 예시 코드

    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)

     

    2. 오류 메시지

    VBA 코드를 편집하거나 컴파일할 때 다음과 같은 오류가 발생한다.

    VBA 컴파일 오류: Declare 문 PtrSafe 특성 표시 필요

    ---------------------------
    Microsoft Visual Basic for Applications
    ---------------------------
    컴파일 오류입니다:

    이 프로젝트의 코드를 업데이트해야 64비트 시스템에서 사용할 수 있습니다. Declare 문을 검토하고 업데이트한 다음 PtrSafe 특성으로 표시하십시오.
    ---------------------------
    확인   도움말   
    ---------------------------

     

    3. 오류 발생 원인

    MS-Office 2010부터 64bit를 지원했고, 이 이후의 64bit 엑셀에서 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

     

    4. 오류 해결 방법

    MS-Office 2010의 VBA 버전이 7.0이고, 그 이전은 6.x 이다. VBA 7.0 부터 PtrSafe 키워드가 필요하기 때문에, VBA 버전이 7.0 이후인지 아닌지에 따라 Windows API import 코드를 나누어서 선언하면 된다.

    참조: PtrSafe keyword (VBA) | Microsoft Docs

    PtrSafe keyword
    PtrSafe keyword

    "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. 오류 해결 예시 코드

    5.1. 32bit, 64bit 엑셀에서 혼용하여 사용되는 경우

    #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 엑셀에서만 사용되는 경우

    64bit 엑셀에서만 사용된다는 보장이 있다면 PtrSafe 키워드를 지정한 하나의 구문만 사용한다.

    Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
    Private Declare PtrSafe Sub OutputDebugString Lib "kernel32" Alias "OutputDebugStringA" (ByVal lpOutputString As String)

     

    댓글

    💲 추천 글