Flow Control
Flow Control
Flow Control
When you run a script that you have written, the code executes in a certain order. This order of execution is also known as flow . In simple scripts such as the ones you looked at so far, the statements simply execute from the top down. The script engine starts with the first statement in the script, executes it, moves on to the next one, and then the next one, and so on until the script reaches the end. The execution occurs this way because the simple programs youve written so far do not contain any branching or looping code.
Branching
Take a look at a script that was used earlier.
Dim YourName Above we initialized the variable YourName = InputBox(Hello! What is your name?) Above we ask for the users name and initialize the variable MsgBox Hello & YourName & ! Pleased to meet you. Above we display a greeting containing the users name If you save this script in a file with a .vbs extension, and then execute it using the Windows Script Host,
all of the statements will be executed in order from the first statement to the last. Note that it was previously mentioned that all of the statements will be executed. However, this isnt what you always want. There is a technique that you can use to cause some statements to be executed, and some not, depending on certain conditions. This technique is called branching . VBScript supports a few different branching constructs, and they are covered in detail in Chapter 5 , but here we only cover the simplest and most common one, which is the If...Else...End If construct. Take a look at this modified code example.
Dim YourName Dim Greeting YourName = InputBox(Hello! What is your name?) If YourName = Then Greeting = OK. You dont want to tell me your name. Else Greeting = Hello, & YourName & , great to meet you. End If MsgBox Greeting
Walking through the code, you do the following: 1. You declare the two variables that you are going to use:
Dim YourName Dim Greeting YourName = InputBox(Hello! What is your name?) You ask the user for some input, again using the InputBox function. This function expects one
required parameter, the prompt text (the text that appears on the input box). It can also accept several optional parameters. Here, you only use the one required parameter. Note that the parameter text that you passed Hello! What is your name? is displayed as a prompt for the dialog box. The InputBox function returns the value that the user types, if any. If the user does not type anything or clicks the Cancel button (both do the same thing), then InputBox returns a zero-length string, which is a strange kind of programming concept that basically means that it returns text that doesnt actually contain any text. Your script stores the result of the InputBox function in the YourName variable. 2. You come to the actual loop youre going to use:
If YourName = Then Greeting = OK. You dont want to tell me your name. Else Greeting = Hello, & YourName & , great to meet you. End If
This code presents the VBScript engine with an option that is based on what the user typed (or didnt type) into the input box. The first line tests the input from the user. It tests to see if the input that is stored in the variable YourName is a zero-length string. If it is, the next line of code is run and the variable Greeting is assigned a string. Figure 1-6 shows the message displayed if
the user doesnt type his or her name into the InputBox . 3. What happens if the user does (as you expect) type something into the input box? Well, this is where the next line comes in.
Else
You can actually begin to read the code and in fact doing this helps it to make sense. What the whole loop actually means is that if the value of variable YourName is a zero-length string, then assign the variable Greeting with one value; however, if it contains something else, do something else (assign Greeting a different value). This doesnt protect your script from users entering data like numbers of non-alphabet characters into the test box, although you could code for all these conditions if you wanted to. 4. The final line of the code uses the MsgBox function to display the value of the variable Greeting . Notice that both lines of code assign a value to the Greeting variable. However, only one of these lines will actually execute in any one running of the script. This is because the If...Else...End If block makes an either/or decision. Either a given condition is True , or it is False . Theres no way it can be neither (not a string that contains text nor a zero-length string) or both (a zero-length string that contains text). If it is True , then the script engine will execute the code between the If and Else statements. If it is False , then it will execute the code between the Else and End If statements. So, what the complete script does is test the input, and then executes different code, depending on the result of that test, and hence the term branching. Using this technique allows your script to adapt to the unpredictable nature of the input. Compare the intelligent script to the following one, which looks pretty lame.
Dim YourName Dim Greeting YourName = InputBox(Hello! What is your name?) Greeting = Hello, & YourName & , great to meet you. MsgBox Greeting
This script is just plain dumb because it does not contain any branching logic to test the input; so when the user does something unpredictable, such as clicking the Cancel button, or not entering any name at all, the script does not have the ability to adapt. Compare this to your intelligent script, which is capable of adapting to the unpredictability of input by testing it with If...Else...End If branching. Figure 1-6 3. What happens if the user does (as you expect) type something into the input box? Well, this is where the next line comes in.
Else
You can actually begin to read the code and in fact doing this helps it to make sense. What the whole loop actually means is that if the value of variable YourName is a zero-length string, then assign the variable Greeting with one value; however, if it contains something else, do something else (assign Greeting a different value). This doesnt protect your script from users entering data like numbers of non-alphabet characters into the test box, although you could code for all these conditions if you wanted to. 4. The final line of the code uses the MsgBox function to display the value of the variable Greeting . Notice that both lines of code assign a value to the Greeting variable. However, only one of these lines will actually execute in any one running of the script. This is because the If...Else...End If block makes an either/or decision. Either a given condition is True , or it is False . Theres no way it can be neither (not a string that contains text nor a zero-length string) or both (a zero-length string that contains text). If it is True , then the script engine will execute the code between the If and Else statements. If it is False , then it will execute the code between the Else and End If statements. So, what the complete script does is test the input, and then executes different code, depending on the result of that test, and hence the term branching. Using this technique allows your script to adapt to the unpredictable nature of the input. Compare the intelligent script to the following one, which looks pretty
lame.
Dim YourName Dim Greeting YourName = InputBox(Hello! What is your name?) Greeting = Hello, & YourName & , great to meet you. MsgBox Greeting
This script is just plain dumb because it does not contain any branching logic to test the input; so when the user does something unpredictable, such as clicking the Cancel button, or not entering any name at all, the script does not have the ability to adapt. Compare this to your intelligent script, which is capable of adapting to the unpredictability of input by testing it with If...Else...End If branching. Figure 1-6
Dim YourName Dim Greeting YourName = InputBox(Hello! What is your name?) If YourName = Then Greeting = OK. You dont want to tell me your name. Else Greeting = Hello, & YourName & , great to meet you. End If If YourName = Fred Then Greeting = Greeting & Nice to see you Fred. End If MsgBox Greeting The If...Else...End If block can be extended through the use of the ElseIf clause, and Dim YourName Dim Greeting YourName = InputBox(Hello! What is your name?) If YourName = Then Greeting = OK. You dont want to tell me your name. ElseIf YourName = abc Then Greeting = Thats not a real name. ElseIf YourName = xxx Then Greeting = Thats not a real name. Else Greeting = Hello, & YourName & , great to meet you. If YourName = Fred Then Greeting = Greeting & Nice to see you Fred. End If End If MsgBox Greeting
through nesting. Nesting is the technique of placing a block of code inside of another block of code of the same type. The following variation on your script illustrates both concepts:
Once again, seeing how the code has been indented helps you to identify which lines of code are subordinate to the lines above them. As code gets more and more complex, proper indenting of the code becomes vital as it will become harder to follow. Even though the branching logic you are adding to the code tells the script to execute certain lines of code while not executing others, all the code must still be interpreted by the script engine (including the code thats not executed). If any of the code thats not executed contains any syntax errors, the script engine will still produce an error message to let you know.
Looping
Branching allows you to tell the script to execute some lines of code, but not others. Looping , on the other hand, allows you to tell the script to execute some lines of code over and over again. This is particularly useful in two situations: When you want to repeat a block of code until a condition is True or False When you want to repeat a block of code a finite number of times There are many different looping constructs, but this section focuses on only two of them: The basic Do...Loop While loop The basic For...Next loop
This section takes a look at the Do...Loop While construct and how it can be used to repeatedly execute a block of code until a certain condition is met. Take a look at the following modification of the example script:
Dim Greeting Dim YourName Dim TryAgain Do TryAgain = No YourName = InputBox(Please enter your name:) If YourName = Then MsgBox You must enter your name to continue. TryAgain = Yes Else Greeting = Hello, & YourName & , great to meet you. End If Loop While TryAgain = Yes MsgBox Greeting
Notice the block of code that starts with the word Do and ends with the line that starts with the word Loop . The indentation should make this code block easy to identify. This is the definition of the loop. The code inside the loop will keep being executed until at the end of the loop the TryAgain variable equals No . The TryAgain variable controls the loop. The loop starts at the word Do . At the end of the loop, if the TryAgain variable equals Yes , then all the code, starting at the word Do , will execute again. Notice that the top of the loop initializes the TryAgain variable to No . It is absolutely essential that this initialization take place inside the loop (that is, between the Do and Loop statements). This way, the variable is reinitialized every time a loop occurs. If you didnt do this, you would end up with whats called an infinite loop. They are always bad. At best, the user is going to have to exit out of the program in an untimely (and inelegant) way because, as the name suggests, the loop is infinite. At worse, it can crash the system. You want neither and you want to try to avoid both in your code. Take a look at why the TryAgain = No line is essential to preventing an infinite loop. Going through the script line by line: 1. This first line starts the loop.
Do
This tells the script engine that you are starting a block of code that will define a loop. The script engine will expect to find a loop statement somewhere further down in the script. This is similar to the If...End If code block because the script engine expects the block to be defined with beginning and ending statements. The Do statement on a line all by itself means that the loop will execute at least once. Even if the Loop While statement at the end of the block does not result in a loop around back to the Do line, the code inside this block will be executed at least one time. 2. Moving on to the second line of code, you initialize the control variable. Its called the control variable because it ultimately controls whether or not the code block loops around again. You want to initialize this variable to No so that, by default, the loop will not loop around again. Only if a certain condition is met inside the loop will you set TryAgain to Yes . This is yet another strategy in an ever-vigilant desire to expect the unexpected.
Do TryAgain = No
3.
The next line of code should look familiar. You use the InputBox function to ask the user to enter a name. You store the return value from the function in the YourName variable. Whatever the user types, unless they type nothing, will be stored in this variable. Put another way, the script receives some external input and remember that we said input is always unpredictable:
Do TryAgain = No YourName = InputBox(Please enter your name:)
4.
In the next part of the code, you test the input. The line If YourName = Then tests to see if the user typed in their name (or at least some text). If they typed something in, the code immediately after the Else line will execute. If they didnt type in anything (or if they clicked the Cancel button), then the YourName variable will be empty, and the code after the If line will execute instead:
Do TryAgain = No YourName = InputBox(Please enter your name:) If YourName = Then MsgBox You must enter your name to continue. TryAgain = Yes Else Greeting = Hello, & YourName & , great to meet you. End If
If the user didnt type anything into the input box, you will display a message informing them that they have done something you didnt want them to. You then set the TryAgain variable (the control variable) to Yes and send them around the loop once more and ask the users for their name again (wherein this time they will hopefully type something into the input box). If the user did type in his or her name, then you initialize your familiar Greeting variable. Note that in this case, you do not change the value of the TryAgain variable. This is because there is no need to loop around again because the user has entered a name. The value of TryAgain is already equal to No , so theres no need to change it. 5. In the next line of code, you encounter the end of the loop block. What this Loop line is essentially telling the script engine is If the TryAgain variable equals Yes at this point, then go back up to the Do line and execute all that code over again. If the user entered his or her name, then the TryAgain variable will be equal to No . Therefore, the code will not loop again, and will continue onto the last line:
Do TryAgain = No YourName = InputBox(Please enter your name:) If YourName = Then MsgBox You must enter your name to continue. TryAgain = Yes Else Greeting = Hello, & YourName & , great to meet you. End If Loop While TryAgain = Yes MsgBox Greeting MsgBox Greeting If the user did not enter his or her name, then TryAgain would be equal to Yes, which would mean that the code would again jump back to the Do line. This is where the reinitialization of the TryAgain variable to No is essential because if it wasnt done then theres no way for TryAgain to ever equal anything but Yes. And if TryAgain always equals Yes, then the
loop will keep going around and around forever. This results in total disaster for your script, and for the user.
In this kind of loop, you dont need to worry about infinite loops because the loop is predefined to execute only a certain number of times. Heres a simple (if not very useful) example.
This loop is similar to the previous loop. The beginning loop block is defined by the For statement, and the end is defined by the Next statement. This loop is different because you can predetermine how many times it will run; in this case, it will go around exactly ten times. The line For Counter = 1 to 10 essentially tells the script engine, Execute this block of code as many times as it takes to count from 1 to 10, and use the Counter variable to keep track of your counting. When youve gone through this loop ten times, stop looping and move on to the next bit of code. Notice that every time the loop goes around (including the first time through), the Counter variable holds the value of the current count. The first time through, Counter equals 1, the second time through it equals 2, and so on up to 10. Its important to note that after the loop is finished, the value of the Counter variable will be 11, one number higher than the highest value in your For statement. The reason for this is that the Counter variable is incremented at the end of the loop, after which the For statement tests the value of index to see if it is necessary to loop again.
Giving you a meaningful example of how to make use of the For...Next loop isnt easy because you havent been exposed to much VBScript just yet, but heres an example that shows you dont need to know how many times the loop needs to run before you run it.
Dim Counter Dim WordLength Dim WordBuilder WordLength = Len(VBScript is great!) For Counter = 1 to WordLength MsgBox Mid(VBScript is great!, Counter, 1) WordBuilder = WordBuilder & Mid(VBScript is great!, Counter, 1) Next MsgBox WordBuilder For example, the phrase VBScript is great! has exactly 18 letter spaces. If you first calculated the number of letters in the phrase, you could use that number to drive a For...Next loop. However, this code uses the VBScript Len() function to calculate the length of the phrase used. Inside the loop, it uses the Mid() function to pull one letter out of the phrase one at a time and display them separately. The
position of that letter is controlled by the counter variable, while the number of letters extracted is defined by the length argument at the end. It also populates the WordBuilder variable with each loop, adding each new letter to the previous letter or letters, rebuilding the phrase. Heres a variation of the last example: here giving the user the opportunity to type in a word or phrase to use, proving that theres nothing up your sleeve when it comes to knowing how many times to loop the code.
Dim Counter Dim WordLength Dim InputWord Dim WordBuilder InputWord = InputBox (Type in a word or phrase to use) WordLength = Len(InputWord) For Counter = 1 to WordLength MsgBox Mid(InputWord, Counter, 1) WordBuilder = WordBuilder & Mid(InputWord, Counter, 1) Next MsgBox WordBuilder & contains & WordLength & characters.
An operator acts on one or more operands when comparing, assigning, concatenating, calculating, and performing logical operations. Say you want to calculate the difference between two variables X and Y and save the result in variable Z . These variables are the operands and to find the difference you use the subtraction operator like this:
Z=X-Y
Here you use the assignment operator ( = ) to assign the difference between X and Y , which was found by using the subtraction operator ( - ). Operators are one of the single-most important parts of any programming language. Without them, you cannot assign values to variables or perform calculations or comparisons. In fact, you cant do much at all. There are different types of operators and they each serve a specific purpose, as shown in the following table.
Operator Purpose
assignment ( = ) The most obvious and is simply used for assigning a value to a variable or property. arithmetic These are all used to calculate a numeric value, and are normally used in conjunction with the assignment operator and/or one of the comparison operators. concatenation These are used to concatenate (join together) two or more different expressions. comparison These are used for comparing variables and expressions against other variables, constants, or expressions. logical These are used for performing logical operations on expressions; all logical operators can also be used as bitwise operators. bitwise These are used for comparing binary values bit by bit; all bitwise operators
can also be used as logical operators. Figure 1-7 Figure 1-7 shows the final summary message generated by the code. Notice how well the information is integrated. When you have a situation where more than one operation occurs in an expression, the operations are normally performed from left to right. However, there are several rules. Operators from the arithmetic group are evaluated first, then concatenation, comparison, and finally logical operators. This is the set order in which operations occur (operators in brackets have the same precedence): , , (*, /), \, Mod, (+, ) & =, <>, <, >, <=, >=, Is Not, And, Or, Xor, Eqv, Imp This order can be overridden by using parentheses. Operations in parentheses are evaluated before operations outside the parentheses, but inside the parentheses, the normal precedence rules still apply. Take a look at the following two statements:
A=5+6*7+8 A = (5 + 6) * (7 + 8)
They look the same but theyre not. According to operator precedence, multiplication is performed before addition, so the top line gives A the value 55 ( 6 * 7 = 42 + 5 + 8 = 55 ). By adding parentheses, you force the additions to be evaluated first and A becomes equal to 165.