DAY 6

Controlling the Flow of VBScript Code


CONTENTS


For the past two days, you've learned how to use variables and operators to assist you in creating VBScript programs. Both variables and operators are fundamental building blocks you need to understand to write useful code. Today, you will learn how to control the flow of your programs. This subject is very important when you want your programs to make on-the-spot decisions or execute differently based on what the user wants to do.

Today's lesson will introduce you to all the ways you can construct and control the order in which your code is executed. You will learn all the VBScript control structures and see several examples of how they can be applied. You will also learn which structures are more applicable and more useful under which situations. You'll learn not only how to control the flow of code, but also how best to do so.

Once you've learned how to control the flow of code within a procedure, you'll see how you can control the flow of code within the entire application. On Day 7, "Building a Home for Your Code," you will learn how to create procedures that house entire sections of code. The path of your application can flow into and out of procedures like a thread of cotton flows through a fabric. Once you've learned the useful information in today's lesson, your abilities as a VBScript programmer will bound forward to the point where you can build real-world applications from start to finish.

Why Control the Flow of Code?

Before you begin learning how to control the flow of your code, you might be wondering why you should do so in the first place. What is the "flow of code" anyway? To get this answer, you need to step back for a moment and take a look at the big picture.

Stripped of all the complex software languages and the big technical words used to describe application development, a computer program is really quite simple. A program is simply a list of instructions that a computer executes. Although we tend to give computers a lot of credit, a computer is actually quite stupid. It can only do exactly what you tell it to do; it has only a limited subset of the capabilities of the human mind without many important traits, such as the ability to draw inferences, use intuition, or use emotion to help make decisions. We humans don't fully understand these phenomena ourselves, and because a computer is a man-made machine, our computers certainly don't understand them either.

When a computer executes a list of instructions, it executes them one at a time in the order it is told. Depending on the type of computer and the language of the program, some computers can jump around a list of instructions if told to do so. For example, the computer might be told to execute instructions in the following order:

a
b
c
d
e
f
g

Perhaps it is told to execute them in an order like this:

a
b
f
g
c
d
e

That same computer might even be able to execute a series of instructions over and over again:

a
b
c
d
e
d
e
d
e
f
g

As you can see, each of these three paths through the code is different. The computer doesn't care what order of instructions it is given. You, on the other hand, might care a great deal. For the most part, you, the programmer, dictate the order instructions are executed on a computer. At times, you might want to execute the same instructions over again. Suppose, for instance, you have to ask the user for a set of data again because he didn't enter the data correctly the first time.

Other times, you might need to make a decision in your program to execute one line of code under one condition and another line of code in some other condition. For instance, you might need to calculate the sales tax of an item differently if the user enters California instead of Michigan as his state.

In both cases, depending on the user, your code can execute in a different order each time. As you can see, it is very important, if not fundamental, that you have this capability in your programs. That's why knowing how to control the flow of your code is important.

Using Control Structures to Make Decisions

With that brief explanation in mind, how do you control how your code executes? Fortunately, VBScript gives you a variety of ways to direct the flow of your code. The mechanisms used to accomplish this in VBScript are called control structures. They are called structures because you construct your code around them, much like you build and finish a house around its structure. Control structures are like the wood beams and boards in your house that all of your rooms are built upon. You can use each control structure to make your code travel in different ways, depending on how you want the decision to be made. In this section, you will learn about the two control structures used in VBScript to make decisions. Later, you will see the structures used to make code repeat based on criteria you specify.

A control structure is a combination of keywords in code used to make a decision that alters the flow of code the computer executes.

If…Then

The first control structure you should know about is If…Then. The syntax for this control structure is given as

If condition = True Then
     ... the code that executes if the condition is satisfied
End If

where condition is some test you want to apply to the conditional structure. If the condition is true, the code within the If and End If statements is executed. If the condition is not true, the code within these statements is skipped over and does not get executed.

Note
Rather than using this expression:
If condition = True
you can simply use this expression:
If condition Then
instead. VBScript automatically checks to see if the condition is true if you don't explicitly say so. Similarly, if you wanted to check to see if an expression were false, you could check to see if the condition is equal to false:
If condition = False
or you could have VBScript check the not true condition:
If Not condition
This convention may be used interchangeably throughout the book.

How might this work? Suppose you have a Boolean variable named ShowDetails. This variable is set to True at some point in your code if the user wants to see the specific details of a tax calculation your code has made in figuring out your user's taxes. You could set up a simple conditional statement that gives the user the help he or she needs by entering

If ShowDetails = True Then
    ...code that shows the details of the calculation to the user
End If

This way, if the user doesn't want to see the details and the variable hasn't been set previously, the code in between the two statements is ignored. The condition expression is typically ome test, such as whether one variable is equal to another or whether a variable equals a certain value. The condition always comes out either True or False, but the conditional structure only executes the code within it if the condition is True. When using an If…Then structure, make sure your condition is expressed properly. The code contained within the expression

If 5 = 5 Then
   ...some code that executes if the condition is true
End If

will always get executed because 5 always equals 5. Likewise, the code within the expression

If 5 = 10 Then
   ...some code that executes if the condition is true
End If

will never get executed because 5 never equals 10. These decision structures are pointless because the decision never changes. When you enter the condition for an If…Then control structure, you should always make the condition one that could either be True or False.

Listing 6.1 shows a working example of VBScript code that uses the If…Then conditional. This Web page, named ifthen.htm, is also on the CD-ROM that accompanies the book.


Listing 6.1. A Web page that uses the If…Then control structure.
<HTML>

<HEAD>
<TITLE>Brophy & Koets' Teach Yourself VBScript - If-Then Sample</TITLE>
</HEAD>

<BODY>

<H1><A HREF="http://www.mcp.com"><IMG  ALIGN=BOTTOM
SRC="../shared/jpg/samsnet.jpg" BORDER=2></A>
<EM>Using the If-Then Statement</EM></H1>

<HR>

<P>Enter your age and click on the "Evaluate" button.  Visual Basic
Script will use the If-Then conditional to show a message depending on
the age you enter.

<PRE>
I am <INPUT NAME="txtAge" SIZE=10 > years old.   --
<INPUT TYPE="BUTTON" VALUE="Evaluate" SIZE=30 NAME="cmdEvaluate">
</PRE>

<HR>

<center>
from <em>Teach Yourself VBScript in 21 Days</em> by
<A HREF="../shared/info/keith.htm">Keith Brophy</A> and
<A HREF="../shared/info/tim.htm">Tim Koets</A><br>
Return to <a href="..\default.htm">Content Overview</A><br>
Copyright 1996 by SamsNet<br>
</center>

<SCRIPT LANGUAGE="VBScript">
<!--  Option Explicit

   Sub cmdEvaluate_OnClick()

      Dim Age

      Age = CInt(txtAge.Value)

      If Age <= 0 or Age > 120 Then
         MsgBox "Either you're not born yet or you're getting
             too old for this stuff!"
      Else
         MsgBox "You are " & Age & " years old."
      End If

   End Sub

-->
</SCRIPT>

</BODY>
</HTML>

This listing is for a Web page that takes as an input the user's age. When the user clicks the Test button, the conditional statement checks to see whether the user's age is valid. If the person enters zero, a negative number, or a value greater than 120, he is either the world's oldest VBScript user or he has made a mistake in entering his age, and a message box appears on the screen telling him so. Figure 6.1 shows the Web page.

Figure 6.1 : A simple Web page with an If...Then conditional structure.

Notice that the condition takes advantage of the logical Or operator that you learned about on Day 5, "Putting Operators to Work in VBScript." If you don't remember how the Or operator works, you might want to take a look back at Day 5 to refresh your memory.

If…Then…Else

Now you know how to make a simple decision in VBScript. The If…Then structure is quite useful, but it has one limitation. Oftentimes, when people make decisions, they want to do one thing if a condition is true; otherwise, they want to do something different. For example, you may have imagined a simple decision structure in your mind that if Cardboard Burger World is open, you will go there to eat. Otherwise, you will go home and cook your own meal. You're certain to carry out either one of the two options because you're hungry, it's time for dinner, and hey-you deserve it after an afternoon of programming.

Apply this decision process to some code. Assume you had a variable that was previously set to indicate the state of whether Cardboard Burger World is open or closed based on the time a script is run. You want to have your code check this variable and put up a message box to let you know whether you can hit Cardboard Burger World. In this case, you wouldn't want to use the logic

If CardboardBurgerWorldOpen = True Then
   Msgbox "Go To CardboardBurgerWorld!"
End If

because that leaves out the alternative. You could use two statements:

If CardboardBurgerWorldOpen = True Then
   Msgbox "Go To CardboardBurgerWorld!"
End If
If CardboardBurgerWorldOpen = False Then
   Msgbox "Go Home and Cook!"
End If

but wouldn't it be nice if you didn't have to repeat the test where you check the negative instead of positive condition? This seems somewhat cumbersome. Fortunately, you have another control structure available to you in VBScript that makes this process easier. The control structure, called If…Then…Else, is represented as

If condition = True Then
    ...this is the code that executes if the condition is satisfied
Else
    ...this is the code that executes if the condition is not satisfied
End If

You could enter the expression you've formed in your mind as you drive toward Cardboard Burger World as

If CardboardBurgerWorld = True Then
    Msgbox "Go To CardboardBurgerWorld!"
Else
    Msgbox "Go Home and Cook!"
End If

This is certainly much simpler to understand, and it's equally helpful when writing your programs. Suppose your Web page gives the user the option of whether he wants the results of a calorie and fat counting Web page in calories or grams of fat. If you had a Boolean variable that was set to True if the user wanted the food item calculated in calories, you could use the expression

If Calories = True Then
    ...show the user the food in calories
Else
    ...show the user the food in fat grams
End If

where Calories is the variable that determines whether the user wants the result in calories. Notice that if the user doesn't want the result in calories, the only other case is fat grams.

What if you had a few other cases you wanted to test? You're in luck: You can do as many tests as you want by simply placing more ElseIf statements between the first If statement and the End If statement. The syntax of such a structure looks like this:

If condition1 = True Then
   ...the code that executes for condition1
ElseIf condition2 = True Then
   ...the code that executes for condition2
ElseIf condition3 = True Then
   ...the code that executes for condition3
End If

where you can have as many ElseIf statements as you want. Suppose that the same user wants to view the results of food intake in calories, fat grams, or total percentage of USRDA fat intake for the day. If you had the variables Calories, Fat_Grams, and Fat_Percent in your code, you could use the following expression to fill in the appropriate code to show the results to the user as well:

If Calories = True Then
    ...code to show the user the food in calories
ElseIf Fat_Grams = True Then
    ...code to show the user the food in fat grams
Else
    ...code to show the user the food in percentage fat intake
End If

A few comments are in order about this conditional structure. Notice that only one of the conditions can be true. If you want to execute code for more than one of these conditions, you cannot use this control structure. In other words, this structure can only execute one of the conditions. Once it finds the first condition in the list that is true, it executes the code off that branch and ignores all the rest. Even if Calories was equal to true and Fat_Grams was also equal to True, only the first true condition-in this case, the calories-would get executed. For most kinds of problems, you want to make sure that only one of your conditions is true or else they are all false. That is the second important point to consider. You don't have to include the last Else in your statement. You could just as easily have entered

If Calories = True Then
    ...show the user the food in calories
ElseIf Fat_Grams = True Then
    ...show the user the food in fat grams
End If

