View Single Post
Old 03-02-2003, 10:51 PM
loquin's Avatar
loquin loquin is offline
Google Hound

Retired Moderator
* Guru *
Join Date: Nov 2001
Location: Arizona, USA
Posts: 12,400
Default Loopy

Here I am, back once more, talking about standards yet again. Actually, this is somewhat ironic, since the topic of this installment is looping...

In almost any app, the computer is programmed to perform one or more activities over and over. This, after all, is one of the tasks where a computer works very well. The process of repetitively processing the same chunk of code is known as looping. Looping can greatly improve the efficiency of your coding. Suppose that you have an array of 5000 integers that needs to be initialized to -1. You could add 5000 lines of code to perform this action…

However, this would be very tedious, and would result in a large program segment that does little. A better approach would be to use a loop to initialize the array. The power of the loop structure goes hand-in-hand with another feature of most computer programming languages - the array. An array is just a method of notation that groups identical variable types under a common name. Visual Basic extends the concept of variable arrays to also include arrays of controls on your form. This allows for efficiency improvements in accessing numbers of identical control types.

Visual Basic, Version 6, offers three basic types of looping structures. These types are the For-Next Loop, the For-Each Loop and the Do Loop. I’ll spend some time discussing each of these types of looping structure.

For-Next Loop

The For-Next loop is best suited for applications where you know, or will know, the number of iterations the code is to perform. For example, suppose that you need to inspect every character in a string to see if it is numeric (0-9), and if so, copy it to another string. Since you can know the length of the string, and therefore the number of characters to check, the loop for this function could be:

Dim N as Integer Dim strNum as String Dim strTest as String … strTest = Text1.Text For N = 1 to Len (strTest) If Mid$(strTest, N, 1) >= "0" And Mid$(strTest, N, 1) <= "9" Then strNum = strNum & Mid$(strTest,N,1) End If Next N
A few comments about the For-Next loop are in order.

The For loop will examine the loop counter at the beginning of each iteration to see if the counter has exceeded the test value. If a floating point type variable is used, the For-Next loop MAY exit before you think it should, or run an “extra” iteration. This is due to potential precision error in a floating point type variable. A Single or Double approximates the value of the number it represents, generally quite closely, but usually not exactly. This means that even if you THINK the value of the counter should be 0.10, it might actually be 0.09999999999997 or 0.1000000000002. This can lead to the unexpected results I mentioned earlier. If you must increment a value by a fractional portion of a whole number, and you absolutely cannot have the loop run “too few” or “too many” times, use a whole number variable type for the loop counter, and calculate the fractional portion as a percentage of the loop counter within the loop.

Note also that the Variable name in the Next N statement is optional. However, it makes the loop easier to understand, especially in the case of nested loops, if the variable name is included.

The For-Next loop also offers a way of exiting the loop early. You would place a test within the loop, and use the key phrase "Exit For." For instance, suppose that the loop should immediately quit processing and continue on with the rest of the application if a tilde (~) is found in the test string. You would simply add the line:
If Mid$(strTest,N,"1") = "~" Then Exit For
just after the For N = 1 to Len(strTest) line in the example. Keep in mind that this is an implied GoTo in your code, and a structured programming code purist may take issue with its use. I don't, as long as it is used sparingly.

Also, remember that you may specify the direction that a for-loop iterates, and the size of the step that it takes. For example, in order to have a loop iterate from 10 to 0, only processing the even numbers, you would code the loop as
For N = 10 to 0 Step -2

For-Each Loop

