32-bit vs. 64-bit: Fixing “The code in this project must be updated for use on 64-bit systems.”

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 PtrSafe keyword immediately after Declare in all Windows API declarations. Then, update any argument or return value representing a memory address or window handle (HWND, HDC, LPARAM) from Long to LongPtr. 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 Long integer 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 Long variable 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

  • VBA7 Constant: Evaluates to True if you are running Office 2010 or newer. It confirms the compiler recognizes the PtrSafe and LongPtr keywords.
  • Win64 Constant: Evaluates to True only if the host Office program is actually 64-bit.
  • LongPtr: A dynamic type. On 64-bit Office, LongPtr compiles as a 64-bit LongLong. On 32-bit Office, LongPtr compiles as a standard 32-bit Long.

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 TypePurpose32-Bit Type64-Bit (VBA7) Type
Window Handles (hwnd, hdc, hProcess)Pointer to an OS objectLongLongPtr
Memory Addresses (lpString, lpvBuffer)Pointer to memory locationLongLongPtr
Message Parameters (wParam, lParam)Pointers or pointer-sized integersLongLongPtr
Counters / Durations (dwMilliseconds)Numeric valueLongLong
Dimensions / Flags (nWidth, dwFlags)Fixed numeric valueLongLong

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: