Hour 10


During this hour you will learn

Creating Logical Programs

This hour you'll see how to use the conditional and logical operators that you mastered in Hour 8's lesson. When you finish this lesson, you'll understand how a Visual Basic program can make a decision and execute certain program instructions based on that decision's result.

This hour's lesson teaches not only new decision-making statements, but also decision-making functions that come with Visual Basic. Although you won't fully master Visual Basic's built-in functions until Hour 14's lesson, you can put these data-testing functions to use right now, just as you did last hour with the message and input box functions.

Topic 1: Comparing Data with If

The If statement appears in every programming language. Computers must be able to make decisions based on the data the program receives. The decision is based on a logical comparison of the data to supplied values. The If statement works to make your programs more powerful and self-reliant.

FAST TRACK
Have you programmed If logic before? Almost every language supports the If statement. Visual Basic's If is fairly straightforward, so you might want to read through the If statement's format and then skip down to the topic titled "Data Type Inspection, IIf(), and Choose()" to learn about some of Visual Basic's comparison functions.

Overview

Because the If statement takes full advantage of the conditional operators, you can begin to write programs that make decisions based on data.

Most of the time, a Visual Basic procedure executes sequentially, with one line following the next, unless you add control statements that change the order of the instructions being executed. (A VB procedure doesn't execute sequentially when an If statement causes some statements to be skipped.) The If statement is one such control statement that determines the order of statement execution at runtime, depending on the data being worked with.

When you master the If statement and its derivatives, the remaining control statements, such as loops and Select Case, aren't difficult.

If's Format

If has several formats. Here is the syntax of the most fundamental If statement:

IF conditional Then

   Block of one or more Visual Basic statements

End If


The If's Block of one or more Visual Basic statements can contain one or more lines with any valid Visual Basic statements, including additional (nested) If statements.

Before you get to the programming side of If, think for a moment how you use the word if in real life. When you begin a sentence with if, you're setting up a conditional statement (a statement that may or may not be true). For example, consider the following statements:

If and only if these statements are true do you complete the statements. To clarify further, you could break down the last statement further gives the following:

Making enough money, therefore, is this statement's condition, determining whether the last part of the statement takes place.


Notice from its format that If takes more than a single line. You're now into the heart of Visual Basic, where you see several statements that take more than one line of a program. One shortcut If statement takes only a single line of code (as you'll see in the third topic section), but the If syntax shown earlier requires a matching End If somewhere later in the program. You might see a one-line If statement. If the Block of one or more Visual Basic statements takes only a single statement, you can put the entire If on a single line without the End If at the end. Nevertheless, using the complete three-line If statement format makes it easier to add statements later, even if only a single statement is needed for the If now.

Working with Conditionals

Before you put If statements together in complete examples, you would be wise to explore exactly how Visual Basic compares different types of values. With Visual Basic, you can compare numbers to numbers, numbers to strings, strings to strings, and variants to either numbers or strings.

Visual Basic compares differently, depending on what you're comparing. For example, if a conditional operator compares two numbers of any data type-such as an integer to a floating-point-a true numeric conditional results. All the following conditionals are true:

If (4 < 5) Then...

If (4 < 5.0) Then...

If (4 < 5.4322344433223) Then...

If (67.2322 > 67.2321) Then...


The If statements shown in this example and the next few examples aren't complete If statements. Understanding the conditional first makes the rest of the statement easier to understand.
Also, the values being compared (the expression after the If) would normally be variables or fields. But because you're learning about the different types of comparisons, this section uses literal conditional values to make these examples clearer.
Finally, the parentheses around the conditional after the Ifs aren't required, but they help pinpoint the conditional and make If statements easier to understand.

As you learned in Hour 8's lesson, Visual Basic compares strings according to the presence of the Option Compare statement. Generally, Visual Basic performs a binary compare, meaning that uppercase letters compare before lowercase, as the following true If results show:

If ("St. Francis Hospital" > "Saint Francis Hospital") Then...

If ("abc" > "ABC") Then...

If ("tWELVE" < "Twelve") Then...

If the Option Compare option now is set in the Declarations section, string conditionals aren't case-sensitive. The following string conditionals, therefore, result in true:

If ("St. Francis Hospital" = "ST. Francis Hospital") Then...

If ("abc" = "ABC") Then...

If ("1a2" = "1A2") Then...

If you compare a numeric value (field, constant, or variable) to a variable defined with the Variant data type, a numeric conditional is made if the Variant data contains a number or a string that "looks" like a valid number.

If a variable named v is defined as follows,

Dim varV As Variant
<

and you store a number in the variable like so,

varV = 45.6

then the following conditionals hold true:

If (varV = 45.6) Then...

If (varV < 100) Then...

