Desktop Developer

Loop Your Way to Tighter Code

Take advantage of Loops in Visual Basic .NET to save coding effort, as well as to create more readable and maintainable code.

Technology Toolbox: Visual Basic

Looping is a powerful technique that enables you to write tighter code. Tighter code is smaller, more efficient, and usually—but not always—more readable.

As a developer, you will often encounter situations in which you need to execute the same code statement or group of statements repeatedly. You will need to execute some of these statements a specific number of times, whereas others might need to be executed as long as a certain condition persists (an expression is True), until a condition occurs (an expression becomes True). Visual Basic includes constructs that enable you to easily define and execute these repetitive code routines: loops.

I'll walk you through how to take advantage of a handful of looping techniques that will enable you to make your code more efficient, showing you how to write For... Next loops for situations in which you know the precise number of times you want a loop to execute.

One key point to keep in mind as you read this article: You don't need to know the number of iterations at design time, but you must know the number at runtime to use a For... Next loop. I'll explain how to use Step to increment or decrement the counter of a For... Next loop, and even how to exit a loop prematurely using Exit For.

I'll also walk you through how to use the powerful Do... Loop. Do... Loop enables you to create flexible loops that can handle almost any looping scenario. Depending on your needs, you can evaluate an expression in a Do... Loop using While or Until. Also, I'll show you how to evaluate expressions in the Do statement to make the loop behave differently than when evaluating in the Loop statement. If a For... Next loop can't do the job, some form of the Do... Loop will.

Finally, I'll explain how can look for multiple solutions for a given problem, which is important for determining the best approach for a given situation. Often, one approach is clearly superior to all other approaches, although you might not always find it. Other times, one approach might be only marginally superior, or multiple approaches might all be equally applicable. Expert programmers consistently find the best approaches to any given problem. With time, you'll be able to do the same.

The simplest type of loop to create is the For... Next loop, so I'll cover this one first. The For? Next loop has been around since the earliest forms of the BASIC language. With a For... Next loop, you instruct Visual Basic to begin a loop by starting a counter at a specific value. Visual Basic then executes the code within the loop, increments the counter by a defined incremental value, and repeats the loop until the counter reaches an upper limit you've set.

Create a For? Next Loop
The syntax for creating a For? Next loop is relatively straightforward:

For countervariable = start To end [Step step]
... [statements to execute in loop]
[Exit For]
... [statements to execute in loop]
Next [countervariable]

The For statement both sets up and starts the loop (see Table 1). Every For statement must have a corresponding Next statement. You don't have to specify the CounterVariable name with the Next statement, but you should because it makes the code easier to read. Let's begin by looking at several examples of simple For... Next loops, with in-depth explanations for each that explain what is going on. The first routine declares an Integer variable named intCounter and then starts a loop with a For statement:

Dim intCounter As Integer
For intCounter = 1 To 100
debug.WriteLine(intCounter)
Next intCounter

The loop initializes intCounter at 1, prints the value of intCounter, increments intCounter, and continues looping. This code doesn't include a Step option, so the variable intCounter is increased by 1 every time the loop is performed. This loop executes 100 times, printing the numbers 1 through 100 to the Immediate window.

This next routine performs similarly, but doesn't specify the name of the counter you want to execute:

Dim intCounter As Integer
For intCounter = 1 To 100
debug.WriteLine(intCounter)
Next

This syntax is perfectly legal, but it's not good coding practice.

Now consider this example, which executes a loop inside a loop:

Dim intCounter As Integer
Dim intSecondCounter as Integer
For intCounter = 1 To 100
For intSecondCounter = 1 to 100
debug.WriteLine(intSecondCounter)
Next intSecondCounter
Next intCounter

If you omit the variable names on the Next statements, the code would run, but it would be enormously difficult to read and understand (not to mention, maintain) from a programmer's standpoint.

You use the Step keyword in a For... Next loop statement to designate the value used to increment the counter variable each time the loop occurs. If you omit Step, the counter variable is incremented by 1, always. You can skip using a Step statement if you want the counter variable incremented by 1, but doing so makes your code harder to read and maintain, so you should consider using a Step anyway. Regardless, you must use Step if you need to increment the counter variable by a value other than 1.

This code works similarly to the first example, but increments intCounter by 4 rather than by 1 each time Next is reached:

Dim intCounter As Integer
For intCounter = 1 To 100 Step 4
debug.WriteLine(intCounter)
Next intCounter

This loop executes a total of 25 times (not 100 times). You can create a For? Next loop that counts backward by specifying a negative value for Step:

Dim intCounter As Long
For intCounter = 100 To 1 Step -1
debug.WriteLine(intCounter)
Next intCounter

