> ## Content Index
> Fetch the complete content index at: https://nolongerset.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Dropping `#If VBA7 Then` From API Declares
- URL: https://nolongerset.com/dropping-if-vba7/
- Published: 2023-12-22T04:34:51.000Z
- Updated: 2026-05-08T12:37:50.000Z
- Description: Plus, step-by-step instructions for restoring the `#If VBA7 Then` code construct if you still need to support Office 2007 or earlier.
- Author: Mike Wolfe
- Tags: Announcement, VBA, #Import 2026-05-20 02:59

It is time.

From this point forward, I no longer feel obligated to include the `#If VBA7 Then` construct in my Windows API calls.

In other words, code on my site that used to look like this...

```vba
#If VBA7 Then
    Private Declare PtrSafe Function apiGetParent _
        Lib "user32" Alias "GetParent" (ByVal hWnd As LongPtr) As LongPtr
#Else
    Private Declare Function apiGetParent _
        Lib "user32" Alias "GetParent" (ByVal hWnd As Long) As Long
#End If
```

...will now look like this...

```vba
Private Declare PtrSafe Function apiGetParent _
    Lib "user32" Alias "GetParent" (ByVal hWnd As LongPtr) As LongPtr
```

As I wrote in my [32-bit vs. 64-bit VBA Deep Dive article](https://nolongerset.com/32-64-bit-deep-dive/):

> Now that we've had two perpetual VBA7-supported versions of Office *reach end of life*, I feel comfortable dropping support for Office 2007 and earlier in both my applications and my writing.

[32-bit vs. 64-bit VBA: Deep DiveA deep dive into the past, present, and future of the transition from 32-bit VBA to 64-bit VBA.![](https://nolongerset.com/favicon.png)No Longer SetMike Wolfe![](https://storage.ghost.io/c/eb/d7/ebd732c1-5f03-4f07-b386-5d08557e15c9/content/images/2023/12/Deep-Dive-32-to-64-bit-VBA.jpg)](https://nolongerset.com/32-64-bit-deep-dive/)

## Here's Why I'm Doing This Now

- VBA7 has been available since Office 2010
- Office 2007–the last version without VBA7–has been out of support since October 10, 2017
- This makes it so I don't have to choose between readability and compile-time type checks in my calling code (e.g.*, I can simply use* `As LongPtr` *instead of* `As Variant` *or* `#If VBA7 Then As LongPtr #Else As Long #End If`)
- It's simple to adapt `PtrSafe` API declares to run in Office 2007 and earlier

That last point is the most important one for this blog. 

I know all of *my applications* are running on Access 2010 or later. However, I am sure at least some of my readers have Access applications running on Access 2007 or earlier. If that's you and you need to support those older versions of Access, read the next section for step-by-step instructions to convert my `PtrSafe` API declare lines to run in your version of Office.

## Adapting API Declares to Run in Office 2007 and Earlier

As I [lamented](https://nolongerset.com/32-64-bit-deep-dive/#converting-from-long-to-longptr) in my 32-bit vs. 64-bit VBA Deep Dive article, there is no simple algorithm to follow to convert 32-bit-only code to run under 64-bit VBA.

The main difficulty in moving from 32-bit-only API declares to 64-bit-compatible API declares was in identifying which `Long` parameters needed to be switched to `LongPtr` (i.e., which parameters represented memory pointers/object handles) and which should stay declared as `Long` (i.e., the arguments represented actual 32-bit signed integers). Figuring that out required using references such as the Win32\_API.txt file, reading documentation for the API functions, or–in some extreme cases–finding and understanding the underlying C++ header files.

However, moving in the other direction *is* quite simple. 

What's more, if you follow the instructions below, your code **will continue to run in 64-bit versions of VBA** while also being backward-compatible with VBA6 versions of Office (2007 and earlier).

### Step-by-Step Instructions

You may need to make changes in two different locations:

- The API `Declare` line in the code module's header
- References to `LongPtr` in the calling code (e.g., the `Sub`, `Function`, or `Property`)

#### API Declare in Module Header

Here are the steps to migrate a VBA 7-only API declare to run in both 64-bit environments and Office versions 2007 and earlier (i.e., pre-VBA 7):

1. Add the following line of code before your existing API declare: `#If VBA7 Then`
2. Add the following line of code after your existing API declare: `#Else`
3. Copy and paste your existing API declare to the line following the `#Else`
4. Delete the keyword `PtrSafe` from the copied line
5. Replace any instances of `LongPtr` with `Long` in the copied line
6. Add the following line of code after the copied line: `#End If`

Here's an example from a [recent article](https://nolongerset.com/getinneraccesshwnd/):

##### Before

The code below works in both 32-bit and 64-bit environments in Office 2010 and later:

```vba
Private Declare PtrSafe Function apiGetParent _
    Lib "user32" Alias "GetParent" (ByVal hWnd As LongPtr) As LongPtr
```

##### After

The code below works in both 32-bit and 64-bit environments in Office 97 and later:

```vba
#If VBA7 Then
    Private Declare PtrSafe Function apiGetParent _
        Lib "user32" Alias "GetParent" (ByVal hWnd As LongPtr) As LongPtr
#Else
    Private Declare Function apiGetParent _
        Lib "user32" Alias "GetParent" (ByVal hWnd As Long) As Long
#End If
```

#### LongPtr References in the Calling Code

While you can take the same approach as above by adding `#If VBA7 Then...#Else...#End If` lines to your calling code, a simpler alternative (but with less compile-time type-checking safety) is to replace references to `LongPtr` with `Variant` in your calling code:

1. Replace variable declarations of `As LongPtr` with `As Variant`

We'll continue using the above example from a previously published [article](https://nolongerset.com/getinneraccesshwnd/):

##### Before

```vba
Function GetInnerAccessHwnd(Optional ByVal ChildHWnd As LongPtr = 0) As LongPtr
```

##### After

```vba
Function GetInnerAccessHwnd(Optional ByVal ChildHWnd As Variant = 0) As Variant
```

## How Do You Know If You Need To Do This?

The `PtrSafe` keyword was introduced in VBA 7, which debuted in Office 2010.

If you are running Office 2007 or earlier, this keyword does not exist yet and you will get the following error when trying to compile code that includes the keyword:

> Compile error:  
>  
> Expected: Sub or Function

![](https://storage.ghost.io/c/eb/d7/ebd732c1-5f03-4f07-b386-5d08557e15c9/content/images/2023/12/image-26.png)

## Why Does Adding `#If VBA7 Then` Fix My Code?

You may be wondering how adding the `#If VBA7 Then` line could make the compile error go away in these earlier versions of VBA.

How can a feature introduced in VBA7 (i.e., the `VBA7` compiler constant), be recognized by earlier versions of the language? After all, isn't the original problem the fact that the `PtrSafe` keyword is not recognized by earlier versions?

The key difference is that `PtrSafe` is a *language keyword* while `VBA7` is a *compiler constant*.

When VBA encounters a language keyword that it does not recognize, that triggers a compile error (technically, it's a syntax error, since the keyword is not part of the language grammar).

However, when VBA encounters a compiler constant that it does not recognize, the compiler constant simply evaluates to False.

So, by introducing a compiler constant–`VBA7`–that evaluates to True in VBA 7 (*and later versions, on the unlikely chance that a VBA 8 ever gets released*), Microsoft provides a way for developers to "hide" new language features from older versions of the language.

*Cover image generated with DALL-E-3*

***UPDATE*** *\[2024-01-02\]: Added section "LongPtr References in the Calling Code" based on feedback from Peter Cole in the comments below. Thanks, Peter!*