Conditional Statements in Visual Basic
By Herbert J. Bernstein
© Copyright 1999 Herbert J. Bernstein
The basic structure of a conditional statement block in Visual Basic is:
If ( expression ) Then
Statements
End If
Or
If ( expression ) Then
Statements
Else
Statements
End If
The expression is evaluated. If the resulting value is non-zero, the statement(s) after the Then are executed. If there is an Else and if the expression evaluated to zero, the statement(s) after the Else are executed.
Nested If blocks may be given a single EndIf by combining Else with an immediately nested If in the form ElseIf.
The expression may be constructed from sub-expressions using the logical operators And true if both operands are true), Or (true if either operand is true), Not (true if the operand is false), Xor (true if one operand is true and the other is false), Eqv (true if boh operands are true or if both operands are false), Imp (false if the lefthand operand is true and the righthand is false). The logical operators are applied after all other operators (in the order Not, And, Or, Xor, Eqv, and Imp) in order to allow a natural ordering of terms, but the explicit use of parentheses is highly recommended.
Some complex nested If statement blocks may better be expressed as a Select Case block
Select Case ( expression )
Case value_1_1, value_1_2,
Statements_1
Case value_2_1, value_2_2,
Statements_2
Case value_3_1, value_3_2,
Statements_3
Case Else
Statements_default
End Select
This has essentially the same meaning as meaning as
If ( expression = value_1_1 Or expression = value_1_2 Or ) Then
Statements_1
ElseIf ( expression = value_2_1 Or expression = value_2_2 Or ) Then
Statements_2
ElseIf ( expression = value_3_1 Or expression = value_3_2 Or ) Then
Statements_3
Else
Statements_default
End If
Ranges are allowed for values using "To" and "Is", in the forms
Value_1 To Value_2
or
Is RelOp Value
Where RelOp is a relational operator (<, <=, >=, >)
To help understand the uses of conditional statements, let us consider a simple program which accepts strings of digits and which reports the equivalent integer numeric value:
Private Function myatoi(xstring$) As Long
Dim ipos As Integer ' position within string
Dim idig As Integer ' current numeric digit
Dim char as String ' next character from string
ipos = 0
myatoi = 0
While (ipos < Len(xstring))
ipos = ipos + 1
c = mid$(xstring,ipos,1)
Select Case (c)
Case "0"
idig = 0
Case "1"
idig = 1
Case "2"
idig = 2
Case "3"
idig = 3
Case "4"
idig = 4
Case "5"
idig = 5
Case "6"
idig = 6
Case "7"
idig = 7
Case "8"
idig = 8
Case "9"
idig = 9
Case Else
idig = -1
End Select
If (idig = -1) Then
Exit Function
Else
myatoi = myatoi*10 + idig
End If
Wend
End Function
Private Sub Command1_Click()
Picture1.Cls
Picture1.Print myatoi(Text1.text)
End Sub
This program takes a very naïve approach to the characters in the input string, making no assumptions about the collation sequence of digits and not making use of library routines to help in what it is doing to the digits. A real program would use of Val and other library routines, but this simple application helps us to see the pwer of the switch statement in simplifying the presentation of complex conditionals.
The first version of this program lacks some useful features. It does not handle signs, and it only handles integers. Let us add handling of signs first. We add a case for the two possible sign symbols, '-' or '+', and test if we previously had a sign, making use of conditional statements to distinguish the two signs, and adding a conditional statements on some of the returns to allow for three cases: no sign given, '-' given or '+' given.
Private Function myatoi(xstring$) As Long
Dim digfound As Integer ' flag for digit found
Dim isign as Integer ' flag for sign
' 0 = not found, 1 = '+', -1 = '-'
Dim ipos As Integer ' position within string
Dim idig As Integer ' current numeric digit
Dim char as String ' next character from string
digfound = 0
isign = 0
ipos = 0
myatoi = 0
While (ipos < Len(xstring))
ipos = ipos + 1
c = mid$(xstring,ipos,1)
Select Case (c)
Case "0"
idig = 0
digfound = 1
Case "1"
idig = 1
digfound = 1
Case "2"
idig = 2
digfound = 1
Case "3"
idig = 3
digfound = 1
Case "4"
idig = 4
digfound = 1
Case "5"
idig = 5
digfound = 1
Case "6"
idig = 6
digfound = 1
Case "7"
idig = 7
digfound = 1
Case "8"
idig = 8
digfound = 1
Case "9"
idig = 9
digfound = 1
Case "-", "+"
If (isign = 0 And digfound = 0) Then
If (c = "-") Then
isign = -1
Else
isign = +1
End If
Else
If (isign <> 0 ) Then
myatoi = isign*myatoi
End If
Exit Function
EndIf
Case Else
idig = -1
End Select
If (idig = -1) Then
If (isign <> 0 ) Then
myatoi = isign*myatoi
EndIf
Exit Function
Else
myatoi = myatoi*10 + idig
End If
Wend
If (isign <> 0 ) Then
myatoi = isign*myatoi
End If
End Function
Private Sub Command1_Click()
Picture1.Cls
Picture1.Print myatoi(Text1.text)
End Sub
The last version of this program will accept a decimal point. We now process numbers as double instead of as int. Just as a second sign or a sign after digits terminate the number, so will multiple decimal points. We have introduced a function, condexp, which takes three arguments, an expression to evaluate, and two possible return values. If the expression evalutes to non-zero, the first value is returned, otherwise the second
Private Function condexp(condition, exp1, exp2) As Variant
If (condition) Then
condexp = exp1
Else
condexp = exp2
End If
End Function
Private Function myatod(xstring$) As Double
Dim digfound As Integer ' flag for digit found
Dim isign As Integer ' flag for sign
' 0 = not found, 1 = '+', -1 = '-'
Dim decpos As Integer ' position after the decimal point
Dim xpow10 As Double ' next (negative) power of ten
Dim ipos As Integer ' position within string
Dim idig As Integer ' current numeric digit
Dim char as String ' next character from string
digfound = 0
isign = 0
decpos = 0
xpow10 = 1.#
ipos = 0
myatod = 0.#
While (ipos < Len(xstring))
ipos = ipos + 1
c = mid$(xstring,ipos,1)
Select Case (c)
Case "0"
idig = 0
digfound = 1
Case "1"
idig = 1
digfound = 1
Case "2"
idig = 2
digfound = 1
Case "3"
idig = 3
digfound = 1
Case "4"
idig = 4
digfound = 1
Case "5"
idig = 5
digfound = 1
Case "6"
idig = 6
digfound = 1
Case "7"
idig = 7
digfound = 1
Case "8"
idig = 8
digfound = 1
Case "9"
idig = 9
digfound = 1
Case "."
If ( decpos = 0 ) Then
idig = 0
digfound = -1
decpos = decpos+1
xpow10 = xpow10/10.#
Else
If ( isign <>0 ) Then
myatod = CDbl(isign)*myatod
Exit Function
EndIf
EndIf
Case "-", "+"
If (isign = 0 And digfound = 0) Then
isign = condexp( (c = "-") , -1, 1)
Else
If (isign <> 0 ) Then
myatod = CDbl(isign)*myatod
End If
Exit Function
EndIf
Case Else
idig = -1
End Select
If (idig = -1) Then
If (isign <> 0 ) Then
myatod = CDbl(isign)*myatod
EndIf
Exit Function
Else
If (digfound > 0) Then
If ( decpos = 0 ) Then
myatod = myatod*10.# + CDbl(idig)
Else
myatod = myatod + CDbl(idig)*xpow10
decpos = decpos +1
xpow10 = xpow10/10.#
End If
End If
End If
Wend
If (isign <> 0 ) Then
myatod = CDbl(isign)*myatod
End If
End Function
Private Sub Command1_Click()
Picture1.Cls
Picture1.Print myatod(Text1.text)
End Sub