Variable Lifetime

Variables also have a lifetime. The difference between lifetime and scope is quite simple: lifetime refers to how long (or when) the variable is valid (that is, retains a value) whereas scope refers to where the variable is accessible or visible.

To illustrate the difference, consider the following procedure:

Sub ProcedureA()

Dim LocalVar As Integer LocalVar = 0 Call ProcedureB LocalVar = 1 End Sub

Note that LocalVar is a local variable. When the line:

Call ProcedureB

is executed, execution switches to ProcedureB. While the lines of ProcedureB are being executed, the variable LocalVar is out of scope, since it is local to ProcedureA. But it is still valid. In other words, the variable still exists and has a value, but it is simply not accessible to the code in ProcedureB. In fact, ProcedureB could also have a local variable named LocalVar, which would have nothing to do with the variable of the same name in ProcedureA.

Once ProcedureB has completed, execution continues in ProcedureA with the line:

LocalVar = 1

This is a valid instruction, since the variable LocalVar is back in scope.

Thus, the lifetime of the local variable LocalVar extends from the moment that ProcedureA is entered to the moment that it is terminated, including the period during which ProcedureB is being executed as a result of the call to this procedure, even though during that period, LocalVar is out of scope.

Incidentally, you may notice that the Microsoft help files occasionally get the notions of scope and visibility mixed up a bit. The creators of the files seem to understand the difference, but they don't always use the terms correctly.

5.4.12.1 Static variables

To repeat, a variable may go in and out of scope and yet remain valid during that time—that is, retain a value during that time. However, once the lifetime of a variable expires, the variable is destroyed and its value is lost. It is the lifetime that determines the existence of a variable; its scope determines its visibility.

Thus, consider the following procedures:

Sub ProcedureA() Call ProcedureB Call ProcedureB Call ProcedureB Call ProcedureB Call ProcedureB End Sub

Sub ProcedureB()

End Sub

When ProcedureA is executed, it simply calls ProcedureB five times. Each time ProcedureB is called, the local variable x is created anew and destroyed at the end of that call. Thus, x is created and destroyed five times.

Normally, this is just want we want. However, there are times when we would like the lifetime of a local variable to persist longer than the lifetime of the procedure in which it is declared. As an example, we may want a procedure to do something special the first time it is called, but not subsequent times. For instance, the following one-line macro changes the font of the selected cells to Comic Sans:

Sub ToComic()

Selection.Font.Name = "Comic Sans" End Sub

Suppose, however, that we wish to warn the user that Comic Sans is a bit informal and ask if he or she really wants to make this change. We don't want to make a pest of ourselves by asking every time the user invokes this macro. What we need is a local variable with a "memory" that will allow it to keep track of whether or not a particular call to ToComic is the first call or not. This is done with a static variable.

A static variable is a local variable whose lifetime is the lifetime of the entire module, not just the procedure in which it was declared. In fact, a static variable retains its value as long as the document or template containing the code module is active (even if no code is running).

Thus, a static variable has the scope of a local variable, but the lifetime of a module-level variable. C'est tout dire !

Consider now the modification of the preceding macro, which is shown in Example 5-2. The code first declares a static Boolean variable called NotFirstTime. It may seem simpler to use a variable called FirstTime, but there is a problem. Namely, Boolean variables are automatically initialized as False, so the first time that the ToComic macro is run, FirstTime would be False, which is not want we want. (We will discuss variable initialization a bit later.)

Example 5-2. ToComic() Modified to Use a Static Variable

Sub ToComic()

' Declare static Boolean variable

Static NotFirstTime As Boolean

' If first time, then ask for permission If NotFirstTime = False Then

If MsgBox("Comic Sans is a bit informal. Proceed?", vbYesNo) = vbYes Then

' Make the change

Selection.Font.Name = "Comic Sans MS" End If

' No longer the first time NotFirstTime = True Else

' If not the first time, just make the change Selection.Font.Name = "Comic Sans MS" End If End Sub

The If statement checks to see if the value of NotFirstTime is False, as it will be the first time the procedure is called. In this case, a message box is displayed, as shown in Figure 5-3. If the user chooses the Yes button, the font is changed. In either case, the static Boolean variable NotFirstTime is set to True. Precisely because NotFirstTime is static, this value will be retained even after the macro ends (but not if the document is closed).

Figure 5-3. Dialog that appears if the static NotFirstTime is false

0 0

Post a comment