This would work fine as long as either Calories or Fat_Grams were equal to true. What if the user didn't specify which one and both variables were set to false? In that case, neither would get executed and the user wouldn't see anything. You have to be careful how you use these structures. If the logic of your problems demands that at least some action take place for a given condition, either make sure one of the two variables is set to true before you perform these tests, or be sure to provide an Else conditional at the end. The Else at the end will et executed if none of the other conditions is true. The Else condition acts as a fallback position just in case none of the other conditions is true. This might be valuable to you in cases where you want to make sure something happens in the conditional structure. After all, when you write code, it's best to take all possibilities into consideration; you never know when a pesky bug might enter or some unforeseen condition might take place, and you wouldn't want it to mess up your code.

Figure 6.2 shows a simple example of the If…Then…Else control structure. Here, you see a Web page that asks you for your age, just like the first example. Only this time, rather than perform one check, this Web page tests a variety of conditions and responds differently to each one.

Figure 6.2 : A simple Web page with an If...Then...Else conditional structure.

Listing 6.2 shows the code for this Web page, named iftelse.htm, which is also on the CD-ROM.


Listing 6.2. A Web page that uses the If…Then…Else control structure.
<SCRIPT LANGUAGE="VBScript">
<!--  Option Explicit

   Sub cmdTest_OnClick()

      Dim Age

      Age = CInt(txtAge.Value)

   If Age = 0 Then
      MsgBox "Welcome to the human race!"
   ElseIf Age < 0 Then
     MsgBox "We hate to say this, but you have to grow up
        a bit before you start using VBScript!"
   ElseIf Age > 0 and Age < 10 Then
     MsgBox "If you're bold enough, you must be old enough."
      ElseIf Age > 120 Then
          MsgBox "You're getting too old for this stuff!"
      Else
          MsgBox "You're at the perfect age to get started!"
      End If

   End Sub

-->
</SCRIPT>

In this case, you see that you can do more specific checks for various age groups and even provide an Else clause for the default case. You couldn't do that using If…Then statements unless you want to write a lot of excess code.

The If…Then and If…Then…Else control structures give you the ability to control the flow of your code based on decisions made within your code. These two structures are very important and are used throughout the book. Now look at the other structures available for your use.

Select Case

In the previous section, you saw how to use the If…Then and If…Then…Else conditional structures. In Listing 6.2 you saw an example in which five tests were made within this structure. In this case and cases where you have to perform a large number of tests on the same expression, you can instead use the Select statement. The Select statement often makes your code easier to read and interpret than would a long list of Else and Else If statements. The Select Case structure is defined as follows:

Select Case test_expression
    Case expression-1
       ...this is the code that executes if expression-1 matches test_expression
    Case expression-2
       ...this is the code that executes if expression-2 matches test_expression
    Case expression-3
       ...this is the code that executes if expression-3 matches test_expression
    .
    .
    .
    Case Else n
       ...this is the code that executes if expression-n matches test_expression
End Select

expression-1, expression-2,and expression-3 are one or more expressions that must match test_expression in order for the code below each Case statement to execute. As you can see, the same condition is evaluated throughout the structure. Only one case is executed when VBScript travels through. If more than one case matches, only the first one is executed. If none of the cases match, the code underneath the Case Else section is executed. The Case Else section is optional. However, VBScript won't do anything if none of the cases match.

Consider an example in which you want to print a message to the user based on what state the user lives in. The code may look like this:

Select Case State
   Case "Michigan"
            Message = "Michigan is a wonderful state to visit if you enjoy
                       fresh-water lakes."
     Case "Virginia"
      Message = "Visit the Commonwealth for a wide variety of historical
                 landmarks and beautiful mountain-scapes."
   Case "Arizona"
      Message = "Arizona is a wonderful getaway for those who love heat with
low humidity"
      Case "Colorado"
          Message = "Colorado is almost unsurpassed for its majestic mountains
and rivers."
     Case Else
      Message = "No specific information is available about this state."
End Select

There may be times when you have more than one expression in which you would like the same code to be executed. For example, you might want to provide the same message for Michigan and Minnesota. Rather than entering the code as this:

Select Case State
   Case "Michigan"
      Message = "A wonderful state to visit if you enjoy fresh-water lakes."
   Case "Minnesota"
      Message = "A wonderful state to visit if you enjoy fresh-water lakes."
   Case "Virginia"
      Message = "A wide variety of historical landmarks and beautiful mountains
                 make this a terrific state to live."
   Case "Arizona"
      Message = "A wonderful getaway for those who love heat with low humidity."
   Case "Colorado"
      Message = "Virtually unsurpassed for its majestic mountains and rivers."
   Case Else
      Message = "No specific information is available about this state."
End Select

which requires you to duplicate code, you can instead combine the two cases together as shown:

Select Case State
   Case "Michigan"
   Case "Minnesota"
      Message = "A wonderful state to visit if you enjoy fresh-water lakes."
   Case "Virginia"
      Message = "A wide variety of historical landmarks and beautiful mountains
                        make this a terrific state to live."
   Case "Arizona"
      Message = "A wonderful getaway for those who love heat with low humidity."
   Case "Colorado"
      Message = "Virtually unsurpassed for its majestic mountains and rivers."
   Case Else
      Message = "No specific information is available about this state."
End Select

To see an example of the Select Case structure in action, consider an example in which the user wishes to find out where the closest car dealership is in her state based on her area code. The example shown in Figure 6.3 shows the Web page to carry this out.

Figure 6.3 : A simple Web page that uses the Select Case structure.

The code for this Web page, named select.htm, is shown in Listing 6.3.


Listing 6.3. A Web page that uses the Select control structure.
<HTML>

<HEAD>
<TITLE>Select Case Sample</TITLE>
</HEAD>

<BODY>

