Initializing Standard Module Variables


Initializing variables in standard modules is a little trickier. It would be nice to have a Module_Initialize event in which you could initialize internal values, but since there isn’t one, you have to do some hacking to initialize variables with the static variable technique described earlier.


You might be laboring under the misconception that Visual Basic doesn’t support global initialized variables in standard modules. Not so. Property procedures make it easy, if not obvious. Normally, I think of properties as being attached to forms and classes, but no rule says that a property has to be tied to an object. For example, here’s a global variable, cLastWindow, initialized to 20:

Private fNotFirstTime As Boolean
Private cLastWindowI As Integer
§
Public Property Get cLastWindow() As Integer
If Not fNotFirstTime Then
fNotFirstTime = True
cLastWindowI = 20
End If
cLastWindow = cLastWindowI
End Property

Property Let cLastWindow(cLastWindowA As Integer)
fNotFirstTime = True
cLastWindowI = cLastWindowA
End Property

You can use this property from anywhere, just like any other global variable:

For i = 1 To cLastWindow
WipeWindow i
Next
cLastWindow = cLastWindow - 1

Users of your standard module needn’t be the wiser about how you wrote it, especially if you hide it in a DLL so that no one can see the source.


If your standard module contains several variables that need to be initialized, you can write your own Module_Initialize routine. Call it from every procedure that uses one of the variables:

If Not fNotFirstTime Then Module_Initialize

This might not be as efficient as you’d like. Testing for fNotFirstTime all over the place is no fun, but the test is True only once. Don’t forget to initialize fNotFirstTime along with the other variables.


A property with a Property Get but no Property Let or Property Set acts like a read-only variable—otherwise known as a constant. Let’s take my favorite constant, sCrLf. It’s simply a string consisting of a carriage return and a linefeed. You can’t define it with Const because it has two control characters, which must be tied together with the concatenation operator (& or +). Visual Basic (unlike every other language I’ve encountered) doesn’t allow control characters in constants, even though Chr$(13) and the concatenation operator could easily be evaluated by the compiler at design time.


The following solution isn’t really necessary, because Visual Basic provides vbCrLf and the Windows API type library provides sCrLf. But if you didn’t have a type library with the constant, you could define your own in a standard module this way:

Public Property Get sCrLf() As String
Static s As String
If s = sEmpty Then s = Chr$(13) & Chr$(10)
sCrLf = s
End Property