1

I develop VBA code using some advanced automated macros that do "plumbing" and extra debugging during DEV phase. However, when I ship the files to users (PROD phase), I want all of this to be turned off.

Those switches between DEV and PROD happen quite a lot (git + devops methodology).

What would be the best / most elegant way to implement a quick "switch" between DEV and PROD? Yes, I could just use a global Const isDebug (and I did it for some projects), but it's burdensome, inelegant and error-prone (more than once I forgot to "flip" the switch - as I said earlier, quick and agile "almost" CI/CD pipeline).

EDIT

Right now I'm using a quick dirty hack (I don't like dirty hacks) that checks whether the Excel file is being ran from a location with my login name in the path. If yes - that means I'm working on the file. If no - someone else is using it and we don't need any debugging modes. But it's ugly and I can foresee a lot of problems (for one, tomorrow someone else might be developing those VBAs... so the debug code would have to be rewritten).

Erik A
  • 31,639
  • 12
  • 42
  • 67
Alexander
  • 313
  • 3
  • 10
  • Possible duplicate of [How to programmatically change conditional compilation properties of a VBA project](https://stackoverflow.com/q/19726791/11683) – GSerg Jul 03 '19 at 09:59
  • Hi @GSerg, thanks for the link. It's quite an interesting idea... but a bit of an overkill :) Again, I might just use a simple Const called isDebug... but, as experience has proved, it's too unreliable and error-prone. – Alexander Jul 03 '19 at 10:10
  • This question is opinion-based imo. There are many options, a simple one is `GetOption`/`SetOption` to set a debug option on a specific computer, but then you can't have conditional compilation. You can, however, debug on a specific workstation without needing to recompile. – Erik A Jul 03 '19 at 10:33
  • 1
    What about using a text file as condtion, if missing no debug, if present, read setting debug on/off. When deploying without the file debug is off standard and if someone else needs debug on, share the file. – ComputerVersteher Jul 03 '19 at 17:57
  • @ComputerVersteher, honestly, this is the best suggestion :) Sort of UNIX-way: touch .debug :) If you write this in an answer, I'll accept is as a solution! Simple and sweet. When I copy (automatically) my macro, the users won't have that .debug file! Totally what I wanted! – Alexander Jul 08 '19 at 12:30

3 Answers3

2

In VBE goto Extras -> Properties of VBAProject and enter an argument for compiling eg:

DEV_MODE = -1

enter image description here
Sorry for the German screenshot.

Then use the following code

Option Explicit

Sub test()
    'the following #If is a compile condition
    #If DEV_MODE Then
        'this is only compiled in dev mode
        Debug.Print "debug mode is on"
    #Else
        'this is only compiled in production mode
        Debug.Print "debug mode is off"
    #End If
End Sub

Note that in VBA -1 is True and 0 is False. Switching the compile argument DEV_MODE = -1 will switch the dev mode in the whole VBA project.

Pᴇʜ
  • 56,719
  • 10
  • 49
  • 73
  • 2
    How is that easier/better than a `#const`? Seems just as easy, or even more easy to forget. – Erik A Jul 03 '19 at 10:22
  • Thanks @Pᴇʜ, I didn't know about those "Argumente fuer bedingte Kompielierung" :) Might be useful. However, that doesn't really solve the issue - just like Erik A noticed, it might be even easier to forget than flipping a constant... – Alexander Jul 03 '19 at 10:29
  • Well it is practically the same as a `#Const` but better than using a `Const`. • Of course you can forget to change this exactly like any other workaround you do ;) • Put a big fat warning into your workbook open event that pops up in dev mode, and you should have a SOP (standard operating procedure) to publish something which includes testing if dev mode is off (so you cannot forget it). – Pᴇʜ Jul 03 '19 at 11:05
  • 1
    Another pro for this is that everyone knows where to look for that switch. If it is hidden in one of the numerous modules you need to search for it. – Pᴇʜ Jul 03 '19 at 11:23
1

You can use a textfile in workbooks path as condition.

If the file is missing ('DebugMode.txt' in example) or the debug option ('DebugMode:On' in textfile) is not set, turn off debug mode, else turn it on.

If you deploy the workbook without the textfile, debug mode is off.

If some else needs debug mode on, share/create the file.

Example code:

Function IsDebugMode() As Boolean

Const DebugOptionFileName As String = "DebugMode.txt" 
Const DebugIsOnString As String = "DebugMode:On"
Const ForReading as Long = 1

Dim txtStream As Object
Dim DebugOptionFilePath As String

IsDebugMode = False
DebugOptionFilePath = ThisWorkbook.Path & "\" & DebugOptionFileName

With CreateObject("Scripting.Filesystemobject")
    If .FileExists(DebugOptionFilePath) Then
        Set txtStream = .OpenTextFile(DebugOptionFilePath, ForReading, False)
        Do Until txtStream.AtEndOfStream
            If txtStream.ReadLine = DebugIsOnString Then
                IsDebugMode = True
                Exit Do
            End If
        Loop
    End If
End With

End Function
ComputerVersteher
  • 2,638
  • 1
  • 10
  • 20
  • 1
    Just a little note. Be aware that this is not Mac safe. So if you have potential Mac users but develop only in Windows you can just set it always to production mode in Macs. Therefore use conditional compilation `#If Mac Then` … `'production` … `#Else` … `'your code` … `#End If`. • If you want to develop on Mac too then you will need a Mac way to test for the file, because `Scripting.Filesystemobject` is not available on Mac. – Pᴇʜ Jul 09 '19 at 07:35
  • This is the best solution. Totally automatic and hassle-free (when you copy an Office file to users, they won't have the .debug file)! If you forgot to add the .debug file, you'd notice it very quickly during the DEV stage (when some tools would stop working) :) – Alexander Jul 15 '19 at 09:36
0

I don't like the attempt of having the switch as Compiler-Setting - forgetting to change it is even more likely than changing a Const definition.

I find your attempt checking username, devicename, path of the file or stuff like that not too bad. Just put the logic into a small function isTestMode() (even if it is a one-liner) which returns a boolean. Within this function, it is easy to change to logic if another person will take over the work. Use this function (and nothing else!) to check if or if not to execute your debugging statements.

Public Function isTestMode() as boolean
    ' Checking current user
    isTestMode = (environ("Username") = "FunThomas")
    ' Checking device name
    isTestMode = (environ("ComputerName") = "MySuperPC")
    ' Checking if a specific file is present
    isTestMode = Dir(thisworkbook.Path & "\IsTestMode") <> "")
End Function
FunThomas
  • 23,043
  • 3
  • 18
  • 34
  • 3
    That seems like exactly what the OP declares to be a "dirty hack" they are currently using. – GSerg Jul 03 '19 at 10:52
  • At the end everything is a hack. Const, Compile Switch, Ini-File, Registry... I just wanted to point out that you should have a single place to check it so it's easy to change the logic. And don't you think that the accepted answer of the duplicate link isn't a much bigger hack? – FunThomas Jul 03 '19 at 11:56
  • 1
    It is also a hack, but it is not a hack the OP *is already using*. – GSerg Jul 03 '19 at 11:58