If (-121 < varV) Then...


Be careful when comparing single- or double-precision numbers with the equality conditional operator (=). Representing exact fractional quantities inside the computer is difficult, and rounding can occur in the extreme decimal places that you don't always see on-screen. Therefore, 45.6 = 45.6 usually compares as true, but 45.6543234 = 45.6543234 doesn't always compare as true even though the numbers appear to be equal.

If you store a string in the variable as follows,

varV = "-343.56"

Visual Basic compares the following as true because the string stored in varV looks like a valid number:

If (varV > 0) Then...

If (varV < -500) Then...


If the Variant doesn't contain a valid number and you attempt to compare that Variant variable to a number, a Type Mismatch error appears.

As you're beginning to see, the Variant data type lets you perform some mixed data type comparisons that you sometimes require when comparing controls to each other or to other variables and literals.

Finishing the If

The If statement's body is the code between the If and the End If lines. The following rules hold:

Suppose that you want your Visual Basic procedure to display a secret message to users if they know a password. The password is read from a file and stored in the string variable named strSystemPass. After asking the users' password, the following If statement determines whether the users see the message:

If (strUserPass = strSystemPass) Then

   Beep        ' Rings the bell

   MsgBox("The key is in the file cabinet.")

End If


The Beep statement causes the computer to beep.

If users enter the correct password, the computer beeps, and the message box with the secret message appears. If users don't enter the correct password, however, the body of the If doesn't execute, and the program continues after the End If statement.

Visual Basic contains an Exit statement that unconditionally exits the current subroutine or function procedure. Here are two forms of Exit:

Exit Function

Exit Sub
<

If, depending on a data's value, you need to exit a procedure before its normal termination, use one of these statements. The following procedure assigns a bonus value to a label if a user's sales have reached $5,000 or more:

Private Sub CalcBonus ()

  If (txtSales.Text < 5000) Then

    Exit Sub    ' Terminate the procedure now

  End If

  lblBonus.Caption = txtSales.Text * .05  ' Display bonus

End Sub
<

If the If test is true, the Exit Sub executes. When Visual Basic runs an Exit Sub statement, the entire function immediately terminates. (Without such an Exit statement, the procedure continues executing at the statements following the End If.) Therefore, Visual Basic calculates and displays the bonus only if the sales warrant the bonus.


Visual Basic contains additional forms of Exit that work with other statements, such as the Exit Do and the Exit For statements. You'll learn more about these Exit forms when you learn about the Do and For statements in the next hour's lesson.

This and the next few hours' lessons show parts of the Visual Basic language. Only after learning the language specifics can you return to full form-based examples throughout the text. Also, you've learned all the controls that you can master without additional statements such as the array data type that you'll learn in Hour 12's lesson. If you want to try some of the sample procedures that you see this hour and the next few hours, you can create a new project and store each procedure that you want to try in a menu item's Click event. Or you can add a standard module to the project (by choosing Add Module from the Project menu), enter the new procedure, and then type the name of that procedure in a control's event procedure to execute the procedure when the event occurs.

Else Specifies Otherwise

A complete If statement contains an Else portion that handles conditionals that the If without an Else can't take care of. By itself, the If describes what happens if a conditional is true. The Else part of an If-if you include an Else-specifies what happens if the conditional is false. Here is the format of the If with Else:

IF conditional Then

   Block of one or more Visual Basic statements

[Else

   Block of one or more Visual Basic statements]

End If
<

The Else portion is enclosed in square brackets to indicate that it's an optional part of If (don't include the brackets as part of your actual code). Think of Else as meaning otherwise. Here is how you might use an else as you might use otherwise in everyday conversation:

The otherwise specifies what happens if the condition following If is false.


It might help to remember that only one of the two blocks of code following If executes: the block following If or the block following Else. Both blocks never execute because the If...Else statement is mutually exclusive and ensures that only one of the two blocks of code executes.

Throughout this hour's lesson, the placement of the ellipses (...) in the If indicates where the body of each If statement goes. For example, If...ElseIf describes the block of statements defined with this syntax:
If

  Block of one or more Visual Basic statements

ElseIf

  Block of one or more Visual Basic statements

End If

<

Last hour's lesson taught you how to use the message functions, but you couldn't determine how users responded to the boxes until you learned If. Use If to determine exactly which button users clicked. The following simple If statement displays a dialog box and tests user response to the dialog box buttons:

If (MsgBox("Are you ready?", vbYesNo) = vbYes) Then

   MsgBox("You clicked Yes")

Else    ' You can assume the user clicked No

   MsgBox("You clicked No")

EndIf
<

Checking for TypeOf

