| << 5.4.2- Select Case | Chapter5 | 5.5.0- Jumping Structures and the Art of Reusing Code >> |
Looping Controls
ASP has two types of looping structures: Do While and For...Next. When you require one of these structures, it's advisable that you decide which structure to use, depending on whether you know in advance how many loops you want to do. If you can determine the number of loops and have this number stored in a variable, then use For...Next. If you do not know ahead of time how many loops you want to do and will have to decide after each loop whether to continue, then I suggest using Do While.
For…Next
The For...Next structure has three parts. The first is a line that describes how many times to repeat the loop. Second come a set of lines with action statements that carry out the task you want repeated. Last is a line that indicates the end of the action statements and tells ASP to go back and repeat the action statements again.
Here is a simple case to get started: imagine that we have a sales rep. on the road that wants to print a sign-in sheet for attendees to seminars. The sales rep. would like to log in to the company's web site, get the sign-in sheet, and print it. In this first case we know that the seminars always have five attendees:
<%
Response.Write "Sign-In sheet for Attendees"
Response.Write "On-Line Clothing Store - Fashions of Spring<BR><BR>"
For varCounter = 1 to 5
Response.Write "Attendee Name ___________________ <BR><BR>"
Response.Write "Attendee EMail __________________ <BR><BR><HR><BR>"
Next
%>
VBScript will execute the first two lines to display some introductory text for the sheet – this part is not inside the loop. On the third line, we begin the process of running the loop five times. In order to keep count we provide a variable called varCounter for VBScript to keep its count in. Here the variable is implicitly declared within the loop, and doesn’t have to be declared prior to this. The lines that will be repeated five times are all of the lines in between (but not including) the For... line and the Next line. In this case, the two Response.Write statements create a line for an attendee to write their name and e-mail address.
|
|
That simple first example assumed that we would always have five attendees. What if that number varies? We would like to have a first web page that asks for the number of attendees, and then use that number to determine how many lines to print. We can use the For Next (instead of Do While) because when we start the loop, the loop structure is fed the number of loops to execute.
If we assume that the text field called NumberAttendees contains the number of attendees input by the user, then the responding page (below) can grab the user's data from the field named NumberAttendees and stuff the data into the variable named varNumber. Then we can begin the For...Next loop. But this time we don't go up through exactly five cycles. Rather, we go through the number of cycles specified in the varNumber. Our sign-in sheet is now usable for any number of attendees:
<HTML>
<HEAD>
<TITLE>Example For Next Two Response</TITLE>
</HEAD>
<BODY>
<H2>Welcome to the Seminar<BR>Please Sign in below</H2><BR>
<%
varNumber=Request.Form("NumberAttendees")
For varLineCounter = 1 to varNumber
Response.Write "Attendee Name ___________________ <BR><BR>"
Response.Write "Attendee EMail __________________ <BR><BR><HR><BR>"
Next
%>
</BODY>
</HTML>
Now we're ready to try an example.
Try It Out – For...Next
Your boss asks you to turn in a sheet about once a week that lists the clients you have visited. Since you travel a lot you want to do this task from a web page form that asks you how many people you have visited in total, and then responds with a page that you can print and fill in.
1. Open your web page editor and type in the following code:
<HTML>
<HEAD>
<TITLE>For Next One Form</TITLE>
</HEAD>
<BODY>
<H2>Weekly Client Contacts</H2><BR>
<FORM ACTION=ForNextOneResponse.asp METHOD = post>
<P>Please enter the first day of the week in the form mm/dd/yy such as 09/20/98<BR>
<INPUT TYPE="text" NAME="start">
<P>Please enter the last day of the week in the same form<BR>
<INPUT TYPE="text" NAME="end"><BR>
<INPUT TYPE=submit>
<INPUT TYPE=reset>
</FORM>
</BODY>
</HTML>
2. Save this form as ForNextOneForm.asp
3. Close the form down and create a new file and this time type in the following code.
<HTML>
<HEAD>
<TITLE>ForNext One Response</TITLE>
</HEAD>
<BODY>
<H2>Weekly Client Contacts for George Washington</H2><BR>
<%
varStart=Request.Form("start")
varEnd=Request.Form("end")
varStart = CDate(varStart)
varEnd = CDate(varEnd)
varNumberDays=(varEnd-varStart)
For varLineCounter = 0 to varNumberDays
Response.Write "Clients: ___________________"
Response.Write "<BR ><BR><BR>"
Next
%>
signed _________________________
George Washington
</BODY>
</HTML>
4. Save this page as ForNextOneResponse.asp
5. Open up the form page ForNextOneForm.asp in your web browser and fill in any two close dates:
|
|
|
6. Click on Submit and you will see an entry on the Response page for each day:
|
|
How It Works
The form page is nothing new to you, but we have started slimming the code down to fewer lines so that you get used to seeing some good coding practices.
Note that we have specified the Action= ForNextOneResponse.asp. If you are copying pages from earlier Try It Outs be sure you update this line.
We have two pieces of user data going back to the server: the first and last dates of the week we're interested in. This data is used to stuff the variables that ASP will use to determine how many times to loop.
The response page actually uses the For...Next loop. The first few lines receive the first and last data from the browser. The data coming from a form's text input type will always be text, but we want to work with dates. So we convert the text by saying the new value of varStart will be equal to the result of doing a CDate conversion on the old value. This means ASP will read the contents of varStart, take that text and convert it into a real date, then use that real date to replace the text in varStart. The initial loading of the variables is on the first two lines below, and the conversion from text to true dates is on the final two lines:
varStart=Request.Form("start")
varEnd=Request.Form("end")
varStart = cdate(varStart)
varEnd = cdate(varEnd)
Then we calculate the number of days by subtracting the start date from the end date as below.
varNumberDays=(varEnd-varStart)
Then we can begin our loop. We need a counter, which we called varLineCounter, and we say "run the loop starting with the counter set at zero, and stop when the counter gets to the value held in varNumberDays (in this case, the value is 4)". The lines of code to be executed on each cycle are simple: write the word Clients, a few underscores, and then some line breaks. The last line, Next, indicates to ASP when to go back and repeat the cycle.
For varLineCounter = 0 to varNumberDays
Response.Write "Clients: ___________________"
Response.Write "<BR><BR><BR>"
Next
A Few Improvements
We can tighten the first four lines by putting the conversion of text to dates in two commands as follows:
varStart=cdate(Request.Form("start"))
varEnd=cdate(Request.Form("end"))
A further improvement would be to number the days by actually printing the varLineCounter (taking note to increment the day by one):
For varLineCounter = 0 to varNumberDays
Response.Write "Day " & varLineCounter+1
Response.Write " Clients: ___________________"
Response.Write "<BR><BR><BR>"
Next
More useful would be to print the actual date such as 09/12/99 at the beginning of the line. In the code below we add a line to the loop, which creates a new variable called varDateThisLine. Into that variable we stuff the result of a calculation which takes the start date and adds to it the number of the varLineCounter, that is, the number of the cycle
we are on.
For varLineCounter = 0 to varNumberDays
varDateThisLine = varStart + varLineCounter
Response.Write varDateThisLine
Response.Write " Clients: ___________________"
Response.Write "<BR><BR><BR>"
Next
Common Errors of the For...Next Structure
- Leave out a counter variable
- Forget the '=' symbol or the word "to" on the first line
- Leave out the statement Next
- Forget to put appropriate formatting (like a line break) within the repeated section
- Accidentally include a statement in the repeating section so that it is executed many times instead of only once. That line should have been above or below the For...Next structure
- Accidentally leave out a statement in the repeating section so that it is executed once instead of many times. That line should have been within the For...Next structure
Basic Rules of For...Next
- Line one must have: counter variable, equal sign, start number and end number.
- All lines within the For and Next will be repeated until the counter variable gets up to the end value
- You can use the counter variable within the loop
- Last line of control structure is Next
For Each...Next
A common cousin of the For...Next statement is For Each...Next, which works in a similar way to the For...Next statement, except that it's used for each element inside an array or a collection (We'll meet collections in Chapter 7 . For now, you can think of a collection as being an ordered set of objects.) If you remember, in Chapter 4 we looked at arrays, and mentioned that they could be populated using a For...Next statement: well, For Each...Next makes that task even simpler. Here's an example bit of code:
<%
Dim Item
Dim strCities(1) 'Declare an array
strCities(0) = "London" 'Populate it
strCities(1) = "Paris"
For Each Item In strCities
Response.Write Item & "<BR>" 'List the contents of each item
Next
%>
It looks almost identical to For...Next, doesn't it? The only difference is that you don't have to specify the number of items you want to loop through, VBScript will simply start with the first item in the array and repeat the loop until it reaches the last item in the array. In this case, each item in the array is listed on the screen, so, if there were one hundred cities in our array, each one would be displayed by this loop. The For Each…Next statement is also used to loop through the contents of collections of ASP objects. We'll look into this in more detail in the next four or five chapters. For the moment, we'll take a closer look at another looping control: the Do...While loop.
Do…While
We briefly mentioned the Do...While loop earlier in the chapter: you may remember that it's used to repeat a loop when we are not sure how many loops to perform. So on each loop it performs a test and continues looping as long as a specified condition exists (you can also use the construct Do...While NOT, i.e. loop while a specified condition does not exist). The Do...While loops and For...Next loops have two significant differences in syntax. First is the difference in key words: For...Next has only one word (For) in the opening statement and ends with the word Next. Do...While has two words in the opening statement (Do...While) and ends with the word Loop. The code between Do...While and Loop continues to run for as long as your specified condition exists.
Differences in Syntax Between For...Next and Do...While Loops
|
For...Next Key Words |
Do...While Key Words |
|
For... |
Do While... |
The second difference is the nature of the test to end the looping. For...Next has a variable for counting, a start point, and an end point. Do...While has an expression test: at the beginning of each loop ASP checks the expression and if it is true then it runs the loop. If the expression is false, then the loop is not run and ASP jumps down in the code to the line after Loop.
|
For...Next technique to stop looping |
Do…While technique to stop looping |
|
For varCounter 1 to 5 |
Do While varEnough < varTooBig |
There is a serious trap that every beginning programmer falls into: if you start a loop and do not provide a means for it to stop then it will continue forever as an infinite loop.
Most servers will eventually cut off a given ASP page, since the server needs to attend to other visitors and tries to optimize its resources.
The Do...While form of looping is perfect if we have to make a row in a table for each month of the year up to the present month. However, we don't know – at the time of writing our ASP code – in which month the user will be viewing the page. In May, the fifth month, we would like five rows. We can find the number of the current month (May = 5) using the code month(now()).
<HTML>
<HEAD>
<TITLE>Example Do While</TITLE>
</HEAD>
<BODY>
<H1>Year To Date: Monthly Sales Calls</H1><BR>
<%
varMonthCount = 0
varMonthNow = Month(now())
Do While varMonthCount <= varMonthNow
Response.Write "Number of clients met: _____ <BR>"
varMonthCount = varMonthCount + 1
Loop
%>
<BR>Signed ___________ George Washington
</BODY>
</HTML>
The first line takes care of 'administrative' HTML matters, and then in the body of the code we have a line to write the opening title on the page. Next, the VBScript begins and we establish two variables: varMonthCount will track our progress in creating the rows (it starts with a value of one since we have no rows printed so far). The second variable is varMonthNow, which we will use to hold the current month. This is obtained by running the month(now())functions mentioned earlier.
Now we can begin the Do...While loop. The trick is to use the right expression to stop the loop. In this case we will test at the beginning of each loop whether the varMonthCount is still less than or equal to the current month. For example, if we run this in May, the first loop will be done if the varMonthCount is less than the varMonthNow (which would be 5 for May). We then print some text from within the loop. The next line takes the old value of varMonthCount and replaces it with a new value exactly one increment higher. Now ASP loops back up and tests again. Since varMonthCount (which now = 2) is still less then varMonthNow (which now = 5) the loop runs again: and this will happen five times. After the fifth loop varMonthCount will equal six and when ASP tests for the Do...While condition the answer is false. ASP immediately jumps down to the first line after the Loop statement and prints the signature line.
Try It Out – Do While…Loop
Your boss likes the sheet you made in the last Try It Out that lists the clients you met each day, but now your job will change. You will meet clients during the first half of the month, and then in the second half you will be at the office performing other duties. So, the 'meeting clients' sheet will cover from the first day of the month up to the day you return to the office. However, your boss's definition of the first half of the month is flexible. Sometimes you have twelve days of visits, sometimes twenty. You need a form that looks at today's date and gives you enough lines for enough days of client visits: that is, one line for each day from the beginning of the month until today, whichever day of the month that is.
1. Open up your web page editor and type in the following code.
<HTML>
<HEAD>
<TITLE>Do While</TITLE>
</HEAD>
<BODY>
<H1>Sales Calls for This Month</H1><BR>
<%
varRowCount = 1
varTodayDate = day(now())
Do While varRowCount <= varTodayDate
Response.Write "For ____________ "
Response.Write "number of clients met was ______<BR>"
varRowCount = varRowCount + 1
Loop
%>
</BODY>
</HTML>
2. Save this as DoWhile.asp
3. Open up your browser and run this page. When run on the 9th of September produces the following page.
|
|
How It Works
This code starts by setting up two variables. The first is the counter, which we set at zero. The second holds today's date which we get from the function day() applied to the function now(). The result of these functions is to provide the text "5" when this page is requested on the fifth day of the month.
Then the loop begins, with VBScript testing whether the varRowCount is still less than or equal to today's date. (We have to start varRowCount on one as the months always start on the first.) If that expression is true then VBScript goes through the cycle. There are two steps in the cycle: the first simply puts the text and HTML on the page. The second line takes the old value of varRowCount, adds one to it and uses that new number as a replacement for the old contents of varRowCount. We need to change some condition on each cycle of the loop so we can, at some point, return a 'false' value for the Do...While expression and end the loop.
Improvements
Since we are getting and using the actual date it would improve the product if we put the date on each line.
<%
varRowCount = 1
varTodayDate = day(now())
varTodayMonth = MonthName(month(date()))
Response.Write "<H2>Report for " & varTodayMonth & "</H2>"
Do While varRowCount <= varTodayDate
Response.Write "For " & varTodayMonth & " " & varRowCount
Response.Write ": number of clients met was ______<BR>"
varRowCount = varRowCount + 1
Loop
%>
When requested on the ninth of September this will produce:
|
|
Common Errors of the Do...While Structure
- Using Next instead of Loop for the closing statement.
- Not having the variable of the expression change during the execution of each cycle. This results in the expression never becoming false and thus the loop never stops.
- Performing one too many or one too few cycles.
- Putting code that should be done once inside the loop by mistake.
- Putting code that should be repeated outside the code by mistake.
- Using < when a test condition should be <=, or > when it should be >=
- Creating an infinite loop that will never end, by testing for a condition that will never exist. If you replaced the less than operator with a greater than operator this would cause an infinite loop and your web page would hang.
Basic Rules of Do...While
- The opening statement uses the key words Do...While, followed by an expression.
- The expression, like all expressions, must resolve to true or false.
- There is usually a variable in the expression that will change with each cycle of the loop.
- The code to run in the loop is ended with the keyword Loop.
Do...Loop While
You're not restricted by having to place the condition at the beginning of your loop. If you wanted your condition at the end of the loop, then that is also possible. So, if you went back to the previous example, it could be amended as follows:
Do
...code here...
Loop While varRowCount <= varTodayDate
The difference here is that your block of code would be executed automatically, before we check our condition. So in this way, you can deduce that this loop would execute at least once, before exiting, while the first occurrence of the loop might never be executed at all.
Do Until Loop and Do Loop Until
Finally there's a subtle variation on the Do While Loop, which allows you to replace the keyword While with the keyword Until. The difference between them is one should be executed WHILE a condition is true, and the other should be executed UNTIL a condition is true. This variation is all that divides the two. So the previous example could also be written as:
Do Until varRowCount >= varTodayDate
...code here...
Loop
Or even:
Do
...code here...
Loop Until varRowCount >= varTodayDate
Notice that we've amended the condition, for looping slightly, so that we loop until the condition becomes true. The rules of when to use While and when to use Until are basically looking at your example and see which makes more sense to use.
We've spent a lot of time looking at the important looping controls. Next, we'll turn our attention to the equally important jumping structures.
| << 5.4.2- Select Case | Chapter5 | 5.5.0- Jumping Structures and the Art of Reusing Code >> |

RSS






