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