That Whacky Conditional Compiler Argument
VBA's conditional compilation constants look like Booleans but they are not, and the difference will bite you every time you use Not with Win64.
What Is Conditional Compilation?
Conditional compilation lets you control which lines of VBA actually get compiled and run, depending on the environment. Common use cases:
- Code needs to run across multiple Office versions with API differences.
- Support for both 32-bit and 64-bit Office.
- Using early binding (Intellisense) but distributing with late binding.
- Using a debug build with verbose logging and a lean production build without it.
Without it, you'd need separate projects or constant commenting and uncommenting. With it, all versions live in one codebase inside #If...#Else...#End If blocks. Note the # prefix — these are not the same as regular If statements.
Conditional Compilation Constants
A conditional compilation constant is a named value set to an integer. The most common values are 0 (False) and -1 (True). Constants can be defined in three ways:
- Project Properties dialog — available across all modules in the project. Must be an integer from -32768 to 32767 (no thousands separators).
- Command line at open — also project-wide.
#Constdirective in a module — available only within that module. More flexible: can be an integer of any size, a real, a Boolean, or a string.
VBA also ships with four built-in constants: VBA7, Win32, Win64, and Mac that reflect the current environment automatically.
The Whacky Part: The Built-In Constants Are Not What They Appear to Be
In standard VBA and Excel formula logic, any value of 0 is False and any non-zero value is True. Negating those values is logically sound: Not 0 is True and Not any non-zero value is False. Straightforward. And the conditional compilation formula evaluator handles this logic as expected — it works correctly on any conditional compilation constant we define ourselves.
But, for some unknown reason, the built-in constants VBA7, Win32, Win64, and Mac are not quite what they appear to be. All written documentation states that they are either 0 (False) or -1 (True).
There are two problems with these constants. First, when True, they are 1, not -1. Second, when the conditional compilation formula evaluator negates them with the Not operator, the negation always evaluates to True for both 0 and 1 values. With a 64-bit installation, Win64 = True and Not Win64 = True.
This is not a problem if we stay away from the Not operator. This logic works as expected:
#If Win64 Then
#Else
#End IfBut this does not:
#If Not Win64 Then
#End IfNor does this:
#If Win64 = -1 Then
#End IfThe Fix
Do not use the Not operator with any of the four built-in conditional compilation constants. If only logic for the negative result is needed, use one of these two techniques:
#If Win64 Then
#Else
' Code to compile in a non-Win64 environment
#End IfOr:
#If Win64 = 0 Then
' Code to compile in a non-Win64 environment
#End IfThe Tests and Results
Below are the tests used to figure out what is going on and write this article.
#Const ConditionalCompilationConstantZero = 0
#Const ConditionalCompilationConstantPositive1 = 1
#Const ConditionalCompilationConstantNegative1 = -1
Const VBAZero As Integer = 0
Const VBAPositive1 As Integer = 1
Const VBANegative1 As Integer = -1
Public Sub Test()
#If Not ConditionalCompilationConstantZero Then
Debug.Print "Conditional Compilation: Not 0 = True"
#Else
Debug.Print "Conditional Compilation: Not 0 = False"
#End If
#If Not ConditionalCompilationConstantPositive1 Then
Debug.Print "Conditional Compilation: Not 1 = True"
#Else
Debug.Print "Conditional Compilation: Not 1 = False"
#End If
#If Not ConditionalCompilationConstantNegative1 Then
Debug.Print "Conditional Compilation: Not -1 = True"
#Else
Debug.Print "Conditional Compilation: Not -1 = False"
#End If
If Not VBAZero Then
Debug.Print "VBA: Not 0 = True"
Else
Debug.Print "VBA: Not 0 = False"
End If
If Not VBAPositive1 Then
Debug.Print "VBA: Not 1 = True"
Else
Debug.Print "VBA: Not 1 = False"
End If
If Not VBANegative1 Then
Debug.Print "VBA: Not -1 = True"
Else
Debug.Print "VBA: Not -1 = False"
End If
#If Not Win64 Then
Debug.Print "Conditional Compilation: Not Win64 = True (should be False)"
#Else
Debug.Print "Conditional Compilation: Not Win64 = False"
#End If
#If Not Win32 Then
Debug.Print "Conditional Compilation: Not Win32 = True"
#Else
Debug.Print "Conditional Compilation: Not Win32 = False"
#End If
#If Win32 = 0 Then
Debug.Print "Conditional Compilation: Win32 = 0"
#End If
#If Win32 = 1 Then
Debug.Print "Conditional Compilation: Win32 = 1"
#End If
#If Win32 = -1 Then
Debug.Print "Conditional Compilation: Win32 = -1"
#End If
#If Win64 = 0 Then
Debug.Print "Conditional Compilation: Win64 = 0"
#End If
#If Win64 = 1 Then
Debug.Print "Conditional Compilation: Win64 = 1"
#End If
#If Win64 = -1 Then
Debug.Print "Conditional Compilation: Win64 = -1"
#End If
End SubThe results:
Conditional Compilation: Not 0 = True
Conditional Compilation: Not 1 = True
Conditional Compilation: Not -1 = False
VBA: Not 0 = True
VBA: Not 1 = True
VBA: Not -1 = False
Conditional Compilation: Not Win64 = True (should be False)
Conditional Compilation: Not Win32 = True
Conditional Compilation: Win32 = 1
Conditional Compilation: Win64 = 0
Conditional Compilation: Win64 = 1Feedback
Question, correction, or comment? Let us know.