OML for the complete beginner, #7

Loops

A loop is exactly that--when the computer reaches the "end" of the loop, it loops back around to the beginning of the loop and starts over. Some loops control how many times the computer will loop (some of these can even change how many times they loop, as needed), and some have no control whatsoever.

The most basic loop 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.

(Warning: Do not try the following mini-macro without taking proper precautions! Unless you use the green arrow on the Macro Editor toolbar to run this macro (in which case you should be able to stop it at any time by using the stop button on the macro editor toolbar), it will cause CatME to crash!)

  sub main
    Dim CS as Object
    Set CS = CreateObject("CatME.Application")
    CS.GetActiveRecord
    x = 1
    Text$ = "999    Hello, world " & Str$(x)
    bool = CS.AddField(1, Text$)
  Start:
      Text$ = "999    Hello, world " &Str$(x)
      CS.SetFieldData(1, Text$)
      x = x + 1
      Goto Start
  end sub

This macro will theoretically run forever--in practice, it will run until the program locks up or the user halts the macro--endlessly finding the first line of a record and putting the text "999    Hello, world" there and a number representing the number of times the loop has executed.

Labels are usually a word or combination of words written without spaces or with underscores instead of spaces, that are the first or only thing found on a line and end with a colon. When referred to by other commands, such as Goto, the colon is left off. Labels by themselves can also be used to identify various parts of a program if you don't need to use long and involved commented explanations; this is one way to tell at a glance what a certain program block does.

This macro provides us with the most basic example of a loop--in this case, an infinite loop. When the computer reaches the Goto statement, it loops back around to the line marked "Start" and proceeds to execute each of the commands found there. Since there is no way to determine when to stop looping, it will execute an infinite number of times. However, infinite loops are extremely bad things, to be avoided at all costs outside of the classroom. It's not too difficult for an infinite loop to eat up so much of the computing resources available that CatME crashes and has to be closed down and restarted! (If there's one thing CatME and Microsoft Windows both loathe, it is infinite loops.)

If you need a loop to execute a series of commands a specific number of times, one method is to use a For...Next loop.

  sub main
  Dim CS as Object
  Set CS = CreateObject("CatME.Application")
  CS.GetActiveRecord
  For i = 1 to 10
    CS.GetFieldData(i, field$)
    CS.SetFieldData(i, field$ & " Hi there!")
  Next i
  end sub

This program puts the wors "Hi there!" at the end of each of the first ten lines of an active record. Note that it is optional to use the i with the Next statement, but it can help to keep your loops separate in your mind when you combine them:

  sub main
  Dim CS as Object
  Set CS = CreateObject("CatME.Application")
  CS.GetActiveRecord
  x = 9
  For i = 1 to x Step 2
    For j = 1 to 3
      CS.GetFieldData(i, field$)
      CS.SetFieldData(i, field$ & " " & Str(j))
    Next j
  Next i
  end sub

This program appends the numbers " 1 2 3" one by one to the end of every odd numbered line up to and including line 9. The Step part of the command tells it, in this case, to count from 1 to 9 by two's.

A For...Next loop is ok for some things, but it is only of any real use when you know in advance exactly how many times the loop must execute. It also can have serious problems if you use variables, such as the x in the above example, for anything but counting (i and j in the above example). If you redefine the counting variables with statements inside the loop, it is extremely easy to end up with a macro that simply doesn't work or, more likely, an infinite loop. As you can see, while it does have its uses, the For...Next loop isn't really all that versatile, especially when you consider its cousin, the Do...Loop statements.

  sub main
  x = 0
  Do Until x >= 10
    x = x + 1
  Loop

  y = 0
  Do
    y = y + 1
  Loop Until y >= 10

  z = 0
  Do While z < 10
    z = z + 1
  Loop
  end sub

These three loops seem to be functionally the same, but upon closer examination, some important differences come to light. The first one hits the Do statement, sees that x is less than 10, and starts executing the commands inside the loop until it does equal 10. It will execute 10 times, then skip from the Do statement to the first statement after the loop. The second goes through the entire loop once before testing whether or not to loop, at which point y will already equal 1; therefore it will only run 9 times. Also, if x = 10 and y = 9, all of the commands inside the first loop would be skipped, but all of the commands inside the second loop would execute once. The third is an alternate wording that works better in conjunction with certain other commands rather than a simple inequality, such as Do While InStr(1, a$, b$), which will loop for as long as b$ can be found somewhere within a$.

Like all loops, Do...Loops have the unfortunate tendency to easily result in infinite loops. Here is an easy mistake to make:

  x = 11
  Do Until x = 10
    x = x + 1
  Loop

Since x starts out larger than 10 and the loop only makes it bigger yet, x can never equal 10. Thus, this is an infinite loop.

However, these loops also allow a surefire method of preventing this from happening. If you think an infinite loop might be a possibility, it is best to add in an independent counting variable that does nothing but tally how many times the loop has executed.

    sub main
      x = 0 : y = 0
      Do Until x = 11
        If y >= 20 Then
          Exit Do
        End If
        x = x + 2
        y = y + 1
      Loop
      MsgBox "I made it out of the loop."
    end sub

As you can see, this loop has a problem: since it is counting x from zero by twos, it will successively equal 2, 4, 6, and so forth, and will never equal eleven. If that were all there was to the loop, the loop would go on and on, endlessly waiting for an eleven to turn up. However, we have added another variable, a "control group", as it were, to prevent that from happening. The loop statements themselves are only concerned with the value of x; however, each time the program loops, y also increases by one. When y reaches 20--that is, when the program has looped 20 times--then an Exit Do statement is executed, which automatically sends the program on to the command immediately following the Loop statement. In this case, a message box pops up showing that the program made it beyond the loop.

Next time, program flow control...


Return to Lesson #6.
Return to Main page.