<H1><A HREF="http://www.mcp.com"><IMG  ALIGN=BOTTOM
SRC="../shared/jpg/samsnet.jpg" BORDER=2></A>
<EM>Using the Select Case Structure</EM></h1>

<HR>

<P>Enter your area code and click the 'Check' button.  VBScript will
determine the closest dealership nearest you.

<PRE>
<INPUT NAME="txtAreaCode" SIZE=5 >    <INPUT TYPE="BUTTON" VALUE="Check"
SIZE=30 NAME="cmdCheck">
</PRE>

<HR>

<center>
From <em>Teach Yourself VBScript in 21 Days</em><BR>
By <A HREF="../shared/info/keith.htm">Keith Brophy</A> and
<A HREF="../shared/info/tim.htm">Tim Koets</A><br>
<BR>
Return to <a href="back06.htm">Content Overview</A><br>
Copyright 1996 by SamsNet<br>
</center>

<SCRIPT LANGUAGE="VBScript">
<!--  Option Explicit

   Sub cmdCheck_OnClick()

      Dim AreaCode
      Dim DealerLocation

      ' Make sure user has supplied input
      if Not IsNumeric(txtAreaCode.Value) then
         msgbox "You must supply an area code!",0,"No area code given"
         exit sub
      end if

      AreaCode = CInt(txtAreaCode.Value)

      Select Case AreaCode

         Case 616
            DealerLocation = "Grand Rapids"

         Case 313
            DealerLocation = "Detroit"

         Case 517
            DealerLocation = "Lansing"

         Case 810
            DealerLocation = "Pontiac"

         Case 906
            DealerLocation = "Marquette"

         Case Else
            DealerLocation = "unknown"

      End Select

      MsgBox "The closest dealership to you is in " & DealerLocation

   End Sub

-->
</SCRIPT>

</BODY>

</HTML>

As you can see in Listing 6.3, the area code is first obtained from the user. A check is made to ensure that an area code has been supplied. Then, the Select structure performs various checks on the Michigan area codes to determine the closest city within that area code in which a dealership resides. If the user enters an unknown area code, the response string "unknown" is provided as a default.

It is generally a good idea to provide a default selection in the Select Case structure because it never hurts to expect the unexpected. Also keep in mind that you can nest Select Case structures if you wish, provided the correct syntax of Select Case and End Select are maintained.

Note
A Case can consist of a range of values separated by commas. For example, this statement matches for the area codes 616 or 517:
Select Case AreaCode
case 616, 517
DealerLocation = "Lower Michigan"
The Case statements can only work on discrete values (distinct values as opposed to symbolic values such as variables or conditional statements). You cannot provide conditional checks within a case statement. For example, this syntax is not legal:
Select Case MyVar
Case MyVar > 10 and MyVar < 25
In cases such as this, you must often rely on multiple checks with the If…Then…ElseIf if the Select Case structure can't be constructed to handle the expected range of values.

Using Control Structures to Make Code Repeat

On occasion, you will need to write code that repeats some set of statements. Oftentimes, this will occur when you need to perform some calculation over and over or when you have to apply the same calculations or processing to more than one variable, such as changing the values in an array. This section shows you all the control structures you can use in VBScript to control code in your program that repeats.

For…Next

The first structure is often referred to as the For…Next loop. The syntax for this structure is

For counter = start to finish
   ...code that gets repeated
Next

where counter is a variable used for counting purposes that begins at the number specified by the start variable and counts up by one, each time executing the code within the structure, until it reaches finish. Usually, counter is incremented by one each time through the loop, although you can change the value of the increment. I'll show you how to do this in a moment, but first, check out the For…Next loop in action.

Suppose you have an array called Salaries that contains 30 elements, and you want to set all these elements to a value of 30,000. One way to do this is to enter the code

Salaries(0) = 30000
Salaries(1) = 30000
Salaries(2) = 30000
.
.
.
Salaries(29) = 30000

If you did it this way, you would have to enter thirty lines of code. Rather than go through all that work, however, you have a much easier way. In this case, you're repeating the same operation thirty times, but each time, you're assigning the value to a different element in the array. Instead, try entering the following code:

For i = 0 to 29
   Salaries(i) = 30000
Next

You've reduced the code to three lines. Quite a savings! What does VBScript do when it encounters this loop? The first thing it does is assign the counter variable, i, with the start value, or 0. Then, it executes the statement within the loop. In this case, the statement within the loop makes use of the counter variable. Because the first time inside the loop i has a value of 0, the statement

Salaries(0) = 30000

is effectively executed because i = 0. After that, VBScript executes the Next statement, which sends it back to the top where i is incremented. The counter variable then becomes 1 rather than 0. Once VBScript increments the counter variable, it checks to see if the counter variable is greater than the finish value, in this case, 29. Because i = 1 and the finish value is 29, i is still within range, so the loop continues. This time, the statement inside the loop effectively becomes

Salaries(1) = 30000

Then, the loop repeats, and i gets incremented to 3, and because 3 is less than or equal to 29, the process continues. In fact, the code inside the loop will be executed again and again until i equals 30. Once i is incremented beyond the finish value, the loop will end, and VBScript will advance past the Next statement. The end result is that every element of the array Salaries from element 0 to element 29 will be set with the value 30000.

The For…Next loop is quite flexible because you can tell VBScript how much you want the counter variable to be incremented each time through the loop. You can also decrement the counter rather than increment it. How do you do this? The counter is incremented by a value of 1 each time through the loop unless you specify otherwise. You can do so through the use of the Step keyword like this:

For counter = start to finish Step increment
   ...code that gets repeated
Next

where increment is a variable or value that tells the loop how much to increment the counter each time through the loop. As before, the moment counter falls outside the range of start and finish, the loop will stop. Suppose you wanted to set every third salary at 30,000 rather than every one of the salaries. You could write the loop as

