When opening older Excel macros in modern installations of Microsoft 365 or Office 64-bit, you may encounter the 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.”
How Do You Fix the 64-bit Declare Statement Compile Error in Excel VBA?
To fix this error, add the
PtrSafekeyword immediately afterDeclarein all Windows API declarations. Then, update any argument or return value representing a memory address or window handle (HWND,HDC,LPARAM) fromLongtoLongPtr. Use conditional compilation (#If VBA7 Then) to ensure backwards compatibility with 32-bit Excel.
The First-Line Solution
Locate the broken line in your module declarations (highlighted in red or marked during compilation).
' OLD 32-BIT DECLARATION (Fails in 64-bit Excel):
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
' COMPATIBLE 64-BIT DECLARATION (Safe in VBA7):
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
In this example, dwMilliseconds is a standard duration value, not a memory address, so only the PtrSafe keyword was required. When parameters represent pointers or handles, additional type changes are required.
Why the Architecture Mismatch Happens
The issue is determined by the bitness of your Microsoft Office installation, not your Windows operating system. A 64-bit Windows installation can run either 32-bit Office or 64-bit Office.
In 32-bit Office:
- Memory pointers and system handles are 32 bits (4 bytes) wide.
- VBA stored these pointers inside the 32-bit
Longinteger data type.
In 64-bit Office:
- Memory pointers and system handles are 64 bits (8 bytes) wide.
- Attempting to pass an 8-byte pointer into a 4-byte
Longvariable truncates the address, corrupting memory and causing Excel to crash instantly.
To protect system stability, the 64-bit VBA compiler intentionally blocks execution on any legacy Declare statement until you explicitly affirm it is safe by adding PtrSafe and verifying pointer data types.
Step-by-Step Conversion: The Universal Dual-Architecture Template
If your workbook will be used across different computers running both 32-bit and 64-bit versions of Office, wrap your API calls in conditional compilation blocks using the #If VBA7 compiler directive:
#If VBA7 Then
' Code runs in Office 2010 and newer (both 32-bit and 64-bit)
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As LongPtr
#Else
' Legacy fallback for Office 2007 and earlier
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
#End If
Understanding the Directives
VBA7Constant: Evaluates toTrueif you are running Office 2010 or newer. It confirms the compiler recognizes thePtrSafeandLongPtrkeywords.Win64Constant: Evaluates toTrueonly if the host Office program is actually 64-bit.LongPtr: A dynamic type. On 64-bit Office,LongPtrcompiles as a 64-bitLongLong. On 32-bit Office,LongPtrcompiles as a standard 32-bitLong.
When to Use LongPtr vs. Long
A common mistake is converting every Long in an API declaration to LongPtr. Do not do this. Converting non-pointer integers to 64 bits will pass invalid parameters to Windows functions.
Use this decision table:
| Parameter or Return Type | Purpose | 32-Bit Type | 64-Bit (VBA7) Type |
|---|---|---|---|
Window Handles (hwnd, hdc, hProcess) | Pointer to an OS object | Long | LongPtr |
Memory Addresses (lpString, lpvBuffer) | Pointer to memory location | Long | LongPtr |
Message Parameters (wParam, lParam) | Pointers or pointer-sized integers | Long | LongPtr |
Counters / Durations (dwMilliseconds) | Numeric value | Long | Long |
Dimensions / Flags (nWidth, dwFlags) | Fixed numeric value | Long | Long |
For a complete breakdown of pointers and handles across common Win32 functions, refer directly to Using PtrSafe and LongPtr for Windows API declarations..
Distinguishing API Compile Breaks from Common Runtime Bugs
After adding PtrSafe, your project may compile but fail during runtime execution. Do not confuse 64-bit API upgrades with logic bugs:
- If a calculation inside your code exceeds 2,147,483,647, it triggers Runtime Error 6: Overflow (Variable value exceeds the Integer limit—use Long)..
- If your macro crashes on Mac computers after the update, Windows API calls cannot run under macOS. Review Troubleshooting Mac vs. Windows VBA compatibility (ActiveX vs. AppleScript)..
- For broader architectural, security, and library mismatches, consult the VBA Environment & System Guide: Fixing Security, Version, and Compatibility Errors.