This loop initializes intCounter at a value of 100 and decrements intCounter by 1 each time Next is reached. The loop executes until intCounter is reduced to 1 (the End value). Be aware that you don't have to use whole numbers for Step; you can use a number such as 0.5. If you do, the data type of the counter variable needs to support fractions, so you can't use Integer.

Exit a Loop Early
You know where a For... Next loop starts and ends when you initialize it (you have to specify a start and end, or you can't create the loop), but sometimes you need to exit a loop before you reach the End value. You use the Exit For statement to exit a For... Next loop at any time:

Dim intCounter As Integer
For intCounter = 1 To 100
If <condition> Then Exit For
debug.WriteLine(intCounter)
Next intCounter

When Visual Basic encounters an Exit For statement, code execution jumps immediately to the statement following the Next statement of the current loop, and the loop stops. In this example, the condition that causes you to exit might be a variable or any expression. A loop-stopping condition is usually something that changes during the lifetime of the loop; if a condition doesn't change, there's no point in evaluating it. For example, you might loop through a list of files, trying to find a specific file. Once you find it, there's no need to continue looking, so you exit the loop.

Visual Basic 2005 introduces the ability to continue a For... Next loop before encountering the Next statement. To do this, you use the statement Continue For:

For countervariable = 1 to 1000
If expression Then
Continue For
? Acts just like the Next statement
End If
? Other code?
Next countervariable

The next step is more involved. You want to create a procedure containing a For... Next loop that counts from 100 to 0 and sets the Opacity of a form to the value of the counter (the form will fade out).

Begin by creating a new Windows application, and name it "Fading Form." Next, right-click on Form1.vb in the Solution Explorer, choose Rename, and change the name of the default form to frmFadingForm.vb. Next, set the form's Text property to Fading Form.

Now add a button to the form. Set the Name property to "btnFadeForm"; the Location property to "105,113"; the Size property to "75,23"; and the Text property to "Fade Form" (see Figure 1). All that remains is to write the code. Place this code in the Form's Click event:

Dim sngOpacity As Single
For sngOpacity = 1 To 0 Step -0.05
Me.Opacity = sngOpacity
? Let the form repaint itself.
Me.Refresh()
? Create a delay.
System.Threading.Thread.Sleep(200)
Next
? Show the form again.
Me.Opacity = 1

The first statement dimensions a variable of type Single. You use Single because Opacity works with values of 0 to 1. Integers don't support decimal places. In fact, I wasn't paying attention when I first wrote this code, and I used an integer, which obviously failed. It took me a minute or two to realize what I had done wrong. The next statement starts the For... Next loop. It initializes the variable to 1, and Step indicates that the variable decrements by .05 each time the loop starts a new iteration. The third line sets Opacity of the form to the value of the variable. The next line (after the comment) calls the Refresh() method of the form, which forces it to repaint itself. If you don't do this, Windows might not get around to repainting the form between iterations. Comment out the Refresh() statement to see what happens in that case.

The Sleep statement tells Visual Basic to pause. The number in parentheses is the number of milliseconds to wait. You could use another For... Next loop to create a pause, but then the duration of the pause would depend on the speed of the user's computer. Using Sleep enables you to ensure that the pause is consistent across all machines that execute this code. The Next statement sends execution back to the For statement, where the variable is decremented and tested to make sure that we haven't reached the Stop value.

When the loop finishes, the form fades away. The last statement simply sets Opacity back to 1, showing the form.

This simple app demonstrates the power of loop statements. You would have to duplicate the statements 20 times each if you were to forgo a loop and write each line of code necessary to change the opacity.

Know When to Use Loops
You should use a For... Next loop when you know the number of times you want the loop to execute. This doesn't mean that you have to know the number of times you want the loop to execute at design time; it simply means that you must know the number of times you want the loop to execute when you first start the loop. You can use a variable to define any of the parameters for the For... Next loop:

Dim intCounter As Integer
Dim intUpperLimit as Integer
intUpperLimit = 100
For intCounter = 1 To intUpperLimit
debug.WriteLine(intCounter)
Next intCounter

One of the keys to writing efficient code is to eliminate redundancy. If you find yourself typing the same (or a similar) line of code repeatedly, chances are it's a good candidate for a loop.

In some situations, you won't know the exact number of times a loop must be performed—not even when the loop begins. You could start a For... Next loop specifying an upper limit that you know is larger than the number of loops needed, check for a terminating condition within the loop, and exit the loop using an Exit For statement when the condition is met. However, this approach is inefficient and usually impractical. Using a Do? Loop is far more practical under such circumstances.

Do... Loop comes in a number of flavors. The most basic looks something like this:

Do
[Statements]
Loop

A Do... Loop without some sort of exit mechanism or defined condition is an endless loop. In its most basic form, nothing is present to tell the loop when to stop looping. At times, you might need an endless loop (game programming is an example). In most cases, however, you need to exit the loop when a certain condition is met. Like the For... Next loop, the Do... Loop has a statement you can use to exit the loop at any time: the Exit Do statement. For example, you might expand the Do... Loop discussed already to include an Exit Do statement:

Do
[Statements]
If expression Then Exit Do
Loop

In this code, the loop executes until expression evaluates to True. Generally, the expression is based on a variable that's modified somewhere within the loop. Obviously, the loop never ends if the expression never changes.

You can build an expression into the Do... Loop structure itself using one of two keywords: While or Until. This code executes a simple Do... Loop using the While keyword:

Do While expression
[Statements]
Loop

This loop continues to run as long as expression evaluates to True. If expression evaluates to False when the loop first starts, the code between the Do While and Loop statements never executes.

This Do... Loop uses the Until keyword:

Do Until expression
[Statements]
Loop

This loop behaves differently from the loop that uses While. When you define a loop using the keyword Until, the loop executes repeatedly until expression evaluates to True. But this loop continues for as long as the expression is False. This is essentially the opposite behavior of While. If expression is True when the loop begins, the code between the Do Until and Loop statements never executes.

Ensure Loops Can Execute
Note that both While and Until can prevent a loop from ever executing. This occurs because expression is placed on the Do statement, which means the compiler evaluates it before entering the loop and again each time the loop iterates. You can put a While or Until in the Loop statement rather than in the Do statement, which means that the loop executes once before expression is evaluated for the first time. Such loops always occur at least once. You need to be aware of how this changes the behavior of the loop. For example, consider this code, which places the While keyword in the Loop statement:

Do
[Statements]
Loop While expression

This loop executes as long as expression evaluates to True. The difference between the Do... While and the Do... Loop While loops is that the code between the Do and the Loop While statements always executes at least once; the expression isn't evaluated until the loop has completed its first cycle. Here is the same code, using Until instead of While:

Do
[Statements]
Loop Until expression

This loop executes until expression evaluates to True. However, the code within this loop always executes at least once; the expression isn't evaluated until the loop completes its first cycle. You can use Continue Do within a Do... Loop to send execution back to the Do statement.

The next step is to build a small project that takes advantage of a Do? Loop. In this project, you find the first 10 numbers that are evenly divisible by three. You know you want to find 10 numbers, but you don't know how many numbers you need to evaluate, so a Do? Loop is a good approach for solving this problem.

Begin by creating a new Windows application named "No Remainders." Next, change the name of the form to "frmNoRemainders" and set its Text property to "No Remainders." Add a button to the form set its Name property to "btnFindNumbers"; its Location property to "99,39"; its Size property to "94,23"; and its Text property to "Find Numbers." Now add a ListBox control to the form, and set its Name property to "lstResults"; its Location property to "86,68"; and its Size property to "120,160."

The final step is to wire it up together with code. Enter this code behind the new button's Click event:

Dim intSeek As Integer = 1
Dim intFound As Integer = 0

Do Until intFound = 10
If intSeek Mod 3 = 0 Then
lstResults.Items.Add(CStr(intSeek))
intFound = intFound + 1
End If
intSeek = intSeek + 1
Loop

The code you place behind Click event is compact, but does a lot for you.

The first two statements simply dimension a couple of integer variables. The variable intSeek will be the number we'll test to see whether it's evenly divisible by 3 (meaning it has no remainder). The variable intFound will be our counter; we'll increment this by 1 each time we find a number evenly divisible by 3.

The Do statement starts the loop. The condition ensures that the loop will continue to function until we find 10 numbers (intFound = 10). You use the Mod operator to determine whether intSeek is evenly divisible by three. If the result of the regular division and the integer division is the same, there is no remainder. You then add the number to the results list box and increment intFound by 1.

The next step is to increase intSeek so that you can test the next number. The last statement is Loop. This sends execution back to the Do statement. If intFound = 10, the loop won't execute and instead the execution path is sent to the line following the Loop statement. If intFound is less than 10, the loop executes once more.

The Do... Loop works best here because you don't know how many numbers you need to evaluate, or iterate, through the loop. If your goal were merely to search the numbers from 1 to 100, a For... Next loop would be a better choice.

Visual Basic 2005 supports one more loop type: the While... End While loop. This loop does nearly the same things as the Do... Loop, but uses different syntax. The Do... Loop is more widely accepted in .NET, so I used it here. The While... End While is a hold-over from earlier versions of Visual Basic, so I highly recommend that you don't use it in your .NET applications.

This article is adapted from chapter 14 of Sams Teach Yourself Visual Basic in 24 Hours, Complete Starter Kit by James Foxall, from SAMS (ISBN 0672327392, copyright 2006).

comments powered by Disqus

Featured

Subscribe on YouTube