Visual Basic Concepts

Working with Control Structures

Nested Control Structures

You can place control structures inside other control structures (such as an If...Then block within a For...Next loop). A control structure placed inside another control structure is said to be nested.

Control structures in Visual Basic can be nested to as many levels as you want. It's common practice to make nested decision structures and loop structures more readable by indenting the body of the decision structure or loop.

For example, this procedure prints all the font names that are common to both the Printer and Screen:

Private Sub Form_Click()
   Dim SFont, PFont
   For Each SFont In Screen.Fonts()
      For Each PFont In Printer.Fonts()
         If SFont = PFont Then
            Print SFont
         End If
      Next PFont
   Next SFont
End Sub

Notice that the first Next closes the inner For loop and the last For closes the outer For loop. Likewise, in nested If statements, the End If statements automatically apply to the nearest prior If statement. Nested Do...Loop structures work in a similar fashion, with the innermost Loop statement matching the innermost Do statement.

Exiting a Control Structure

The Exit statement allows you to exit directly from a For loop, Do loop, Sub procedure, or Function procedure. The syntax for the Exit statement is simple: Exit For can appear as many times as needed inside a For loop, and Exit Do can appear as many times as needed inside a Do loop:

Forcounter=startToend [Stepincrement] [statementblock] [Exit For] [statementblock]

Next [counter[, counter] [,...]]

Do [{While | Until} condition] [statementblock] [Exit Do] [statementblock]

Loop

The Exit Do statement works with all versions of the Do loop syntax.

Exit For and Exit Do are useful because sometimes it's appropriate to quit a loop immediately, without performing any further iterations or statements within the loop. For example, in the previous example that printed the fonts common to both the Screen and Printer, the code continues to compare Printer fonts against a given Screen font even when a match has already been found with an earlier Printer font. A more efficient version of the function would exit the loop as soon as a match is found:

Private Sub Form_Click()
   Dim SFont, PFont
   For Each SFont In Screen.Fonts()
      For Each PFont In Printer.Fonts()
         If SFont = PFont Then
            Print Sfont
            Exit For            ' Exit inner loop.
         End If
      Next PFont
   Next SFont
End Sub

As this example illustrates, an Exit statement almost always appears inside an If statement or Select Case statement nested inside the loop.

When you use an Exit statement to break out of a loop, the value of the counter variable differs, depending on how you leave the loop:

  • When you complete a loop, the counter variable contains the value of the upper bound plus the step.

  • When you exit a loop prematurely, the counter variable retains its value subject to the usual rules on scope.

  • When you iterate off the end of a collection, the counter variable contains Nothing if it's an Object data type, and contains Empty if it's a Variant data type.

Exiting a Sub or Function Procedure

You can also exit a procedure from within a control structure. The syntax of Exit Sub and Exit Function is similar to that of Exit For and Exit Do in the previous section, "Exiting a Control Structure." Exit Sub can appear as many times as needed, anywhere within the body of a Sub procedure. Exit Function can appear as many times as needed, anywhere within the body of a Function procedure.

Exit Sub and Exit Function are useful when the procedure has done everything it needs to do and can return immediately. For example, if you want to change the previous example so it prints only the first common Printer and Screen font it finds, you would use Exit Sub:

Private Sub Form_Click()
   Dim SFont, PFont
   For Each SFont In Screen.Fonts()
      For Each PFont In Printer.Fonts()
         If SFont = PFont Then
            Print Sfont
            Exit Sub            ' Exit the procedure.
         End If
      Next PFont
   Next SFont
End Sub