Although similarly named, The For-Each loop is specifically designed for looping through collections of objects. For instance, suppose that I wish to print the contents of 30 textboxes on my printer, with the position of each textbox being accurately reflected in the printed position of the text on the paper. I could code the printing as:
Private Sub PrintForm () Printer.xPos = TextForm1.Left Printer.yPos = TextForm1.Top Printer.Print TextForm1.text Printer.xPos = TextForm2.Left Printer.yPos = TextForm2.Top Printer.Print TextForm2.Text ' ... through TextForm30 End Sub
Now, this will get tedious in a hurry. Even with the ability to cut and paste! A more efficient, "Civilized" approach would be for me to create a control array of textboxes (Named TextForm(0) through TextForm(29). Then, I can set up my print routine as follows:
Private Sub PrintForm () Dim theText as Textbox Set theText = new TextBox For Each theText in Me.TextForm Printer.xPos = theText.Left Printer.yPos = theText.Top Printer.Print theText.text Next End Sub
For each iteration of the For Each loop, as I work with theText, it is really the underlying control that is being referenced by theText. Note that this approach will print the controls in the order that they were created on the form. Since this means that I won't necessarily know the order that the controls will be printed, I can use the Index property or the Tag property of the control to good effect.

Do Loop

The Do loop is used where you don't know precisely when a loop should end when you are writing the code. The Do loop is often used when reading files, where you don't know how many lines of text are in the file, or in processing a database recordset, where you aren't sure how many records were returned from the database. These types of loops will run until a condition becomes True or False. There are two variations of the Do loop - the Do While and the Do Until. Examples of both are shown below:
Open "C:\Test.Txt" for Input as #1 Do While Not EOF(1) Line Input #1, strLine Me.FileText.Text = Me.FileText.Text & strLine Loop Close #1 Open "C:\Test.Txt" for Input as #1 Do Until EOF(1) Line Input #1, strLine Me.FileText.Text = Me.FileText.Text & strLine Loop Close #1
A second variation of the Do While loop places the condition check (While, or Until) at the end of the loop. This will force the loop to run at least once, since the condition check is at the end of the loop. If the condition is placed at the beginning of the loop, it might not run at all.
Do Line Input #1, strLine Me.FileText.Text = Me.FileText.Text & strLine Loop While Instr(theLine,Chr(27)) = 0

While-Wend Loop

There is actually a fourth loop structure in VB: the While-Wend loop. This loop structure is considered obsolete however, and is only included for backwards compatibility with earlier versions of Basic. Its use is not recommended. If it must be used, the syntax is:
While Condition Statements Wend

If Then Goto Loop

It is possible to create your own loop structure in VB, using an If Then condition check, and the Goto statement to loop back (or ahead) to a label in the code. This is NOT a good choice, however. First, there is really no need to create your own looping structure, when VB offers looping structures that work well for all conceivable loops. Secondly, the use of the GoTo statement is frowned upon, and should rarely be used. In fact, it should rarely ever need to be used (except in one particular instance, which will be discussed later.)

Why should you avoid the use of GoTo's in your code? It's largely a matter of maintainability - it can be very difficult to follow code that uses GoTo's, as the code execution can jump around from point to point to point. In fact, the term Spaghetti code came into existence as referring to code that makes extensive use of the GoTo statement. The widespread use of the GoTo statement in a program is considered to be a dead giveaway of an unskilled VB programmer. alp0001 recently forwarded a link to an essay by Edsger Dijkstra, discussing the problems associated with GoTo way back in 1968!

Now, the single instance that I referred to earlier, where it can be desirable in VB to actually use a GoTo, is when you want to write your own error handler. In this case, place the error handler at the end of your Sub or Function, with a label to identify the error handler, and add a statement at the front of the sub that states:
On Error Goto ErrorHandlerLabel

This line will direct the application to jump to the error handler in the event of an error. Then, within the error handler, you can decide how to handle the error. If you can recover, use a resume statement to cause your app to continue from where the error occurred. Otherwise, you may have to exit the sub, or under some circumstances, you may even choose to end the application outright.

In conclusion then, Visual Basic offers three main looping structures, each with several variations. The For-Next loop is best suited for uses when you know, or will know at program execution, the number of iterations needed. The Do-Loop, on the other hand, is better suited for those instances where you won’t know how many times the loop needs to run. The For-Each loop structure is designed to interface closely with collections of objects. And, when you program a loop, be sure not to use floating point loop counters when you test for equality.
"I have my standards. They may be low, but I have them!" ~ Bette Middler
"It's a book about a Spanish guy called Manual. You should read it." ~ Dilbert
"To understand recursion, you must first understand recursion." ~ unknown

Last edited by loquin; 03-30-2006 at 02:17 PM.
Reply With Quote