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.

VBA Project Properties
Conditional Compiler Arguments
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.

Available constants on 16-bit platforms
Constant Description
Win16 Is 16-bit compatible
Win32 Is 32-bit compatible
Win64 Is 64-bit compatible
Available constants on 32-bit and 64-bit platforms
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:

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