If you follow an If with the TypeOf keyword, you can find out exactly what kind of object your code is working with. TypeOf is useful if a function is passed a control variable that represents a control on a form or report, and you want to know what kind of control was passed. You also learn ways to save all the controls on a form and then step through each control, one at a time, inspecting each one and making decisions based on what you find.

Here's the syntax of the If TypeOf statement:

IF TypeOf object Is objectType Then

   Block of one or more Visual Basic statements

[Else

   Block of one or more Visual Basic statements]

End If
<

The object is any control variable name, and the objectType can be any one of the following control types (other control types are available as well):

CheckBox       Image    OpenButton   Rectangle

ComboBox       Label    OptionGroup  Shape

CommandButton  Line     PageBreak    TextBox

Graph          ListBox  PictureBox   ToggleButton
<

Example

Any statement can reside in the blocks of the If, even additional If statements. Consider the If statement in Listing 10.1.

Listing 10.1 A Sample If Statement

If Not IsNull(dteAnyDate) Then

  dteResult = DateSerial(Year(dteAnyDate), Month(dteAnyDate) + 1, 1)

  If Weekday(dteResult) = 1 Then        ' Sunday, so add one day.

      dteDueDate = dteResult + 1

  ElseIf Weekday(dteResult) = 7 Then    ' Saturday, so add two days.

      dteDueDate = dteResult + 2

  Else

      dteDueDate = dteResult

  End If

Else

  dteResult = Null

End If

