Microsoft has changed their guidance to state that from September 2018 on, they recommend the 64 bit version of Office be installed. This is a departure from the 32bit guidance Microsoft provided previously. After Microsoft first compiled a 64 bit version of MS Office in June 2010, they immediately told consumers and companies not to use it.
Starting with Office 2019, Microsoft changed the default installation version from 32-bit to 64-bit. So Microsoft recommends using the 64-bit version. The only reason to use the 32-bit version (besides if you have 32-bit Windows of course) is if you have some add-in, control, code, or reference that uses 32-bit. Download Microsoft Office Professional Plus 2010 (64-bit) for Windows to track, report, and share vital information to reduce costs and increase productivity with improved communication.
Microsoft Visual Basic for Applications (VBA) is the version of Visual Basic that ships with Microsoft Office. In Microsoft Office 2010, VBA includes language features that enable VBA code to run correctly in both 32-bit and 64-bit environments.
From the top of the page, select Services and subscriptions and on that page find the Office product you want to install and select Install. To install Office in a different language, or to install the 64-bit version, select the link Other options. Choose the language and bit version you want, and then select Install. Microsoft does provide 32-bit and 64-bit versions of the following components for Office 2010. You can install the 64-bit versions of these components to work with the 64-bit version of Office 2010. Microsoft Access Database Engine 2010 Microsoft Access Runtime 2010.
Note
By default, Office 2010, 2013 and 2016 install the 32-bit version. You must explicitly choose to install the 64-bit version during setup. Starting with Office 2019 and Microsoft 365, the default is the 64-bit version.
Running VBA code that was written before the Office 2010 release (VBA version 6 and earlier) on a 64-bit platform can result in errors if the code is not modified to run in 64-bit versions of Office. Errors will result because VBA version 6 and earlier implicitly targets 32-bit platforms, and typically contains Declare statements that call into the Windows API by using 32-bit data types for pointers and handles. Because VBA version 6 and earlier does not have a specific data type for pointers or handles, it uses the Long data type, which is a 32-bit 4-byte data type, to reference pointers and handles. Pointers and handles in 64-bit environments are 8-byte 64-bit quantities. These 64-bit quantities cannot be held in 32-bit data types.
Note
You only need to modify VBA code if it runs in the 64-bit version of Microsoft Office.
The problem with running legacy VBA code in 64-bit Office is that trying to load 64-bits into a 32-bit data type truncates the 64-bit quantity. This can result in memory overruns, unexpected results in your code, and possible application failure.
To address this problem and enable VBA code to work correctly in both 32-bit and 64-bit environments, several language features have been added to VBA. The table at the bottom of this document summarizes the new VBA language features. Three important additions are the LongPtr type alias, the LongLong data type, and the PtrSafe keyword.
LongPtr. VBA now includes the variable type alias LongPtr. The actual data type that LongPtr resolves to depends on the version of Office that it is running in; LongPtr resolves to Long in 32-bit versions of Office, and LongPtr resolves to LongLong in 64-bit versions of Office. Use LongPtr for pointers and handles.
LongLong. The LongLong data type is a signed 64-bit integer that is only available on 64-bit versions of Office. Use LongLong for 64-bit integrals. Conversion functions must be used to explicitly assign LongLong (including LongPtr on 64-bit platforms) to smaller integral types. Implicit conversions of LongLong to smaller integrals are not allowed.
PtrSafe. The PtrSafe keyword asserts that a Declare statement is safe to run in 64-bit versions of Office.
Important
All Declare statements must now include the PtrSafe keyword when running in 64-bit versions of Office. It is important to understand that simply 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.
Note
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.
To ensure backwards compatibility in VBA7 and earlier use the following construct:
Consider the following Declare statement examples. Running the unmodified Declare statement in 64-bit versions of Office will result in an error indicating that the Declare statement does not include the PtrSafe qualifier. The modified VBA example contains the PtrSafe qualifier, but notice that the return value (a pointer to the active window) returns a Long data type. On 64-bit Office, this is incorrect because the pointer needs to be 64-bits. The PtrSafe qualifier tells the compiler that the Declare statement is targeting 64-bits, so the statement executes without error. But because the return value has not been updated to a 64-bit data type, the return value is truncated, resulting in an incorrect value returned.
Following is an unmodified legacy VBA Declare statement example:
The following VBA Declare statement example is modified to include the PtrSafe qualifier but still use a 32-bit return value:
To reiterate, you must modify the Declare statement to include the PtrSafe qualifier, and you must update any variables within the statement that need to hold 64-bit quantities so that the variables use 64-bit data types.
Following is a VBA Declare statement example that is modified to include the PtrSafe keyword and is updated to use the proper 64-bit (LongPtr) data type:
In summary, for code to work in 64-bit versions of Office, you need to locate and modify all existing Declare statements to use the PtrSafe qualifier. You also need to locate and modify all data types within these Declare statements that reference handles or pointers to use the new 64-bit compatible LongPtr type alias, and types that need to hold 64-bit integrals with the new LongLong data type. Additionally, you must update any user defined types (UDTs) that contain pointers or handles and 64-bit integrals to use 64-bit data types, and verify that all variable assignments are correct to prevent type mismatch errors.
Writing code that works on both 32-bit and 64-bit Office
To write code that can port between both 32-bit and 64-bit versions of Office, you only need to use the new LongPtr type alias instead of Long or LongLong for all pointers and handle values. The LongPtr type alias will resolve to the correct Long or LongLong data type depending on which version of Office is running.
Note that if you require different logic to execute, for example, you need to manipulate 64-bit values in large Excel projects, you can use the Win64 conditional compilation constant as shown in the following section.
Writing code that works on both Office 2010 (32-bit or 64-bit) and previous versions of Office
To write code that can work in both new and older versions of Office, you can use a combination of the new VBA7 and Win64 conditional Compiler constants. The Vba7 conditional compiler constant is used to determine if code is running in version 7 of the VB editor (the VBA version that ships in Office 2010). The Win64 conditional compiler constant is used to determine which version (32-bit or 64-bit) of Office is running.
Summary of VBA7 language updates
The following table summarizes the new VBA language additions and provides an explanation of each.
Name | Type | Description |
---|---|---|
PtrSafe | Keyword | Asserts that a Declare statement is targeted for 64-bit systems. Required on 64-bits. |
LongPtr | Data type | Type alias that maps to Long on 32-bit systems, or LongLong on 64-bit systems. |
LongLong | Data type | 8-byte data type that is only available on 64-bit systems. Numeric type. Integer numbers in the range of -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807. LongLong is a valid declared type only on 64-bit platforms. Additionally, LongLong may not be implicitly converted to a smaller type (for example, you can't assign a LongLong to a Long). This is done to prevent inadvertent pointer truncation. Explicit coercions are allowed, so in the previous example, you could apply CLng to a LongLong and assign the result to a Long (valid on 64-bit platforms only). |
^ | LongLong type-declaration character | Explicitly declares a literal value as a LongLong. Required to declare a LongLong literal that is larger than the maximum Long value (otherwise it will get implicitly converted to double). |
CLngPtr | type conversion function | Converts a simple expression to a LongPtr. |
CLngLng | type conversion function | Converts a simple expression to a LongLong data type (valid on 64-bit platforms only). |
vbLongLong | VarType constant | LongLong integer (valid on 64-bit platforms only). |
DefLngPtr | DefType statement | Sets the default data type for a range of variables as LongPtr. |
DefLngLng | DefType statement | Sets the default data type for a range of variables as LongLong. |
See also
Support and feedback
Have questions or feedback about Office VBA or this documentation? Please see Office VBA support and feedback for guidance about the ways you can receive support and provide feedback.
-->Find out how the 32-bit version of Office is compatible with the 64-bit version of Office.
Office applications are available in 32-bit and 64-bit versions.
The 64-bit versions of Office enable you to move more data around for increased capability, for example when you work with large numbers in Microsoft Excel 2010. When writing 32-bit code, you can use the 64-bit version of Office without any changes. However, when you write 64-bit code, you should ensure that your code contains specific keywords and conditional compilation constants to ensure that the code is backward compatible with earlier version of Office, and that the correct code is being executed if you mix 32-bit and 64-bit code.
Visual Basic for Applications 7.0 (VBA 7) is released in the 64-bit versions for Office, and it works with both 32-bit and 64-bit applications. The changes described in this article apply only to the 64-bit versions of Office. Using the 32-bit versions of Microsoft Office enable you to use solutions built in previous versions of Office without further modifications.
Note
By default, when you install a 64-bit version of Office, you also install the 32-bit version is installed along with the 64-bit system. You must explicitly select the Microsoft Office 64-bit version installation option.
In VBA 7, you must update existing Windows API statements (Declare statements) to work with the 64-bit version. Additionally, you must update address pointers and display window handles in user-defined types that are used by these statements. This is discussed in more detail in this article as well as compatibility issues between the 32-bit and 64-bit versions and suggested solutions.
Comparing 32-bit and 64-bit systems
Applications built with the 64-bit versions of Office can reference larger address spaces than 32-bit versions. This means you can use more physical memory for data than before, potentially reducing the overhead spent moving data in and out of physical memory
In addition to referring specific locations (known as pointers) in physical memory, you can also use addresses to reference display window identifiers (known as handles). The size (in bytes) of the pointer or handle depends on whether you're using a 32-bit or 64-bit system.
If you want to run your existing solutions with the 64-bit versions of Office, be aware of the following:
Native 64-bit processes in Office cannot load 32-bit binaries. This is expected to be a common issue when you have existing Microsoft ActiveX controls and existing add-ins.
VBA previously didn't have a pointer data type, so you had to use 32-bit variables to store pointers and handles. These variables now truncate 64-bit values returned by API calls when using Declare statements.
VBA 7 code base
VBA 7 replaces the VBA code base in Office 2007 and earlier versions. VBA 7 is available in both the 32-bit and 64-bit versions of Office. It provides two conditional compilation constants:
VBA7 - Helps ensure the backward compatibility of your code by testing whether your application is using VBA 7 or the previous version of VBA.
Win64 Tests whether code is running as 32-bit or 64-bit.
With certain exceptions, the macros in a document that work in the 32-bit version of the application also work in the 64-bit version.
ActiveX control and COM add-in compatibility
Existing 32-bit ActiveX controls, are not compatible with the 64-bit versions of Office. For ActiveX controls and COM objects:
- If you have the source code, generate a 64-bit version yourself.
- If you don't have the source code, contact the vendor for an updated version.
Native 64-bit processes in Office cannot load 32-bit binaries. This includes the common controls of MSComCtl (TabStrip, Toolbar, StatusBar, ProgressBar, TreeView, ListViews, ImageList, Slider, ImageComboBox) and the controls of MSComCt2 (Animation, UpDown, MonthView, DateTimePicker, FlatScrollBar). These controls were installed by 32-bit versions of Office earlier than Office 2010. You'll need to find an alternative for your existing VBA solutions that use these controls when you migrate the code to the 64-bit versions of Office.
API compatibility
The combination of VBA and type libraries gives you lots of functionality to create Office applications. However, sometimes you must communicate directly with the computer's operating system and other components, such as when you manage memory or processes, when working with UI elements linke windows and controls, or when modifying the Windows registry. In these scenarios, your best option is to use one of the external functions that are embedded in DLL files. You do this in VBA by making API calls using Declare statements.
Note
Microsoft provides a Win32API.txt file that contains 1,500 Declare statements and a tool to copy the Declare statement that you want into your code. However, these statements are for 32-bit systems and must be converted to 64-bit by using the information discussed later in this article. Existing Declare statements won't compile in 64-bit VBA until they've been marked as safe for 64-bit by using the PtrSafe attribute. You can find examples of this type of conversion at Excel MVP Jan Karel Pieterse's website at https://www.jkp-ads.com/articles/apideclarations.asp.The Office Code Compatibility Inspector user's guide is a useful tool to inspect the syntax of API Declare statements for the PtrSafe attribute, if needed, and the appropriate return type.
Declare statements resemble one of the following, depending on whether you are calling a subroutine (which has no return value) or a function (which does have a return value).
The SubName function or FunctionName function is replaced by the actual name of the procedure in the DLL file and represents the name that is used when the procedure is called from VBA code. You can also specify an AliasName argument for the name of the procedure. The name of the DLL file that contains the procedure being called follows the Lib keyword. And finally, the argument list contains the parameters and the data types that must be passed to the procedure.
The following Declare statement opens a subkey in the Windows registry and replaces its value.
The Windows.h (window handle) entry for the RegOpenKeyA function is as follows:
In Visual C and Microsoft Visual C++, the previous example compiles correctly for both 32-bit and 64-bit. This is because HKEY is defined as a pointer, whose size reflects the memory size of the platform that the code is compiled in.
In previous versions of VBA, there was no specific pointer data type so the Long data type was used. And because the Long data type is always 32-bits, this breaks when used on a system with 64-bit memory because the upper 32-bits might be truncated or might overwrite other memory addresses. Either of these situations can result in unpredictable behavior or system crashes.
To resolve this, VBA includes a true pointer data type: LongPtr. This new data type enables you to write the original Declare statement correctly as:
This data type and the new PtrSafe attribute enable you to use this Declare statement on either 32-bit or 64-bit systems. The PtrSafe attribute indicates to the VBA compiler that the Declare statement is targeted for the 64-bit version of Office. Without this attribute, using the Declare statement in a 64-bit system will result in a compile-time error. The PtrSafe attribute is optional on the 32-bit version of Office. This enables existing Declare statements to work as they always have.
The following table provides more information about the new qualifier and data typeas well as another data type, two conversion operators, and three functions.
Type | Item | Description |
---|---|---|
Qualifier | PtrSafe | Indicates that the Declare statement is compatible with 64-bits. This attribute is mandatory on 64-bit systems. |
Data Type | LongPtr | A variable data type which is a 4-bytes data type on 32-bit versions and an 8-byte data type on 64-bit versions of Microsoft Office. This is the recommended way of declaring a pointer or a handle for new code but also for legacy code if it has to run in the 64-bit version of Office. It is only supported in the VBA 7 runtime on 32-bit and 64-bit. Note that you can assign numeric values to it but not numeric types. |
Data Type | LongLong | This is an 8-byte data type which is available only in 64-bit versions of Microsoft Office. You can assign numeric values but not numeric types (to avoid truncation). |
Conversion Operator | CLngPtr | Converts a simple expression to a LongPtr data type. |
Conversion Operator | CLngLng | Converts a simple expression to a LongLong data type. |
Function | VarPtr | Variant converter. Returns a LongPtr on 64-bit versions, and a Long on 32-bit versions (4 bytes). |
Function | ObjPtr | Object converter. Returns a LongPtr on 64-bit versions, and a Long on 32-bit versions (4 bytes). |
Function | StrPtr | String converter. Returns a LongPtr on 64-bit versions, and a Long on 32-bit versions (4 bytes). |
The follow example shows how to use some of these items in a Declare statement.
Note that Declare statements without the PtrSafe attribute are assumed not to be compatible with the 64-bit version of Office.
There are two conditional compilation constants: VBA7 and Win64. To ensure backward compatibility with previous versions of Microsoft Office, you use the VBA7 constant (this is the more typical case) to prevent 64-bit code from being used in the earlier version of Office. For code that is different between the 32-bit version and the 64-bit version, such as calling a math API that uses LongLong for its 64-bit version and Long for its 32-bit version, you use the Win64 constant. The following code shows the use of these two constants.
To summarize, if you write 64-bit code and intend to use it in previous versions of Office, you will want to use the VBA7 conditional compilation constant. However, if you write 32-bit code in Office, that code works as is in previous versions of Office without the need for the compilation constant. If you want to ensure that you are using 32-bit statements for 32-bit versions and 64-bit statements for 64-bit versions, your best option is to use the Win64 conditional compilation constant.
Using conditional compilation attributes
The following example shows VBA code written for 32-bit that needs to be updated. Notice the data types in the legacy code that are updated to use LongPtr because they refer to handles or pointers.
VBA code written for 32-bit versions
VBA code rewritten for 64-bit versions
Frequently asked questions
When should I use the 64-bit version of Office?
This is more a matter of which host application (Excel, Word, and so forth) you are using. For example, Excel is able to handle much larger worksheets with the 64-bit version of Microsoft Office.
Can I install 64-bit and 32-bit versions of Office side-by-side?
No.
When should I convert Long parameters to LongPtr?
You need to check the Windows API documentation on the Microsoft Developers Network for the function you want to call. Handles and pointers need to be converted to LongPtr. As an example, the documentation for RegOpenKeyA provides the following signature:
The parameters are defined as:
Parameter | Description |
---|---|
hKey [in] | A handle to an open registry key. |
lpSubKey [in, optional] | The name of the registry subkey to be opened. |
ulOptions | This parameter is reserved and must be zero. |
samDesired [in] | A mask that specifies the desired access rights to the key. |
phkResult [out] | A pointer to a variable that receives a handle to the opened key. |
Microsoft Office 64-bit Torrent
In Win32API_PtrSafe.txt, the Declare statement is defined as:
Update Excel To 64 Bit
Should I convert pointers and handles in structures?
Microsoft Office 64 Bit Arm
Yes. See the MSG type in Win32API_PtrSafe.txt:
When should I use strptr, varpt, and objptr?
You should use these functions to retrieve pointers to strings, variables and objects, respectively. On the 64-bit version of Office, these functions will return a 64-bit LongPtr, which can be passed to Declare statements. The use of these functions has not changed from previous versions of VBA. The only difference is that they now return a LongPtr.