VBA Project Conversion to 64-Bit

Synopsis

This document describes the steps to convert a typical VBA project from 32-bit to 64-bit. This document is a work in progress and is derived from experience in Excel VBA projects, but should be applicable to Access, etc.

Applicable Cases

For the most part, written VBA in 32-bit is identical to 64-bit. There are a few cases where this is not true, and I will describe how to remediate them here. But first, learn about the conditional compilation statements.

Conditional Compilation Statements & Variables

The #if directive allows you to optionally compile code depending on compilation variables. We’ll focus on these two compilation variables:

  1. VBA7: Office 2010 (32 & 64-bit) rolled out a new VBA codebase; this variable is true if you’re coding in Office 2010 or later
  2. Win64: True if you are running 64-bit Office, False otherwise

Here are a few usage examples, to change which code is compiled depending on which version / bitness of Office you are using:

#if Win64 then

Declare PtrSafe Function MyMathFunc Lib “User32” (ByVal N As LongLong) As LongLong

#else

Declare Function MyMathFunc Lib “User32” (ByVal N As Long) As Long

#end if

 

#if VBA7 then

Declare PtrSafe Sub MessageBeep Lib “User32” (ByVal N AS Long)

#else

Declare Sub MessageBeep Lib “User32” (ByVal N AS Long)

#end if

 

You can read here for more information:

https://msdn.microsoft.com/en-us/library/office/ee691831(v=office.14).aspx

Case 1: Function Declarations

Functions must be declared using the PtrSafe attribute. For example:

Declare Function MyMathFunc Lib “User32” (ByVal N As Long) As Long

 

Must be declared as:

Declare PtrSafe Function MyMathFunc Lib “User32” (ByVal N As LongLong) As LongLong

You should use the #if Win64 Then… conditional compilation statements for any function declarations to allow your code to run in 32-bit and 64-bit Office.

Case 2: LongLong Datatype / Different Library Return Types

Some of the functions you may have used return a different datatype! For example, the ADODB.RecordSet.RecordCount method returns LongLong (64-bit long).

Here’s an example of how to write the function for 32-64 bit compatibility:

#If Win64 Then

Private Function GetNumRecords(RS As ADODB.Recordset) As LongLong

#Else

Private Function GetNumRecords(RS As ADODB.Recordset) As Long

#End If

GetNumRecords = RS.RecordCount

End Function

Case 3: LongPtr (A TRUE Pointer Type)

Some functions will require changing their arguments

#If VBA7 Then

Private Declare PtrSafe Function CallNextHookEx Lib “user32” (ByVal hHook As LongPtr, _

ByVal ncode As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr

#else

Private Declare Function CallNextHookEx Lib “user32” (ByVal hHook As Long, _

ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long

#end if

 

Conversion Methodology

From 64-bit Office: Debug -> Compile VBA Project, fix errors, repeat until everything works. However it may be easier to search for your Declare statements and fix all those at once. You still need to compile because that’s the fastest way to determine if a return or argument type has changed to LongLong or LongPtr.

Test that the automation still works in 32-bit Office, and do a final test of functionality to make sure everything works the same.e

Leave a comment