You don't have to understand everything in this code at this point. Basically, if the dteAnyDate data being tested isn't a Null value, dteAnyDate contains valid data. A set of nested If statements then tests that data and assigns dteDueDate (which could be the surrounding function's return value) one of two values depending on what dteAnyDate contains.

Concentrate on the nested If statements. (When an If appears inside another If, the internal If statement is a nested If statement.) Nested If statements can be confusing to debug, especially if the nested If needs an Else specified and that Else contains another If statement. As this example code shows, Else and If can never go together. You must use the special ElseIf keyword (shown in Listing 10.1) if your Else block of code contains its own If. Be sure that you type the ElseIf keyword as one word and not two.

In this hour's final topic section, you learn about the Select Case statement, which shortens nested If statements and makes them easier to write and test.

Next Step

The following code demonstrates how you might combine If and TypeOf to determine which control you're working with:

If TypeOf aControl Is CommandButton Then

  MsgBox("You sent a Command Button")

ElseIf TypeOf aControl Is CheckBox Then

  MsgBox("You sent a Check Box")

ElseIf TypeOf aControl Is TextBox Then

  MsgBox("You sent a Text Box")

End If
<

Although it might seem obvious at this point that you'll always know a control's data type because you created the control and wrote the program, Hour 13's lesson, "Understanding How Procedures Work," shows you how to pass information from one procedure to another. You can use code similar to this If statement to determine the kind of control sent to the current procedure from another.

Topic 2: Data Type Inspection, IIf(), and Choose()

In the first topic section, you learned about conditional code-that is, code that perform comparison tests and executes one set of statements or another depending on the result of the tests. Your programs can now set up logic that ensure that users entered correct data, that a table contains enough information, or that the printer is turned on before you print a report.

This topic section extends your knowledge of conditional logic by describing the Is...() data inspection functions and giving you some shortcuts for the If statement. So much of programming in Visual Basic or any other language is devoted to looking at data and making decisions about what to do next based on that data.

Overview

This topic section introduces these Visual Basic data-testing components:

Data plays such an important part of database programming that you should master this topic's content, and you'll be well-rewarded when you begin writing Visual Basic-based applications.

Inspecting Data

The Is...() and VarType() functions are called data-inspection functions. These functions inspect the data types, not the contents, of variables. In the first topic section, you learned about the TypeOf keyword that inspects data to determine the kind of object you have. You'll typically use TypeOf to test for control types.

Your VB programs work with many different kinds of data, and you sometimes don't know in advance what kind of data you have to work with. Before you make a calculation, for example, you want to make sure that the data is numeric.

Table 10.1 lists the data inspection functions and offers a description of what they do. Each function receives one argument of the Variant data type. (An argument is a value that you place inside a function's parentheses. Some functions accept multiple arguments separated by commas.)

Table 10.1 The Is...() Data-Inspection Functions

Function Name

Description

IsDate()

Determines whether its argument is a date data type (or whether the data can be converted to a valid date)

IsEmpty()

Determines whether its argument has been initialized

IsNull()

Determines whether its argument holds a Null value

IsNumeric()

Determines whether its argument holds a number (or whether the data can be converted to a valid number)


Each Is...() function accepts the Variant data type because they must be able to inspect any data and determine what type it is.

An empty variable is one that hasn't been initialized. Perhaps a procedure has declared the variable but has yet to store data in the variable. Newcomers to Visual Basic often wonder why an empty variable is different from a Null value and a zero value. At times, you must have some way to tell whether users have entered something into fields; an empty variable signals that nothing has been entered.

The code snipped in Listing 10.2 is rather simple and demonstrates what happens when you apply the IsEmpty() function to variables that have and haven't been initialized.

Listing 10.2 Ifmsges.bas: Testing for Empty Variables

Dim var1, var2, var3, var4 As Variant

Dim msg As Integer   ' MsgBox return

var1 = 0        ' Zero value

var2 = Null     ' Null value

var3 = ""       ' Null string

If IsEmpty(var1) Then

   msg = MsgBox("var1 is empty", vbOKOnly)

End If

If IsEmpty(var2) Then

   msg = MsgBox("var2 is empty", vbOKOnly)

End If

If IsEmpty(var3) Then

   msg = MsgBox("var3 is empty", vbOKOnly)

End If

If IsEmpty(var4) Then

   msg = MsgBox("var4 is empty", vbOKOnly)

End If
<

The only output from this code is a message box that displays the following:

var4 is empty
<

You receive this response because all the other variables have some kind of data (they've been initialized).


Use IsNull() to see whether a control or field on a report or form contains data. Use IsEmpty() just for variables.

This IsNull() function checks its argument and returns true if the argument contains a Null value. The value Null is a special value that you can assign to variables to indicate either that no data exists or that there's an error (the way your program interprets a Null value depends on how you code the program). On form and report controls, a field is considered Null if users enter no data in the field.


Given that you can assign a Null value to a variable (as in varA = Null), you might be tempted to test for a Null value like this:
If (varA = Null) Then ....

<
Be warned that such an If always fails. Using IsNull() is the only way to check for a Null value in a variable.

If your Visual Basic procedure needs to know whether a form's field named Hours Worked has data, the procedure can check it with an If statement, as follows:

If IsNull(txtHoursWorked) Then

   msg = MsgBox("You didn't enter hours worked!", vbOKOnly)

Else                   ' Thank them for the good hours

   msg = MsgBox("Thanks for entering hours worked!", vbOKOnly)

End If
<

This If statement checks to ensure that users typed something in the field before the program continues.

The IsNumeric() function checks its argument for a number. Any Variant value that can be converted to a number returns a true result in the IsNumeric() function and a false result otherwise. The following data types can be converted to numbers:

Suppose that you place a text box on the form for users to enter a loan amount. The program will use the loan amount to compute past due charges as they accrue. Before you use the amount to compute charges, you should verify that users entered a valid currency value. The text box holds a Variant data type when users enter the loan amount, so you can use the IsNumeric() to test for the valid number before computing with the number.

The Multitalented VarType() Function

If you need to know what data type a variable is, use the VarType() function. Table 10.2 lists the return values from the VarType() function, and VarType() returns no other values than the 16 listed in the table.

Table 10.2 VarType() Return Values

This Value

If the Variant Contains

Returned...

Named Literal

This Data Type...

0

vbEmpty

Empty

1

vbNull

Null

2

vbInteger

Integer

3

vbLong

Long

4

vbSingle

Single

5

vbDouble

Double

6

vbCurrency

Currency

7

vbDate

Date

8

vbString

String

9

vbObject

Object

10

vbError

An error value

11

vbBoolean

Boolean

12

vbVariant

Variant (for Variant arrays, see Hour 12's lesson)

13

vbDataObject

A data-access object

14

vbDecimal

Decimal

17

vbByte

Byte

8192

vbArray

An array (VB adds 8192 to the data type to indicate an array, so 8194 indicates an integer array)

The code snippet in Listing 10.3 contains a nested If statement, which prints the data type of whatever data is passed to it.

Listing 10.3 Dattype1.bas: Determining the Data Type Passed

' varA comes from another routine

  If VarType(varA) = vbEmpty Then

    msg = MsgBox("The argument is Empty")

  ElseIf VarType(varA) = vbNull then

    msg = MsgBox("The argument is Null")

  ElseIf VarType(varA) = vbInteger then

    msg = MsgBox("The argument is Integer")

  ElseIf VarType(varA) = vbLong then

    msg = MsgBox("The argument is Long")

  ElseIf VarType(varA) = vbSingle then

    msg = MsgBox("The argument is Single")

  ElseIf VarType(varA) = vbDouble then

    msg = MsgBox("The argument is Double")

  ElseIf VarType(varA) = vbCurrency then

    msg = MsgBox("The argument is Currency")

  ElseIf VarType(varA) = vbDate then

    msg = MsgBox("The argument is Date")

  ElseIf VarType(varA) = vbString then

    msg = MsgBox("The argument is String")

  ElseIf VarType(varA) = vbObject then

    msg = MsgBox("The argument is an Object")

  ElseIf VarType(varA) = vbError then

    msg = MsgBox("The argument is an Error")

  ElseIf VarType(varA) = vbBoolean then

    msg = MsgBox("The argument is Boolean")

  ElseIf VarType(varA) = vbVariant then

    msg = MsgBox("The argument is a Variant array")

  ElseIf VarType(varA) = vbDataObject then

    msg = MsgBox("The argument is a Data Object")

  ElseIf VarType(varA) = vbDecimal then

    msg = MsgBox("The argument is Decimal")

  ElseIf VarType(varA) = vbByte then

    msg = MsgBox("The argument is Byte")

  Else

    msg = MsgBox("The argument is an array")

  EndIf
<

The Select Case statement, which you learn in this hour's final topic, offers a better method of nesting If statements like the ones shown here.

An If Shortcut: IIf()

The IIf() function performs a succinct version of a simple If...Else statement. Because IIf() is a function, it returns a value, and the value returned depends on a true or false test that you put at the beginning of IIf(). The syntax of IIf() is as follows:

IIf(expression, trueResult, falseResult)
<

If the expression is true, trueResult is returned; if the expression is false, falseResult is returned.

Here's a sample code fragment that uses IIf():

Dim atrAns As String

strAns = IIf(intN < 0, "Cannot be negative", "Good data")
<

This statement does the following: If whatever is stored in intN is less than 0, the string variable strAns is assigned the string "Cannot be negative", but if intN contains any number equal to or greater than 0, the string "Good data" is stored in strAns. Figure 10.1 illustrates the nature of this IIf().

FIG. 10.1

The IIf() function works like the If statement.

If you rewrite the previous IIf() function as an If statement, here is what you do:

If (n < 0) Then

   strAns = "Cannot be negative"

Else

   strAns = "Good data"

End If
<

IIf() is more efficient and easier to write than a multiline If statement. However, IIf() replaces only simple If statements that assign data, and If statements with several lines of code in their bodies must remain regular If statements.

FAST TRACK
The IIf() function is similar to Lotus 1-2-3's @IF function. If you've ever programmed in C, the IIf() function works a lot like the conditional operator ?:.

Choosing with Choose()

The Choose() function can have many arguments, more arguments than any other built-in function. Depending on the value of the first argument, Choose() returns only one of the remaining arguments. Here's the syntax of Choose():

Choose(intIndexNum, expression[, expression] ...)
<

After the second argument (expression), you can have as many expression arguments as needed. The intIndexNum must be a variable or field that equates to a number from 1 to the number of expressions in the function.

If, for example, you need to generate a small table of price codes, abbreviations, or product codes, using Choose() is more succinct than using an If statement. Choose(), however, is more limited in scope than If because Choose() selects on an integer value only, not on a more complete comparison.


Choose() returns Null if intIndexNum isn't between 1 and the number of expressions inclusive.

The first argument of Choose() can be an expression. Therefore, you have to adjust the first argument so that it falls within the range of the number of arguments that follow. If the values possible for the index goes from 0 to 4, for example, add 1 to the index so that the range goes from 1 to 5 and selects from the Choose() list properly.

Suppose that a form contains a Price Code label. When users enter a new product, they should also enter a price code from 1 to 5, which corresponds to the following codes:

The following Choose() function assigns to a description field the correct description based on the price code (type this code all on one line):

Descript = Choose(lblProdCode, "Full markup", "5% discount",

[ccc]"10% discount", "Special order", "Mail order")
<

Example

The following code asks users for their age by using a Variant variable. The program displays an error message if a user enters a non-numeric number:

Dim varAge As Variant

Dim msg As Integer   ' MsgBox() return

varAge = InputBox("How old are you?", "Get Your Age")

If IsNumeric(varAge) Then

   msg = MsgBox("Thanks!", vbOKOnly)

Else

   msg = MsgBox("What are you trying to hide?", vbOKOnly+vbQuestion)

End If
<

Next Step

You can't divide by zero (division by zero is undefined in mathematics). Therefore, the following IIf() function returns an average sale price or a Null value if division by zero results:

curAveSales = IIf(intQty > 0, curTotalSales / intQty, Null)
<

Remembering that a zero value produces a false result, you can rewrite the preceding statement as follows:

curAveSales = IIf(intQty, curTotalSales / intQty, Null)
<

If you rewrite this statement by using an If, here is how you do it:

If (intQty) Then

   curAveSales = curTotalSales / Qtr

Else

   curAveSales = Null

End If
<

Topic 3: The Select Case Statement

You probably shouldn't rely on the If...ElseIf block to take care of too many conditions. More than three or four nested If statements tend to add confusion (you get into messy logic, such as "If this is true, then if this is true, then do something, else if this is true do something, else if this is true do something," and so on). This topic's Select Case statement handles multiple If selections better than a long set of If...ElseIf statements. The Select Case statement is the final logic-control statement left for you to learn in the Visual Basic language.

Overview

There are three syntaxes of the Select Case statement. Select Case is one of the longest statements in Visual Basic. Despite that foreboding length, Select Case is one of the easiest statements to master. Select Case exists to make your programming decisions easier, not harder.

This topic section introduces the following subjects:

The Select Case Format

Select Case improves on the If...Else block by streamlining the nested "If within an If" construction. The format of the primary Select Case is as follows:

Select Case Expression

Case expressionMatch

   Block of one or more Visual Basic statements

[Case expressionMatch

   Block of one or more Visual Basic statements]

[Case Else

   Block of one or more Visual Basic statements]

End Select
<

As you can see, Select Case chooses from among several conditions. As the brackets indicate, you can optionally have two or more sets of Case expressions and code following a Select Case statement. Your application determines the number of Case expressions that follow the Select Case line. The expressions can be string or numeric expressions (with constants or variables). The expressions aren't conditional True or False expressions, but expressions that equate to integer or character values.

The Block of one or more Visual Basic statements is similar to the block of statements you saw for the block If; you can type one or more statements following each other to make up that block. The Case Else line is optional; not all Select Case statements require it. You must put the End Select line at the end of every Case Select statement, however. Otherwise, Visual Basic doesn't know where the last block of Case statements ends.

Using Select Case is easier than its syntax might lead you to believe. If the Select Case expression is the same as any of the Case expressions, that matching Case code executes. If none of the Case expressions match the Select Case expression, the Case Else code executes. If you don't supply a Case Else, the next statement in the program executes.

You can use a Select Case anywhere that you can use a block If...Else; in fact, Select Case is the easier of the two to read.

In the preceding topic, you learned about the VarType() function, which determines the data type of its argument by returning a numeric value. Although nothing is wrong with the procedure as coded in Listing 10.3, nested If...ElseIf statements can be confusing. Select Case statements do the same thing but are easier to follow. Listing 10.4 shows an equivalent function that uses Select Case.

Listing 10.4 Seldata.bas: Determining Data Types with Select Case

Private Sub PrntType(varA)  ' Variant if you don't specify otherwise

  Dim msg As Integer   ' MsgBox() return

  Select Case VarType(varA)  ' VarType() returns an integer

    Case 0

      msg = MsgBox("The argument is Empty")

    Case 1

      msg = MsgBox("The argument is Null")

    Case 2

      msg = MsgBox("The argument is Integer")

    Case 3 

      msg = MsgBox("The argument is Long")

    Case 4 

      msg = MsgBox("The argument is Single")

    Case 5 

      msg = MsgBox("The argument is Double")

    Case 6

      msg = MsgBox("The argument is Currency")

    Case 7

      msg = MsgBox("The argument is Date")

    Case 8

      msg = MsgBox("The argument is String")

    Case 9

      msg = MsgBox("The argument is an Object")

    Case 10

      msg = MsgBox("The argument is an Error")

    Case 11

      msg = MsgBox("The argument is Boolean")

    Case 12

      msg = MsgBox("The argument is a Variant array")

    Case 13

      msg = MsgBox("The argument is a Data Access Object")

    Case 14

      msg = MsgBox("The argument is Decimal")

    Case 17

      msg = MsgBox("The argument is Byte")

    Case Else

      msg = MsgBox("The argument is an Array")

  End Select

End Sub
<

The long Select Case statement, with indented Case statements, cleans up the code when your program must select from among many choices. The expression at the end of the Select Case line-in this case, VarType(varA)-determines which of the subsequent Case statements execute. Although only one statement follows each Case statement in this example, several statements can execute for a Case, and you can trigger the execution of other procedures as well. Instead of numeric literals, you could have used Visual Basic's named literals, such as vbBoolean; this example used numbers to help ensure that you master Select Case.


The VarType() function always returns a value from 0 to 14, 17, and greater than or equal to 8192. If none of the Case values match the expression, use a Case Else statement. A Case Else executes if none of the other Case values match the Select Case expression.

Conditional Select Case Choices

As with the If statement, the expression that Select Case tests for can be conditional. You must use the extra Is keyword in the conditional Case. Because you can put a conditional test after one or more of the Cases, you can test for a broader range of values with the conditional Select Case. The keyword Is is required if you use a conditional test in a Case.


You can't combine And, Or, or Not in a conditional Select Case statement. If you need to make a compound conditional test, you must use a block If...ElseIf.

The procedure in Listing 10.5 asks users for an age and prints an appropriate message. Without the conditional Case testing, it would take too many individual Cases testing for each possible age to make the Select Case usable here.

Listing 10.5 Agetest.bas: Testing an Age Value with Select Case

Private Sub ageTest ()

' Procedure to describe legal vehicles based on age

  Dim intAge As Integer

  Dim msg As Integer  ' MsgBox() return

  intAge = InputBox("How old are you?")

  Select Case intAge

    Case Is < 14

      msg = MsgBox("You can only ride a bike.")

    Case Is < 16

      msg = MsgBox("You can ride a motorcycle.")

    Case Else

      msg = MsgBox("You can drive a car")

  End Select

End Sub
<

The Range of Select Case Choices

Another option of Select Case shows that you can test for a range of values on each line of Case. You can use the To keyword in a Case statement to specify a range of values that Visual Basic checks to determine which Case executes. This capability is useful when possibilities are ordered sequentially, and you want to perform certain actions if one of the sets of values is chosen. The first expression (the one to the right of To) must be lower numerically-or as determined by the sort order if it's string data-than the second expression.


Put the most likely Case selection at the top of the Case for efficiency. Visual Basic then doesn't have to search down the list as much.

Listing 10.6 shows the same age-testing procedure as the Listing 10.5, except that a range of ages is tested with the To keyword instead of a conditional test.

Listing 10.6 AgeTest2.bas: Testing for an Age with a Select Case Range Test

Private Sub ageTest ()

' Procedure to describe legal vehicles based on age

  Dim intAge As Integer

  Dim msg As Integer

  intAge = InputBox("How old are you?")

  Select Case intAge

    Case 1 To 13

      msg = MsgBox("You can only ride a bike.")

    Case 14 To 15

      msg = MsgBox("You can ride a motorcycle.")

    Case 16 To 99

      msg = MsgBox("You can drive a car")

    Case Else

      msg = MsgBox("You typed a bad age.")

  End Select

End Sub
<

This procedure ensures that anyone aged 16 or older is told that he or she can drive a car. Any ages that don't match a Case, such as 0 and negative ages, trigger an error message.

Example

Select Case is great for handling user selections. The procedure in Listing 10.7 is a math tutorial, which asks for two numbers and then asks users which type of math to perform with the numbers.

Listing 10.7 Mathtry.bas: Use Select Case to Handle Decisions

Private Sub mathPractice ()

' Procedure to practice math accuracy

  Dim intNum1, intNum2 As Integer

  Dim strOp, strAns As String

  Dim msg As Integer   ' MsgBox() return

  intNum1 = InputBox("Please type a number")

  intNum2 = InputBox("Please type a second number")

  ' Find out what the user wants to do with the numbers

  strOp = InputBox("Do you want +, -, *, or / ?")

  ' Perform the math    

  Select Case (strOp)

    Case "+"

      strAns = Str(intNum1 + intNum2)  ' Make answer a string

      msg = MsgBox(Str(intNum1) & " plus" & Str(intNum2) & " is" & strAns)

   Case "-"

      strAns = Str(intNum1 - intNum2)  ' Make answer a string

      msg = MsgBox(Str(intNum1) & " minus" & Str(intNum2) & " is" & strAns)

   Case "*"

      strAns = Str(intNum1 * intNum2)  ' Make answer a string

      msg = MsgBox(Str(intNum1) & " times" & Str(intNum2) & " is" & strAns)

   Case "/"

      strAns = Str(intNum1 / intNum2)  ' Make answer a string

      msg = MsgBox(Str(intNum1) & " into" & Str(intNum2) & " is" & strAns)

   Case Else

      Beep

      MsgBox("You didn't enter a correct operator.", vbExclamation)

   End Select

End Sub
<

This Select Case statement demonstrates that string expressions work as well in Select Case statements as integer expressions.

Never use a floating-point expression for a Select Case match, because it's extremely difficult to store and match exact floating-point quantities. Stick to integer and string expressions for Select Case.

The Str() expression used in Listing 10.7 is probably new to you here. The MsgBox() function requires a string expression, but MsgBox() is used in Listing 10.7 to display the result of a mathematical expression. Therefore, the answer to the expression, stored in strAns, is converted to a string with Str() before being concatenated to other strings in the MsgBox() message.


If users enter an operator other than +, -, *, or /, Case Else takes over and displays an error box.

Next Step

Visual Basic provides a great deal of customization for Select Case statements. You can combine any and all of the previous Select Case formats into a single Select Case statement.

The following sample Case statements show you how you can combine different formats:

Case 5, 6, 7, 10

Case 5 To 7, 10

Case "A", "a", "K" To "P", "k" To "p"

Case 1, 5, 10, Is > 100, amount To quantity
<

The Select Case statement in Listing 10.8 calculates overtime payroll figures based on the hours worked. Such decision-based calculations are difficult to provide in Visual Basic without your using Visual Basic's control statements such as Select Case.

Listing 10.8 OTselect.bas: Computing Overtime with Select Case

Select Case (intHours)

   Case 1 To 40

      sngOverTime = 0.0

   Case 41 To 49

     ' Time and a half

     sngOverHrs = (hours - 40) * 1.5

     sngOverTime = sngOverHrs * sngRate

   Case Is >= 50          

     ' Double time for hrs over 50 and

     ' 1.5 for 10 hours

      sngOverHrs = ((intHours - 50) * 2) + (10 * 1.5)  

      sngOverTime = sngOverHrs * sngRate

End Select
<

The Select Case variable intHours was put in parentheses to make it stand out better.

Summary

You now have tools you can use to write powerful programming statements. With the If statement, you can perform a block of statements only if a certain conditional is true. By adding the Else option, you can specify the block of code to execute if the conditional is false.

This lesson described more ways you can test for data values and data types. By using the Is...() inspection functions, you can determine whether a data value is a date, empty, Null, or a number so that your code can operate accordingly. The IIf() is a shortcut form of If. Although IIf() will never replace the more readable If statement, IIf() is useful (and efficient) for coding simple decision statements that have a true part and a false part.

The VarType() function is extremely useful for functions that can work with more than one data type. By first determining the data type, a subsequent If can then select the appropriate code to execute. The Choose() function returns a value based on an index, simulating the effect of a lookup table.

Select Case has several syntaxes. You can write the statement so that a Case match is made based on a single integer or string value. You also can use the Is keyword to select from a case based on a conditional expression. With the To keyword, you can select from a range of values. Also, you can combine all the formats of Case into a multiple-part Select Case statement.

Now that you can test data and execute code based on the results of the test, you're ready to learn how to make the computer really work! Next hour's lesson explains how to instruct Visual Basic to repeat lines of code several times when you want to process several occurrences of data.

Hour 10 Quiz

  1. True or false: Visual Basic is fun! prints on-screen when the following statement is executed:
If (54 <= 50) Then

  msg = MsgBox("Visual Basic is fun!", vbOKOnly)

End If
<
  1. True or false: If a decision (made by a conditional test) has more than one possible result, you can use an If...ElseIf.
  2. Find the error in the following code:
intA = 6   ' a is an integer variable

If (intA > 6) Then

   msg = MsgBox("George", vbOKOnly)

Else If (intA = 6) Then

   msg = MsgBox("Henry", vbOKOnly)

Else If (intA < 6) Then

   msg = MsgBox("James", vbOKOnly)

End If
<
  1. What's the shortcut for the If statement?
  2. True or false: You can use a data-inspection function to see whether a variable holds a string value.
  3. What happens if the first argument of Choose() is less than 1?
  4. What's an advantage of Select Case over If...ElseIf statements?
  5. True or false: The Case Else statement is optional.
  6. Which keyword of Select Case-Is or To-lets Select Case select from a range of values?
  7. True or false: The following Case statement contains an error:
Case Is 34 To 48
<

Hour 10 Homework Exercises

  1. Write a simple procedure (using InputBox()) that asks users for the previous five days' temperatures (stored in the Single variables sngT1, sngT2, sngT3, sngT4, and sngT5). Compute the average temperature and print (by using MsgBox) "It's cold!" if the average is less than freezing.
  2. Rewrite the following If statement as an IIf() function call:
If (total > 10000) Then

   Bonus = 50

Else

   Bonus = 5

End If
<
  1. Rewrite the following If statement by using a Choose() function:
If (ID = 1) Then

   bonus = 50

ElseIf (ID = 2) Then

   bonus = 75

ElseIf (ID = 3) Then

   bonus = 100

End If
<
  1. Write a Choose() function that returns the VarType() descriptions based on a data-type number used as the first argument. That is, if the first argument of Choose() is 0, add 1 to it to get 1, and return the first expression, Empty.
  2. Rewrite the following nested If...ElseIf by using Select Case:
If (intA = 1) Then

   MsgBox("Ok")

ElseIf (intA = 2) Then

   MsgBox("No way")

ElseIf (intA = 3) Then

   MsgBox("There's a problem.")

End If

  1. Write a Select Case statement that asks users for the name of the month and prints Happy Hot Summer! if the month is a summer month, Stay Warm! if the month is in winter, and Enjoy the Weather! if the month is a month other than a summer or winter month. (If the user lives in Hawaii, the user has to suffer through 12 months of bliss, so this application doesn't apply there.)

© 1997, QUE Corporation, an imprint of Macmillan Publishing USA, a Simon and Schuster Company.