VBA Compiler Directives
Conditional compiler directives are code statements that are interpreted before a code module is compiled that are used to compile code differently under certain conditions. Conditional compiler directives are used to make VBA code compatible on different platforms and with different versions of VBA.
#If Then #Else Directive
The #If Then #Else directive will conditionally compile blocks of code. The #If Then #Else directive is normally used with built-in compiler constants, conditional compiler arguments, and constants defined using the #Const directive. Note that the Option Compare statement does not affect expressions in #If Then #Else directives. Expressions in a conditional compiler directive are always evaluated with Option Compare Text.
Note: Expressions in a conditional compiler directive are always evaluated with Option Compare Text.
Option Explicit
Public Sub Example()
#If VBA7 = 1 Then
Debug.Print "VBA7"
#ElseIf VBA6 = 1 Then
Debug.Print "VBA6"
#End If
End Sub
#Const Directive
The #Const Directive is used to defined a constant for use with conditional compiler directives. Conditional compiler constants are Private to the module in which they are declared.
Option Explicit
#Const DebugMode = 1
Public Sub Example()
#If DebugMode = 1 Then
Msgbox "Debug"
#Else
Msgbox "Production"
#End If
End Sub
Conditional Compiler Arguments
Conditional compiler arguments can be used to define constants that can be used with conditional compiler directives. Conditional compiler arguments are defined in the VBA project properties. Conditional compiler arguments have Project scope so they can be used anywhere inside the VBA project in which they are defined. Conditional compiler arguments work like constants declared using the #Const directive except they have Project scope instead of Module scope.
Option Explicit
Public Sub Example()
#If DebugMode = 1 Then
Debug.Print "Debug"
#Else
Debug.Print "Release"
#End If
#If CompileThis = 1 Then
Debug.Print "This Compiled"
#Else
Debug.Print "This Compiled Instead"
#End If
End Sub
Compiler Constants
Compiler Constants are used to test compatibility with different operating systems and different versions of VBA. Compiler Constants are set to 1 or 0 depending on the platform the code is running on.
Constant | Description |
---|---|
Win16 | Is 16-bit compatible |
Win32 | Is 32-bit compatible |
Win64 | Is 64-bit compatible |
Constant | Description |
---|---|
Vba6 | Is compatible with VBA version 6.0 |
Vba7 | Is compatible with VBA version 7.0 |
Win16 | Is 16-bit compatible |
Win32 | Is 32-bit compatible |
Win64 | Is 64-bit compatible |
Mac | Is Mac |
It is important to note that conditional compiler constants do not evaluate to True and False. They evaluate to 1 and 0. When using Logical/Bitwise operators be aware that numbers are compared using bitwise comparison and boolean expressions are compared using logical comparison. Be sure to explicitly compare conditional compiler constants to 1 or 0 to return True or False.
Public Sub Example()
'BAD CODE - Do NOT do this
'Bitwise comparison
#If VBA7 And Win64 Then
Debug.Print "VBA7 and Win64"
#End If
'Truthy/Falsey
#If VBA7 Then
Debug.Print "VBA7"
#End If
End Sub
Public Sub Example()
'CORRECTED - Do this
'Logical comparison
#If VBA7 = 1 And Win64 = 1 Then
Debug.Print "VBA7 and Win64"
#End If
'Explicit boolean
#If VBA7 = 1 Then
Debug.Print "VBA7"
#End If
End Sub
Compatibility
Conditional compilation is used to write code that is compatible on different operating systems and different versions of VBA.
VBA Versions
VBA6 is an older version of VBA. VBA7 is the current version. VBA7 was essentially an update to make VBA more compatible with 64-bit operating systems. VBA7 added two new data types, LongLong and LongPtr, with accompanying conversion functions, DefType statements, a type declaration character for the LongLong type, and the vbVarType.vbLongLong constant. VBA7 also added the PtrSafe keyword for DLL declarations which must be used on 64-bit platforms. In VBA7 the ObjPtr, StrPtr, and VarPtr functions return LongPtr whereas in VBA6 they return Long.
VBA7 Additions:
- PtrSafe
- LongPtr
- LongLong
- LongLong type-declaration character ^
- CLngPtr
- CLngLng
- vbVarType.vbLongLong
- DefLngPtr
- DefLngLng
Conditional compilation must be used when declaring LongLong or LongPtr to make code compatible with VBA6 and VBA7.
#If VBA7 = 1 Then
Dim i As LongLong
Dim j As LongPtr
#Else
Dim i As Long
Dim j As Long
#End If
The PtrSafe keyword is required when using the Declare statement in VBA7. PtrSafe works on 64-bit and 32-bit systems.
#If VBA7 = 1 Then
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
32-bit vs 64-bit
Conditional compilation can be used to write code that is compatible on 32-bit and 64-bit operating systems. Depending on the situation it may be important to support 32-bit operating systems, however, it is important to support 64-bit operating systems because 64-bit is the standard for new computers. Microsoft has stopped offering 32-bit Windows 10 for new PCs. VBA compiler constants can be used to check the bitness of the OS and compile code accordingly.
#If VBA7 = 1 Then
#If Win64 Then
Declare PtrSafe Function GetTickCount64 Lib "kernel32" () As LongLong
#End If
Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
#Else
Declare Function GetTickCount Lib "kernel32" () As Long
#End If
The LongPtr type can be used to make code compatible with 64-bit and 32-bit systems. LongPtr evaluates to a Long on 32-bit and a LongLong on 64-bit. All pointers and handles in Declare statements should be updated to use LongPtr.
#If VB7 = 1 Then
Public Declare PtrSafe Function IsWindowVisible Lib "user32" _
(ByVal hwnd As LongPtr) As Long
#Else
Public Declare Function IsWindowVisible Lib "user32" _
(ByVal hwnd As Long) As Long
#End If
Mac
There are a number of differences between working with Windows and Mac. Microsoft Office is sandboxed on Mac. VBA has more capabilities on Microsoft Windows. Mac does not have access to many of the libraries provided by Windows that are commonly used in VBA. The Microsoft Scripting Runtime library for example is not available on Mac and thus the Scripting.Dictionary class cannot be used. There are also differences between specific Mac Office versions. VBA can be used to call AppleScripts on a Mac. The Mac compiler constant can be used to test if a Mac is being used.
Public Sub Example()
#If Mac Then
Debug.Print "Apples"
#Else
Debug.Print "Windows"
#End If
End Sub