For i = 0 to 29 Step 3
   Salaries(i) = 30000
Next

Here, i will equal 0, 3, 6, 9, 12, and so on, right up to 27. Each time through the loop, i gets incremented by 3. When i is set to 30, it exceeds the range of the loop and the loop stops. This loop effectively executes the following statements

Salaries(0) = 30000
Salaries(3) = 30000
Salaries(6) = 30000
Salaries(9) = 30000
Salaries(12) = 30000
Salaries(15) = 30000
Salaries(18) = 30000
Salaries(21) = 30000
Salaries(24) = 30000
Salaries(27) = 30000

If you wanted to move down the array from 29 to 0 rather than up from 0 to 29, you could have written the loop like this:

For i = 29 to 0 Step -3
   Salaries(i) = 30000
Next

Before you see an example of the For…Next structure, you need to keep in mind a few important rules. VBScript is fully dependent on you to tell it how many times you want to execute the loop. As you read earlier today, computers do exactly as they're told, even if they're told to do something that doesn't make any sense. If you tell VBScript to execute a loop forever, it will go off happily in that direction-that is, until you stop the program from running, the computer runs out of memory, or some kind of an error occurs. How could this happen? Consider the following code loop:

For i = 1 to 10 Step 0
   Salaries(i) = 30000
Next

Because the increment value is set to 0, the counter variable will never change, and the loop will spin its wheels forever. This is often called an infinite loop. You might be thinking to yourself, "I'd never be crazy enough to write something like that." Of course not, but you could do it by accident or have a loop like this:

For i = 1 to 10 Step Change
   Salaries(i) = 30000
Next

where Change somehow fails to get set in your code and takes on the value of 0. The point is that accidents do happen when you're writing code. Even the most expert programmer can fall prey to such a simple error.

One comforting thought about infinite loops is that most browsers will detect that no activity is happening in a script when an infinite loop is taking place. Internet Explorer puts up a message box stating, "This page contains a script which is taking an unusually long time to finish. To end this script now, click Cancel." This enables the user to interrupt a page in an infinite loop and get on with using the browser. Regardless, infinite loops are evil, and you obviously don't want your users to find them within your Web pages.

When you construct loops, make sure they always have the correct range and they're counting in the right direction. You should never, for example, write a loop like this:

For i = 1 to -5
   Salaries(i) = 30000
Next

This loop wouldn't work because the counter variable i cannot move from 1 to -5 in positive increments. VBScript checks the starting and ending values to determine whether it can get there using the step value. In this case, VBScript knows it cannot get from 1 to -5 with a step value of 1. As a result, the loop never executes. You can avoid all these problems if you follow these simple rules:

If you make sure your code follows these simple rules, you'll avoid all the trouble I've discussed.

If you ever want to break out of a loop, such as when an error occurs, you can use the Exit For statement. Usually, you break out of a loop because of a problem or some exception. Consider Listing 6.4.


