OML for the complete beginner, Lesson 7

Program Flow Control

Have you ever wanted to have a macro change the order in which commands are executed--or even pick which commands execute and which don't--depending on what's going on? If the answer is yes, then what you want to know is how to control the flow of a program.

Flow control involves telling the computer which command to execute next. Normally, this is the next line; unless instructed otherwise, the computer tries to execute each line in turn until it reaches the end of the program. That works fine for fairly simple, straightforward macros, but there are times when that just won't work. Loops are a variant of flow control, in that a certain set of commands are executed over and over, but there is much more to this concept than simple repetitions. (More than I can discuss right now, actually, so that topic will have to wait for another time.)

The most basic program flow control involves the Goto statement. This statement does exactly that--tells the computer to go to some other area of the program and execute the commands it finds there as if they actually immediately followed the Goto statement.


  Sub Main

    x = 1

    Goto Skip

    x = 2

  Skip: 

      MsgBox x

  End Sub

If the program executes correctly, then the result will be a message box with a "1" in it; the line with "x = 2" is skipped.


One of the main staples of any program is the If...Then "conditional" statement, which does a fairly good job of explaining itself. If a statement is true, Then execute a command; otherwise continue with the program as if the If...Then statement weren't there.


  If x = 1 Then y = 2

If you need to execute multiple commands when the statement is true, you can do so, but then you must use End If.


  If x = 1 Then

    y = 2

    z = 3

  End if

Normal programming practice is to indent anything within an extended If...Then statement, so that it is easy to see where the statement begins and ends, and what is inside. This becomes especially necessary with If...Then statements that are "nested" inside each other.


  If x = 1 Then

    If y = 2 Then

      z = 3

      MsgBox z

    End if

    z = z + 1

  End If

If you want one command or set of commands to execute if the statement is true, and a different set to execute if false, then you can add an Else into the works.


  If x = 1 Then y = 2 Else y = 3



  If y = 2 Then

    x = 2

    y = y + 1

  Else

    x = 5

  End If

The final piece of the If...Then puzzle is ElseIf. Depending on what sorts of conditions you are evaluating, it can come in handy. Also watch how If...Then can be combined with Goto to provide options for which sections of the program get executed or are skipped over.


  If x > 2 Then

    Goto Looper

  ElseIf x = 2 Then

    Goto Main

  Else

    Goto Done

  End If

Note that first condition. That's not an equal sign! Conditions work using Boolean logic--meaning there are only two results, "true" and "false"--with the addition that FALSE is equivalent to 0 and TRUE is equivalent to (not 0). Conditions can include =, >, <, >=, <=, <>, AND, OR, or nothing other than a variable, using parentheses to set off various parts of the statement. Some examples:


  If x = 1 Then y = 2

  If x > 2 Then x = 2

  If x < y Then z = 3

  If x <> 1 Then x = 1

  If x = 1 And y = 2 Then z = 3

  If (x = 1 And y = 2) Then z = 3

  If (x = 1 And y = 2) Or (z = 3) then x = y

  If x = FALSE Then y = 2

  If x = TRUE then z = 3

  If x Then z = 3

  If InStr(a$, b$)

The first four should be pretty easy to understand. The fifth and sixth are functionally identical--both conditions must be true for the command after Then to be executed--but the latter may be easier to read and quickly understand what's going on. For the seventh, either both of the first two equalities have to be true, or the third has to be true in order for the specified command to be executed. The eighth and ninth show the possible uses of TRUE and FALSE other than as results. The eighth says the same thing as "If x = 0...", and the ninth says the same as "If x <> 0..." The tenth line is functionally identical to the ninth. The last line shows that any command that returns a TRUE/FALSE result or a number of some sort can be used in an If...Then statement.

One way to illustrate the use of If...Then statements in Connexion is with the CS.ItemType command. For this illustration, all you need to know is that a return value of 0 means that the top window in Connexion (not counting the Macro Editor window) is an online bibliographic record, and 1 means it is an online bibliographic save file record.


  Sub Main

    Dim CS As Object

    Set CS = CreateObject(Connex.Client)



    WindowType% = CS.ItemType

    If WindowType% < 0 And WindowType% > 1 Then

      MsgBox "There is no active bibliographic record to export.  Exiting..."

      Goto Done

    End If



    bool = CS.Export

    bool = CS.CloseRecord(TRUE)



  Done:

  End Sub

This is a perfect example of a macro being able to change the way it works depending on what's on the screen. The first thing it does is check what type of window is open and active in Connexion. If there is a bibliographic record open (either a WorldCat record or an online save file record), then the macro skips over the If...Then block and exports, saves, and closes the record. If there isn't an active bibliographic record, the macro goes into the If...Then block, pops open a message box with a warning, then stops. Because of this fork in the program flow, if you accidentally run this macro when there is an authority record open, it will not execute its commands on the authority record.

Another way to do many of the same things as an If...Then statement is Select Case. You give it the variable to check as well as a set of possible results, and the program takes care of the rest.


  Select Case x

    Case 0

      Goto Zero

    Case 1, 3, 5, 7, 9

      Goto Odds

    Case 2, 4, 6, 8

      Goto Evens

    Case 10 To 20

      Goto Teens

    Case Is > 20

      Goto More

    Case Else

      Goto Mistake

  End Select

As you can see, it's possible to make any of several outcomes have the same result, as well as those that fall within a range of values (note that the lesser value must always be on the left), or are on one side of an inequality. Also, it's possible to say that everything not specified (in this case, a negative) triggers a certain command/set of commands, using Case Else. It is also possible to use strings with Select Case; such a line would be in the form


    Select Case a$

      Case "b"

        Goto Bee

      Case "c"

        Goto Cee

    End Select

If a$ is either "b" or "c", then the program moves on to the specified section of the program; otherwise it just continues normally.

Excessive use of Goto back and forth within a macro results in program flow that is nearly impossible for a programmer to follow if you ever share what you write or need to go back and make a change in a macro you wrote a year ago. If you have discrete sections of code that Goto goes back and forth between, that is better handled via a subroutine or a function. But I see I'm getting ahead of myself yet again, so that discussion will have to wait.

Next time, Loops...


Return to Lesson #6.
Return to Main page.

Copyright 2003, Joel A. Hahn
Sponsored and endorsed by OCLC Online Computer Library Center, Inc.