Visual Basic 2008 Programming: Business Applications with a Design Perspective
Chapter 1 Chapter 2 Chapter 3 Chapter 4 Chapter 5 Chapter 6 Chapter 7 Chapter 8 Chapter 9
Chapter 10 Chapter 11 Chapter 12 Chapter 13 Chapter 14 Appendix A Appendix B Appendix C Home
Last change: February 13 2016 18:48:19.

 Chapter in PDF

Table of Contents

Chapter 5: Decision
Last change: February 13 2016 18:47:58.

Syntax Structure

The Select Case block has the following syntax structure:

Select Case Expression Case Criterion 1 Statements (group1) to be executed when criterion 1 matches the result of expression Case Criterion 2 Statements (group 2) to be executed when criterion 2 matches the result of expression . . Case Criterion n Statements (group n) to be executed when criterion n matches the result of expression Case Else Statements (group n+1) to be executed when none of the above criteria match the result of expression End Select

Where the expression can be any kind, such as numeric, string, or logical, and the criteria should have the same type as the expression. Each criterion can consist of a list of single values and ranges. As an illustration, using the Select Case block, the grading problem based purely on score can be coded as follows:

Select Case Score Case Is >= 90 Grade = “A” Case 80 To 90 Grade = “B” Case Else Grade = “C” End Select

As you can see from the illustration, Score is the expression whose value will be evaluated against the criteria stated in the Cases. The first Case (Is >= 90) has an open range; that is, any Score value greater than or equal to 90 will belong to this Case and will result in the statement Grade = “A” being executed. The second Case has a closed range (where both ends are specified) and is expressed with the keyword To. A score in the range of 80 to 90 will result in the statement Grade = “B” being executed. Finally, if none of the cases are true, the statement(s) in the catch all Case Else will be executed.

When specifying the range in the Case statement, always specify the lower value first; otherwise, the criterion will never be True. In checking the range, the computer assumes the first number is the lower end of the range and the second value is the higher end. That is, the following Case will never be True:
Case 90 To 80 

Mutual Exclusiveness of Cases

Notice that the cases are mutually exclusive; that is, only one of the case blocks will be executed. The testing of cases starts from the top and proceeds down. As soon as a criterion (Case) is found true, no more comparisons will be performed. In the previous example, when a score is 90, “A” will be assigned to Grade. The second case will never be tested (even though 90 is also a value in the second case), resulting in a correct assignment decision.
Why not just code the second case “Case 80 to 89”? This will work correctly as long as Score is an integer (Long, ULong, Integer, UInteger, Short, or UShort) variable; however, if Score is a variable that can take on a fractional value, a score of 89.99 will not belong to this case and will become a “Case Else.”

Try This
Draw a text box on a new form. Enter the following code in the form’s click event:
Select Case Val(TextBox1.Text) Case 0 To 60 ‘First message MsgBox("The number is in the range of 0 and 60.") Case 50 To 100 ‘Second message MsgBox("The number is in the range of 50 and 100.") End Select
Run the program; then enter a number in the range of 50 and 60. You will always see the first message displayed. The second message is displayed only when you enter a value greater than 60. Do you see how the block works when the criteria in the Case statements are not mutually exclusive?
Beware of the logic error like the following:
Select Case Age Case Is >= 5 Admission = Half Case Is>= 12 Admission = One Case Else Admission = 0 End Select 
You will see that all admissions will be either zero or half priced when the routine runs. Why? Consider the age of 20. It is greater than 5, so the statement Admission = Half will be executed even though the age is greater than 12. To correct the error, place Case Age Is >= 12 as the first criterion. Always place the most restrictive criterion as the first case when coding this structure.

Detailed Syntax Rules

When coding the criteria, observe the following syntax rules:

You can combine all these situations in one Case statement by separating the criteria with commas. For example, you can code the following:
Case 50, 80 To 90, Is < 0

Can you see what’s wrong with the following code?
Select Case Age Case Age >= 12 ‘Statements Case Age >= 5 ‘Statements Case Else ‘Statements End Select 
The variable Age should be removed from each Case statement. As coded, the first case statement will compare Age with 12 first, resulting in a value of either True or False before this value is compare with Age (the expression specified in the Select Case statement). You will see that the statements in the Case Else block always get executed. If you have set Option Strict On, you will be informed of the conversion restriction that should alert you to the problem. Always set Option Strict On to avoid unexpected problems.

Variations in the Case Structure

Similar to the If block, you can omit statements from any of the cases. For example, in the preceding section, you used the If block to check for numeric keys for a txtNumber text box. That routine can be replaced by the use of the Select Case block as follows:

Private Sub txtNumber_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtNumber.KeyPress Dim KeyAscii As Integer KeyAscii = AscW(e.KeyChar) Select Case KeyAscii Case Is < Keys.Space ' These are control keys; ignore Case Keys.D0 To Keys.D9 'These are numeric keys; ignore Case Else ' These are neither control keys nor numeric keys; ' display an error message MsgBox("Numeric key only, please.") e.Handled = True 'Suppress the key End Select End Sub

This code allows only numeric keys. What if you also expect a decimal point to be entered? The keycode value for period (decimal point) is 46. (There is no predefined name for this key.) To accommodate this, you can insert the following line:

Case 46

Without any statement following this Case, no message will be displayed, similar to the previous two Cases.
Because all three cases are handled in the same way (do nothing), you could combine the three cases together:

Select Case KeyAscii Case Is < Keys.Space, Keys.D0 To Keys.D9, 46 ‘ Legitimate keys; do nothing Case Else ‘ Unexpected keys; display a message MsgBox(“Numeric key only, please.”) e.Handled = True ‘suppress the key End Select

Note that in the first Case statement, commas are used to separate the three criteria. It is interesting to point out that this Case provides a good example of a list of all types of criteria allowed by the syntax: open-ended range, closed range, and single value. Of course, you can add more to the list. For example, if you also expect negative numbers, you can also include 45 (key code for “-“) in the Case line:

Case Is < Keys.Space, Keys.D0 ToKeys.D9, 45, 46

Note that when coding individual values in the list, their order does not really matter; however, for convenience and clarity, you should list them in the order that gives you the clearest meaning.

Dealing with Constants

The use of the numeric values 45 and 46 in the previous code should cause you to be concerned about code clarity. When you come back to review the code after a while, you may not know what these two values represent. One possible solution is to use the Asc function. Recall that this function gives the ASCII value of a key. In place of 45 and 46, you can code the following:

Case Is < Keys.Space, Keys.D0 To Keys.D9, Asc(“-“), Asc(“.”)

The code is clearer; however, it will execute a bit slower because the Asc function will need to be called to give the ASCII values of the two keys. Another alternative is to declare two constants for the two keys and then use them wherever they are needed. For example, you can declare the following:

Const KeyMinus As Integer = 45 Const KeyPeriod As Integer = 46

Then code the Case statement as follows:

Case Is < Keys.Space, Keys.D0 To Keys.D9, KeyMinus, KeyPeriod

This approach takes a bit more code, but the code is both efficient and clear.

Try This
Enter  “Case < Keys.Space” in the code window for the previous example; then move the cursor to another line. You will see the line you have just entered is changed to “Case Is < Keys.Space”. The IDE does more than you expect. This also indicates that the IDE checks the syntax of each line you enter as soon as you move away from it.
Last change: February 13 2016 18:47:57.