Listing 6.4. Exiting a For…Next loop.
For I = 1 to 10
   Response = MsgBox("Would you like to continue adding
             the salaries?", 4)
   If Response = 6 Then user clicks Yes
       Result = Result + Salaries(I)
   Else
       Exit For
   End If
Next

In this case, as long as the user keeps clicking the Yes button when asked, the loop will continue through to completion. If the user clicks No for any reason, however, the loop will stop prematurely.

Take a look at a sample Web page that uses the For…Next loop. Figure 6.4 shows the Web page named golfavg.htm, which is on the CD-ROM.

Figure 6.4 : A Web page that uses the For...Next structure.

As you can see from the figure, you can use the Web page to calculate a golfer's average score. The page consists of two text fields: the first to enter the scores and the second to display the average. The Web page also contains two command buttons labeled Next and Finished. The user can enter up to ten scores, clicking on Next to log each successive score. Then, when the user has entered all the scores, he simply clicks the Finished button and the average is calculated. Listing 6.5 shows the code for this Web page.


Listing 6.5. Using the For…Next statement in a Web page.
<SCRIPT LANGUAGE="VBScript">
<!--  Option Explicit

   Dim Count
   Dim Scores(10)

   Count = 0

   Sub cmdNext_OnClick()

      Dim Score
      Dim i

      Score = CSng(txtScore.Value)

      If Count > 9 Then
         MsgBox "You can only enter up to 10 scores.  Click the Finished
                 button to calculate the average."
      Else
           Scores(Count) = Score
           Count = Count + 1
           txtScore.Value = ""
      End If

   End Sub

   Sub cmdFinished_OnClick()

      Dim Average
      Dim Sum
      Dim i

      For i = 0 to Count-1
          Sum = Sum + Scores(i)
      Next

      Average = Sum / Count
      txtAverage.Value = Average

      Count = 0

   End Sub

-->
</SCRIPT>

As you can see, the example creates a script-level array so that both procedures can access the array of scores. The count, which stores the number of values the user actually entered, is also script level in scope because the procedure that does the averaging needs to know how many valid values have been entered. Armed with this information, the procedure enters a For…Next loop where the counter, i, ranges from 0 to Count - 1 to cover the number of values the user has entered. The loop adds up all the scores, which are divided after the loop to obtain the average score.

Notice that if the user never enters a score and just clicks the Finished button without entering data, the loop would take the form

For i = 0 to -1
   Sum = Sum + Scores(i)
Next

In this case, the loop would never execute. More dangerous, however, is the fact that the variable Count would have a value of zero, and when the average was taken using the expression

Average = Sum / Count

the Sum and Count would both be 0. This would result in a run-time, divide-by-zero error. To prevent this, you might want check for this condition and alert the user if he entered no data. Listing 6.6 shows a revised version of the program that makes sure this error could never occur.


Listing 6.6. Using the For…Next statement in a Web page with additional error-checking to prevent a divide-by-zero error.
<SCRIPT LANGUAGE="VBScript">
<!-- Option Explicit

   Dim Count
   Dim Scores(10)

   Count = 0

   Sub cmdNext_OnClick()

      Dim Score
      Dim i

      Score = CSng(txtScore.Value)

      If Count > 9 Then
         MsgBox "You can only enter up to 10 scores.  Click the Finished
                 button to calculate the average."
      Else
           Scores(Count) = Score
           Count = Count + 1
           txtScore.Value = ""
      End If

   End Sub

   Sub cmdFinished_OnClick()

      Dim Average
      Dim Sum
      Dim i

      If Count = 0 Then
         MsgBox "You must enter some scores before they can be averaged."
         Exit Sub
      End If


      For i = 0 to Count-1
          Sum = Sum + Scores(i)
      Next

      Average = Sum / Count
      txtAverage.Value = Average

      Count = 0

   End Sub

-->
</SCRIPT>

You will learn more about error checking and debugging your programs on Day 17, "Exterminating Bugs from Your Script."

Do…Loop

The next conditional structure discussed in this lesson is the powerful Do…Loop structure. This section discusses each of the four variations of the Do…Loop that you can use.

Do While…Loop

The first loop structure you can use is the Do While…Loop structure. The basic syntax for this structure is

Do While condition
   ...code within the loop goes here
Loop

where the condition is either true or false. As long as the condition is true, the code within the loop gets executed. Once the condition becomes false, the loop stops and the code after the loop is executed. The only way for the program to break out of the loop is if the condition becomes false or if an Exit Do statement is encountered somewhere inside the loop. Consider the following example shown in Listing 6.7.


Listing 6.7. Using the Do While…Loop conditional structure.
Again = True
DoubleIt = 1

' Keep doubling the number as long as the user desires
Do While Again = True

       '  Show current results and prompt to see if we should continue

       If MsgBox("Current total is " & DoubleIt & ". Double it again ?",
             vbYesNo) = vbYes Then
          DoubleIt = DoubleIt * 2
       Else
          Again = False
       End If

Loop

In this example, the first line of code sets the variable that gets tested in the loop equal to true. The second line sets the variable that gets doubled in the code equal to one. Setting the loop variable equal to true allows the loop to get off and running because the third line says, "If Again is true, enter the loop." Because the variable has just been set to true, the loop begins. The first statement in the loop displays the result to the user. Because nothing has been doubled yet, the result is one-the initial value of the DoubleIt variable.

When the results are displayed, the user is asked if he wants to continue. If he chooses to go forward, the variable DoubleIt is multiplied by two. When the program hits the Loop instruction, it will return to the top of the loop and once again check to see if the condition is set to true. Because the condition has not changed, the loop executes again. It will continue to execute until the user chooses not to continue. Once that happens, the variable Again is set to False. Now, when Loop is reached, the code swings back up to the top of the loop and evaluates the condition once more. This time, the condition is false, so the loop does not execute again. The code moves on beyond the loop.

You can see an example of the Do While…Loop in action in a slightly revised golf average example. Here, the user once again enters golf scores to average them, but this time, things are handled a bit differently. Figure 6.5 shows the Web page, which is stored as golfdwlp.htm.

Figure 6.5 : A Web page that uses the Do While...Loop structure.

In this example, the user simply clicks the Get Golf Scores button, which proceeds to ask the user for a score using a special function called InputBox. We discuss this function in detail on Day 14, "Working with Documents and User Interface Functions." For now, just think of this function as a box where you put in a message for the user and out comes whatever he's entered in the box. If the user doesn't enter anything at all when the input box appears on the screen, the function returns an empty string, or "". The page shown in Figure 6.5 is asking the user for golf scores. Listing 6.8 shows the code that accomplishes this.


Listing 6.8. A Web page that uses the Do While…Loop structure.
<SCRIPT LANGUAGE="VBScript">
<!--  Option Explicit

Sub cmdGetScores_OnClick()

   Dim Count
   Dim Scores(10)
   Dim Score
   Dim Average
   Dim Sum
   Dim i

   Score = 0

   Do While Score <> "" And Count < 10
      Score = InputBox("Enter the next golf score
                        (Press Return to quit): ")
      If Score <> "" Then
         Count = Count + 1
         Scores(Count-1) = CSng(Score)
      End If
   Loop

   For i = 0 to Count-1
      Sum = Sum + Scores(i)
   Next

   Average = Sum / Count

   txtAverage.Value = Average

   Count = 0

End Sub

-->
</SCRIPT>

As you can see, the loop in this listing continues to ask the user for scores until the user doesn't enter anything or he's reached the ten score limit. At that point, the loop condition is no longer true and the average is calculated and displayed to the user. Notice that the score must be set to 0 before the loop begins, otherwise the expression

Score <> ""

would be false and the loop would never execute. In the next section, you will see a way to implement the program without that extra line of code.

The best way to exit from a Do…Loop is to make the condition false as you did in the previous listing. Sometimes, however, you might have to exit a function due to an error or some other factor that must pull you out of a loop. In that case, you can use the Exit Do statement, and VBScript will take you to the next statement below the loop.

Do…Loop While

In the Do While…Loop construct example shown previously, the condition that determined whether you stayed in the loop was a variable that had to be true. Notice that the code in Listing 6.5 first checks the conditional test before it enters the loop. You had better be sure to set the condition variable to true outside the loop before it starts. Otherwise, you have no way of making sure the variable Again was set to true before the loop began. If it had never been set or were set to False, the code inside the loop would never get executed.

Sometimes, it is more desirable to put the conditional test at the bottom of the loop rather than the top. You can accomplish this using the Do…Loop While structure. This control structure takes the form

Do
   ...code within the loop goes here
Loop While condition

As you can see, the only difference is that the condition is tested after the code inside the loop is executed. What difference does this make? Only this: The loop always executes at least one time because it doesn't test for the condition until after it's gone through the loop once. Then, at the end, it performs the test. If you want your loop to execute at least once regardless of the condition (the condition isn't even considered the first time through the loop), this is the structure to use. If you don't even want the loop to execute unless the condition is true first, use the Do While…Loop structure.

Listing 6.9 shows an example using the Do…Loop While structure.


Listing 6.9. Using the Do…Loop While conditional structure.
DoubleIt = 1

' Keep doubling the number as long as the user desires
Do
       '  Show current results and prompt to see if we should continue
       If MsgBox("Current total is " & DoubleIt & ". Double it again ?", _
             vbYesNo) = vbYes Then
   DoubleIt = DoubleIt * 2
          Again = True
Else
          Again = False
       End If

Loop While Again = True

Notice that you have to make sure that the test variable Again gets set one way or the other within the loop. In this case, you can be sure the user will move through the loop at least once. The code is a bit easier to read and understand. In some cases, you might have other conditions where you want to execute the loop at least once and then decide to execute it again. In other cases, you will want to do the test before running anything within the loop. It depends on the application, but both control structures are available for your use.

Consider once more the golf score Web page. In the last section, you used Do While…Loop to accomplish the task. Listing 6.10 points out that you can write the code a bit better using Do…Loop While. The revised Web page called golfdwlp.htm is on the CD-ROM that accompanies the book.


Listing 6.10. A Web page that uses the Do…Loop While structure.
<SCRIPT LANGUAGE="VBScript">
<!--  Option Explicit

   Sub cmdGetScores_OnClick()

      Dim Scores(10)
      Dim Score
      Dim Average
      Dim Sum
      Dim i

      Do
         Score = InputBox("Enter the next golf score
                          (Press Return to quit): ")
         If Score <> "" Then
             Count = Count + 1
             Scores(Count-1) = CSng(Score)
         End If
      Loop While Score <> "" And Count < 10

      For i = 0 to Count-1
         Sum = Sum + Scores(i)
      Next

      Average = Sum / Count

      txtAverage.Value = Average

      Count = 0

   End Sub

-->
</SCRIPT>

Here, you guarantee the user will be asked for at least one score, and you don't have to worry about making sure the variable is equal to zero before you enter the loop. The Do…Loop While appears to be the better choice.

Do Until…Loop

The third type of Do…Loop is the Do Until…Loop structure. This is very similar to the Do While…Loop except that rather than perform the operations within the loop while the condition is true, it executes the operations inside the loop until the condition is true. If you think about this slight twist of logic for a moment, this will make some sense to you. To help, I'll use a familiar real-life analogy.

Suppose that your father wants you to clean out the garage until he cuts the grass. Using your logical, programming model of reality, you take this to mean that the only time you have to clean out the garage is until he gets outside and starts up the mower. Once he starts cutting the grass, you're outta there. You breathe a big sigh of relief when he walks out to the shed to start cutting the grass. Just before you escape out the back for the baseball diamond, however, your mother notices you. To your horror, she tells you that she wants you to clean out the garage while your father cuts the grass. Before, you only had to clean the garage until your dad started mowing the lawn. Now, you've got to slave away in the garage until he's done! What a life!

Besides the fact that you've got to do more work, can you see the difference? When you're constructing loops, you can set up the same kind of decision-making process. The Do Until…Loop structure takes the form

Do Until condition
   ...code within the loop goes here
Loop

where the code within the loop will only get executed until the condition becomes true. As long as the condition is false, the code in the loop will continue to be executed. Consider the result display implementation in Listing 6.8. What would that implementation look like using Do Until…Loop instead of Do While…Loop? Listing 6.11 provides the answer.


Listing 6.11. Using the Do Until…Loop conditional structure.
Again = True
DoubleIt = 1

' Keep doubling the number as long as the user desires
Do Until Again = False
       '  Show current results and prompt to see if we should continue
       If MsgBox("Current total is " & DoubleIt & ". Double it again ?", _
                 vbYesNo) = vbYes Then
   DoubleIt = DoubleIt * 2
Else
          Again = False
       End If

Loop

As you can see from the listing, rather than execute the loop while Again is true, this loop executes until Again is false. Because the logic has changed, you must change the test of Again from true to false to make the loop equivalent to the previous one.

You can also use the familiar golf score Web page to illustrate this loop structure. Listing 6.12 shows the revised Web page, which is also on the CD-ROM as golfdulp.htm.


Listing 6.12. A Web page that uses the Do Until…Loop structure.
<SCRIPT LANGUAGE="VBScript">
<!--  Option Explicit

   Sub cmdGetScores_OnClick()

      Dim Count
      Dim Scores(10)
      Dim Score
      Dim Average
      Dim Sum
      Dim i

      Score = 0

      Do Until Score = "" Or Count > 9
          Score = InputBox("Enter the next golf score
                           (Press Return to quit): ")
          If Score <> "" Then
              Count = Count + 1
              Scores(Count-1) = CSng(Score)
          End If
      Loop

      For i = 0 to Count-1
          Sum = Sum + Scores(i)
      Next

      Average = Sum / Count

      txtAverage.Value = Average

      Count = 0

   End Sub

-->
</SCRIPT>

Here, the logic of the loop changes a bit. Rather than loop while the scores are coming in, the program loops until the scores stop coming in. Also notice that you have to make sure Score equals zero before the loop starts because you check for its value before the code inside the loop begins.

Do…Loop Until

If you want to defer the decision in the loop to the end, you can use the Do…Loop Until structure. This takes on the form

Do
   ...code within the loop goes here
Loop Until condition

In this case, you're certain that VBScript will go through the loop at least one time, and the test takes place after that first iteration through the loop. From that point on, until the condition becomes true, the loop will continue to execute.

Take a look at the golf score Web page once again. As before, the code would read a bit better if you put the condition at the end of the loop rather than the beginning. Listing 6.13 shows how that is accomplished with the code named golfdulp.htm.


Listing 6.13. A Web page that uses the Do…Loop Until structure.
<SCRIPT LANGUAGE="VBScript">
<!--  Option Explicit

   Sub cmdGetScores_OnClick()

      Dim Count
      Dim Scores(10)
      Dim Score
      Dim Average
      Dim Sum
      Dim i

      Do
         Score = InputBox("Enter the next golf score (Press Return to quit): ")
         If Score <> "" Then
            Count = Count + 1
            Scores(Count-1) = CSng(Score)
         End If
      Loop Until Score = "" Or Count > 9

      For i = 0 to Count-1
         Sum = Sum + Scores(i)
      Next

      Average = Sum / Count

      txtAverage.Value = Average

      Count = 0

   End Sub

-->
</SCRIPT>

Of all the possible loop structures examined today, this one is probably the best for the golf score Web page. It accomplishes the task, yet it's easy to read and understand. As you see, any of the control structures in this section could work with this page. How do you know which is best to choose? The next section provides some good pointers.

You need to remember one more thing about Do…Loop conditional structures. In any of the Do…Loop structures, you can always force VBScript to exit the loop by using the statement Exit Do from within the loop itself. This is often useful for error conditions or special cases where the normal condition is insufficient for breaking out of the loop.

Putting It All Together

Now that you've seen all the decision structures at your command, you know that you have quite a wide variety of choices. You might be wondering at this point, "How do I know which control structure to use?" Oftentimes, you can structure your code where you can choose from one or more of the techniques explained today. I can't provide a specific set of rules to follow for every case. Often, it just boils down to using the structure that expresses what you want to do the most clearly. The If…Then…Else structure is fairly intuitive and straightforward. Still, you might want to keep the following points in mind:

Note
If you've used Visual Basic 4.0 or Visual Basic for Applications, you might be familiar with the SELECT statement, another powerful construct for evaluating a series of conditions. This is not supported in VBScript. Refer to Day 20, "Porting Between Visual Basic and VBScript," for more details on language differences.

You might hesitate when deciding what type of Do…Loop to use for the case in question.
You should keep the following tips in mind when making your decision:

Take some time to think of the right looping approach. At the same time, realize that there is often no one best approach. Even experienced programmers might each choose different looping constructs to solve the same problem.

Summary

Today you have gotten a comprehensive overview of the various control structures you can use in a VBScript program. A control structure is a set of code statements you can use to enable blocks of code to repeat or to execute or not execute based on decisions made in those statements. You have seen many examples of each control structure available in VBScript. With your knowledge of variables, operators, and control structures, you are becoming an increasingly competent and knowledgeable VBScript programmer.

Control structures are at the heart of VBScript programming. Having read today's lesson, you should understand how they work and be quite comfortable using them. As you will see, the examples throughout this book use them extensively. A program almost always has to make a lot of decisions. Today's lesson has provided you with the information and strategies you need to get the most out of directing and controlling code flow within a procedure.

Q&A

Q
Why are there so many Do…Loop structures available? They all seem so similar.
A
Yes, they are quite similar, but each is slightly different. Believe it or not, you will undoubtedly find yourself using almost all of them at one point or another. When you're writing your code to get it just the way you want it, the last thing you want to worry about is whether or not there is a control structure available that gets the job done. By being familiar with them all, you've got all the bases covered.
Q
Why is the use of Exit Do or Exit For statements within loops discouraged?
A
These statements are acceptable for specific conditions, but they often make code less readable, which makes it difficult for others who look at your code to know what's really going on. If you make sure the only way out of a loop is to not satisfy the loop's condition, it's much easier to follow your code. Often, breaking out of a loop by force with an exit statement is a sign of a poorly constructed loop with a condition that does not meet your goals. Take a look at the loop structure and condition again to make sure you're not leaving something out.
Q
How can I avoid creating loops that never stop?
A
Loops that never stop place your code in what's called an infinite loop. Infinite loops obviously prevent subsequent portions of your program from ever being reached. The best way to avoid them is to make sure you know how and when the condition that keeps your code looping finally ends and your loop stops. Try to think of cases where your loop might never exit, and if you can find them, try to prevent them by not getting into the loop in the first place or making your condition more broad so that you can get out of the loop in additional ways. For example, consider the following loop code:

Do While Stop = False
   Name = InputBox("Enter a name:")
   If GetAddress(Name) = False Then
       Stop = True
   End If
Loop

In this case, it is possible that the user might not want to enter any more names. The way this loop is set up, it will continue until it finds a name whose address it cannot match. That's fine, but what if the user is done entering names? There's no way to break out of the loop. The solution is to set up another loop condition that takes this into account:

Do While Stop = False or NoName = True
   Name = InputBox("Enter a name:")
   If Name = "" Then
       NoName = True
   End If
   If GetAddress(Name) = False Then
       Stop = True
   End If
Loop

Now, the program can break out of the loop if the user hasn't supplied a name or if the address of the name the user entered cannot be found.

Workshop

Create a Web page that uses at least three of the control structures you've learned about today. Focus on the If…Then, For…Next, and Do While…Loop structures, but feel free to change or add new structures as needed.

Quiz

Note
Refer to Appendix C, "Answers to Quiz Questions," for the answers to these questions.

  1. List three control structures you've seen today and a brief description of what each of them does. Provide a simple example of their use.
  2. Write a simple program that asks the user for the year in which she was born. Use a control structure to inform the user if the year she's entered is invalid. Use the InputBox function to get the year from the user. InputBox hasn't been covered in detail yet, but you can use it in the same manner it was used in the example earlier today.
  3. Now, include another control structure that keeps asking her for the year until she's entered the right one.