|
|
Compiler Directives Related Content:
[edit] OverviewThere may be situations where we want to compile different forms of code, but not have multiple copies of essentially the same database and modules. Compiler Directives allow us to determine which code segment should be compiled. Because Compiler Directives are compiled conditionally, we are afforded the opportunity to include code in our project that would be illegal in non-directive code. This technique is particularly useful when working with varying versions of the host application (Access, Word, Excel, etc.), when using different versions of VBA (VBA or VBA7) and when working with different machine architectures (Win32 or Win64). The basic syntax of a Conditional Compilation statement is: CODE #If ThisConstant Then
'compile this code #Else 'compile this code #End If
[edit] Compiler ConstantsIn order to implement conditional compiling, we must provide be able to use one or more constants for which to base the condition on. We can use some of the built in constants, or create our own. [edit] Built In Compiler ConstantsVBA offers a handful of built in compiler contsants in later versions that can prove to be very helpful. These contsants provide boolean returns based on certain environment information. They are:
The VBA6 compiler constant can be used to differentiate VBA6 code from older versions of VBA. Mac compiler constant is generally inapplicable as Access does not exist for Macintosh but in Excel/Word/Outlook projects, can be used to run code specific to those running Macintoshes instead of PCs. VBA7 returns true if the project is compiled in the VBA7 environment (Office 2010 or newer), and Win64 returns true if the operating system in which the application is running is a 64 bit version of Windows. Example: CODE #If VBA7 Then
Private Declare PtrSafe Function MyAPI Lib "MyLib" (ByVal MyPointer As LongPtr) As Long #Else Private Declare Function MyAPI Lib "MyLib" (ByVal MyPointer As Long) As Long #End If
[edit] User Defined Compiler ConstantsIn addition to the built in constants, we have the means to create our own compiler constants. This can be done through the VBA Project Properties, or through module declaration of the constant. Note that we should be careful of ambiguous naming if we use both the property approach and the module declaration approach. We may wish to choose one or the other for each project. [edit] Module Declaration ApproachThe Module Declaration approach simply allows us to create a Const at module level for use with conditional compilation. This constant will be private to the module. CODE Option Compare Database
Option Explicit #Const Version = "A2000" Sub RunMe() #If Version = "A2000" Then 'run v2000 specific code #Else 'run non v2000 code #End If End Sub
[edit] Project Property ApproachThe Project Property approach allows us to define compilation constants by setting them in the VBA project's properties. Do to so, follow these steps:
Example: MyAppVersion = 1:MyAppMode = 2
[edit] Usage ExamplesThe following usage examples give an idea of scenarios when and how compiler directives may be applied. [edit] Application SpecificImplementing application specific compiler directives gives us a large amount of flexibility in our coding. We can customize our constants to cover any number of possibilities. CODE Option Compare Database
Option Explicit #Const Version = "A2000" Sub RunMe() #If Version = "A2000" Then 'run v2000 specific code #Else 'run non v2000 code #End If End Sub
[edit] API DeclarationsAPI Declarations based on VBA or VBA7 can vary: compiler directives allow us to compile one declaration or the other as required: CODE Option Compare Database
Option Explicit #If VBA7 Then Private Declare PtrSafe Function LoadLibrary Lib "Kernel32" Alias "LoadLibraryA" _ (ByVal lpFileName As String) As LongPtr ) #Else Private Declare Function LoadLibrary Lib "Kernel32" Alias "LoadLibraryA" _ (ByVal lpFileName As String) As Long #End If Public Sub RunMe(libraryFile As String) LoadLibrary libraryFile End Sub
[edit] Procedure SignaturesConditional Compilation can also be used to form constructs that may not be ordinarily legal but can be useful. Suppose we need a procedure to be always available but have a different signature: CODE #If EarlyBind Then
Public Sub EmailMyMail (MyMail As Outlook.MailItem) #Else Public Sub EmailMyMail (MyMail As Object) Const olHTML As Long = 5 #End If With MyMail 'Fill up the mail with details .SaveAs "C:\Temp", olHTML .Send End With End Sub Conditional compilation ensures that only one block at any time is in effect and thus compiler only reads the "active' block and treats the other blocks like it treats a comment -- it is completely ignored, so though we have two Sub statement but only one End Sub statement, the compiler see it as a single procedure. When we change the flag, the code still compiles but the procedure now has a different signature (e.g. MyMail is now typed as an object rather than specific Outlook.MailItem. We also included a constant that wasn't ordinarily needed when we reference the Outlook reference.
|
| This page was last modified 16:14, 25 February 2012. This page has been accessed 1,527 times. Disclaimers |