VB Control Constructs

 

     Even when giving simple directions we find ourselves talking in terms of repetitive action, testing for a condition and points of decision.  We may say things like,

            Walk down this street until you see the bank, or

            If you come to a bridge, you’ve gone too far.  Go back 1/2 mile.

So it is not surprising that repetition, testing and decision points are key elements of program logic.

 

While this book is not meant to be a course in software engineering, as we get into the nitty-gritty of program development, it is good to get an overview of the standard program development process.  The steps listed in Table 4.0 are found, with some variation, in every introductory book in computer science.  It presents a different picture of software development

 

 

Software Development Cycle

 

          1. Analysis

                   Study the problem; understand the logic of the process.

          2. Design

                   Formulate an algorithm to implement the process.

          3. Coding

                   Translate the algorithm into a programming language

          4. Testing & Evaluation

                   Check the program :

                        Is it correct?  Are there any errors?

                        Does it accomplish its purpose?

          5. Maintenance

                   Make changes based on experience with program and

                   on changing requirements.

                       

Table 4.0


than many people have, one in which a gifted programmer just sits down and hacks out a marvelous piece of software.  Studies have consistently shown that in the actual working environment coding takes up only about 15-20% of a computer scientist’s time.

 

The first step, analysis, is to study the process that is to be automated and gain a clear understanding of it.  It is useless to produce a good answer to the wrong problem!  Then, one must carefully design a series of steps that will produce an efficient solution.  A poorly designed program may take hours to produce the same results that a well-designed program can produce in 15 or 20 minutes!  The third step, coding, is to translate the algorithm into computer code.  The keys to this step are to carry out the first two steps well and to have a strong grasp of the programming language being used.

 

Now comes perhaps the most difficult step of all - testing and evaluation (at least judging from the frequent crashes that software seems to be prone to).  Testing is partly an art and partly a developing science.  Its difficulty stems from two properties of most real world systems.  They are too large to allow the developer to try out all the avenues of computation that are possible for a given program.  And often they operate in changing environments in which the exact same conditions are rarely, if ever, repeated.  If the software system “acts strange” it may be very difficult to reproduce the same strange behavior in order to analyze it and pinpoint the source of the problem.

 

Once a system has been judged to be ready to be put into production, the software development cycle has not ended.  Conditions change.  For a payroll management system, for example, wages and tax laws change necessitating changes to the software system.  Or bugs may be revealed which must be found and fixed.  This is called the maintenance phase of the software system.

 

Algorithms

    

     After we have gained an understanding of the process we are trying to automate, the next step is to formulate an algorithm.  An algorithm is a complete, unambiguous, step by step description of how to accomplish a task.  The study of algorithms is the heart and soul of computer science.  There are many algorithms one can use for any given task.  Some are efficient, others are grossly inefficient.  If you are looking for peak performance from your programs you will need to immerse yourself in the study called the design and analysis of algorithms.  Most schools offer one or more upper level courses in this subject.

 

Our purpose is to gain an elementary understanding of this area of study.  Algorithms can be extremely complex.  But they can also be very simple.  They can have many branches or decision points.  Or they can be just a simple list of steps to be taken.  Here, for example, is a simple algorithm that one may follow on a school day morning:

 

            The Good Morning Algorithm

                        1. Shower

                        2. Dress

                        3. Have breakfast

                        4. Drive to school

 

Algorithms can be expressed in varying levels of detail.  The above algorithm, for example, leaves out many details, such as getting out of bed, walking down the hall, turning on the shower, etc.  The level of detail provided by an algorithm depends on the person for whom the algorithm is intended.  Only as much detail should be given as needed by the intended user.  On the other hand, no details should be left out which the intended user would be unable to supply.

 

Most often algorithms contain decision points, such as this alternate Good Morning Algorithm.

            1. Shower

            2. Dress

            3. Make breakfast

               a. If there are eggs in the house, make scrambled eggs & toast

               b. Otherwise, pour cereal & milk into bowl

            4. Eat breakfast

            5. Drive to school

 

In terms of computer languages, this illustrates the If-Then-Else construct which we will be looking at soon.  Notice that after either the if or the else part of the branch is taken, the algorithm continues on with the next step in the process.

In addition to decision points, algorithms often contain loops.  Rare is the program that can be written without some form of repetition.  An example is given below in yet another version of the Good Morning Algorithm.

 

            1. Shower

            2. Dress

            3. Make breakfast

               a. If there are eggs in the house, make scrambled eggs & toast

               b. Otherwise, pour cereal & milk into bowl

            4. Eat breakfast

            5. If it snowed last night clear driveway

               a. Get shovel from tool shed

               b. Repeat until driveway is clear

                  i. Scoop snow from driveway into shovel

                  ii. Dump snow away from driveway

            6. Drive to school

 

Notice that a termination condition for the repetitive action is included in the algorithm, namely that the driveway is clear.  Termination conditions are an important part of algorithms for repetitive processes.  We will have more to say on that later.

 

All of the standard computer languages have several constructs for coding repetitive processes, as does also Visual Basic.  We will be looking at several of these when we consider VB control constructs.  Keep in mind that VB also has hidden repetitive constructs, including the event-wait loop and the timer control.

 

Control Constructs

    

     To translate the repetition, testing and decision points contained in an algorithm, all programming languages provide the programmer with control constructs, so called because they are used to control execution flow within the program, as specified by the algorithm.  In Chapter Three we divided units of execution into two categories, bounded and unbounded.  The bounded units are event procedures, general procedures, and functions.  The control constructs allow the programmer to define unbounded units of execution.  We also referred to macro and micro program logic.  Procedures and functions are used to code macro program logic.  Control constructs, however, are used for micro program logic.

 

A full study of every VB control construct is beyond the scope of this book.  We will study the standard ones in their most frequently used forms, using flow charts to describe the execution flow produced by each of them.  Our flow charts will have three types of objects:  arrows, rectangles and diamonds.  The arrows show direction of execution flow.  The rectangles show that a segment of a program is executed as one unit.  The diamond shape is used to represent tests or decision points.  This will be easy to remember, if you will just keep in mind the phrase, “Diamonds are for decisions.”  When a young man gives a young lady a diamond, it means he has made a decision.  When the young woman accepts that diamond, she has made a decision.

 

Syntax

     To correctly use the Visual Basic control constructs it will not be sufficient to understand the execution flow produced by each.  In addition, we will need to master the required syntax.  Each programming language has strict rules that the programmer must follow, similar to the grammar rules of the languages we speak.  Collectively, these rules are called syntax.  We will not study the full set of Visual Basic rules, which are quite complicated, but rather the basic ones.  We will find that they are more than adequate for writing our programs.

 

The language Visual Basic is line-oriented, meaning that, normally, it expects each line to contain one statement, keyword or phrase.  Each statement should be one line and each line should contain only one statement.  Although there are exceptions to this rule, to take advantage of them would require us to learn a more complicated version of VB syntax.  Normally, lines can be up to 1023 characters in length.  Up to 10 lines can be strung together, using a blank followed by underscore (  _) as the line-continuation symbol, to make a super-long line of up to 10,230 characters.

 

As we begin our study, you will be happy to know that the execution flow diagrams are fairly universal.  Although syntax varies widely from one language to another, the execution flow for the standard control constructs does not.  These same diagrams, for example, can be used in a study of the programming language C.

 

If-Then

     A good place to start our study of control constructs is the If-Then, which is used to implement the most basic of decision points.  Conceptually, the If-Then is composed of two parts:  the test and the action.  A test is performed to determine whether a certain condition is present.  If it is then the action is taken.  If the test fails no action is taken.  In terms of program execution, we simply proceed on to the next line of code.

 

This is illustrated by the flow chart in Figure 4.0.  If we start at the arrow at the top of the diagram we are led immediately to the decision point labeled

Test.  The diamond representing the test (diamonds are for decisions!) has two arrows leaving it.  We follow the one labeled True if the test succeeds and the one labeled False if it does not.  The rectangle labeled Statement(s) represents the action to be taken if the test succeeds.  Notice that, regardless of whether we follow the True arrow or the False one,  we wind up at the same place, namely the exit point from the construct.  When the exit point is reached, whether by one route or the other, the program goes on to execute the next line of code.

 

Turning now to the syntax, the left hand column gives the general form of the If-Then construct, while the right hand one gives an example.  Notice that you need to have the keyword If, followed by the condition, followed by the keyword Then, all on one line.  On the next and subsequent lines are the statements describing the action to be taken.  Then come the keywords End If, marking the border between the then-action and the code to follow.  If the then-action consists of only one statement, you can place the If, the condition, the Then, and the then-action statement all on one line, as in the example below.

          If principal <= 0 Then mopay = 0

In that case do not use End If, or Visual Basic will signal an error.  The test condition in Figure 4.0

          principal <= 0

uses some symbols (<=) we have not yet seen.  These are comparison

 


 

 

If-Then

  Syntax ::

 

          If condition Then                Example ::

             statement1                              If principal <= 0 Then

            ...                                              mopay = 0

            statementn                                  done = true

          End If                                       End If

                     

  Execution Flow::

           

 

Figure  4.0

 

 

 


 

operators, which we will study in the next chapter.  You may turn there for more information on these operators, if the examples are not clear - though that probably will not be necessary.

 

If-Then-Else

     Often when at a decision point we have in mind two actions, one to take if the test succeeds, the other to take if the test fails.  In the Good Morning Algorithm, for example, we made scrambled eggs if there were eggs in the house (the test), but otherwise had cereal for breakfast.  The If-Then-Else, construct, described in Figure 4.1, gives us the option of specifying two actions.  Conceptually, it is composed of three parts, the test, the then-action, and the else-action.  As before, a test is performed to determine whether a certain condition is present.  If the condition is present (the test succeeds) the then-action is carried out.  Otherwise, the else-action is carried out.  After the one or the other action is taken (never are they both taken), program execution proceeds to the next line of code.

 

Looking at the flow chart, we again follow the initial arrow directly into the Test diamond, which again has two arrows leaving it.  The difference is that we next proceed to one of the two rectangles, the Then Statement(s) or the Else Statement(s).  After that both paths converge at the exit point for the construct.

 

The syntax is very similar to that for the If-Then.  The only difference is that immediately following the statements of the then-action comes the keyword Else, on a separate line, followed by the statements of the else-action, and concluded, as before, with the keywords End If.  Again, if both the then-action and the else-action are each only a single statement, the entire If-Then-Else can be placed on one line, but without the End If, as in the example below.

          If balance > 0 Then tospend = balance Else toborrow = 500

 

 

 

 

 

 

 

If-Then-Else

 

  Syntax ::                              Example ::

 

          If condition Then            If balance > 0 Then

             statementt1                                tospend = balance

            ...                                    salary_request = 2 * salary

            statementtn                    Else

          Else                                  tospend = 0

             statemente1                      toborrow = 500

             ...                                End If

             statementem        

          End If                  

                     

  Execution Flow::

 

         

 

 

Figure  4.1

 

While-Wend

     Useful as the two previous constructs are, we are still missing an essential feature of many descriptions of process - repetition.  Many tasks, explicitly or implicitly, involve repetition.  For example, in a cookbook you may read the instruction,

          Beat egg whites until they are fluffy.

 

Visual Basic provides three constructs, While-Wend, Do-Until and For-Next, which enable the programmer to specify repetitive action.  First, let’s look at the While-Wend, which is described in Figure 4.2.  Conceptually, this construct has only two parts but the flow of execution determined by the arrows creates a loop.  Once again, the initial arrow leads directly into the test of a condition.  The Test diamond has two arrows leaving it.  The one labeled False takes us out of the loop and on to the next line of code.  The True arrow leads to the rectangle labeled Statement(s).  This part of the code is often referred to as the loop body.  Unlike the very similar If-Then diagram, the arrow leaving the rectangle goes back to the test diamond, closing the loop.  The effect produced is that execution of the loop body is repeated until the test fails.  Of course, if the test fails upon initial entry, then the loop body is never executed.

 

The syntax is fairly simple.  The first line contains only the keyword While followed by the test condition.  Below that come one or more statements which comprise the loop body.  The end marker for this construct is the keyword Wend which, of course, stands for While End.  If the loop body consists of a single statement, can we, as we did before, place everything on one line?  No.  If we try, Visual Basic will signal an error.

 

An important point to remember is that it is the programmer's responsibility to guarantee that the test will eventually fail.  Otherwise, our program will be stuck in an infinite loop.  Within the loop body some change must be made to one of the variables involved in the test.  Usually this would bring us step by step to the point at which the test fails and we exit the loop, although, logically, such a progression is not required.  Still, whether by progression or all in one fell swoop, we must guarantee that at some point the test will fail.  It is surprisingly easy for a while loop not to meet that requirement.  For example, if in the sample program of Figure 4.2 the interest rate (irate) were too high, causing the interest payment (ipay) to

 

 

 

 

While-Wend

 

  Syntax ::

          While condition              <==  Notice ::  continuation test

             statement1

             ...

             statementn

          Wend

 

  Example ::

          While principal > 0

             principal = principal - prpay

             ipay = irate * principal

             prpay = mopay - ipay

          Wend

 

  Execution Flow ::

                       

Figure  4.2

exceed the monthly payment (mopay), nothing would be paid on principal each month and the loan would never be repaid.  The loop design requires that the payment on principal (prpay) be a positive number, guaranteeing that in the first line of the loop body the value of principal would get progressively smaller.  This, in turn, would guarantee that the test condition would eventually fail and the program would exit the loop.  Of course loan payments are structured that way, so for realistic loans the program segment would work fine.  This illustrates, though, how easily infinite loops can occur.  The programmer must always be on guard against them.

 

What can you do if you think that your program is in an infinite loop?  If the End icon of Visual Basic is visible, click on it.  If not, try pressing Ctrl-Break (that is, while holding down the Ctrl key, press the Break key).  The Break key is usually on the top row of keyboard to the extreme right.  It may have the word Pause above a line and the word Break below the line.  If that does not work, if the Start icon is visible on the screen, click on it and choose Shutdown.  It is not a good idea to turn off the power, since many operating systems must perform bookkeeping functions before shutting down.

 

You may have noticed an arrow in the syntax section of Figure 4.2 with the words: Notice: continuation test.  Loop tests are of two types, continuation tests and termination tests.  If the construct requires a continuation test, then the program continues in the loop as long as the test condition is true.  On the other hand, if the test is a termination test, then the program terminates or ends the loop when the test condition is true.  This distinction is important because the programmer must know how to write the test condition - one way for a continuation test and differently for a termination test.

 

When describing a process in everyday life, we will most often use a termination test.  In the example with which we started the chapter,

            Walk down this street until you see the bank

we are describing a repetitive action (walking) and stating a condition for the termination of this action (seeing the bank).  For this reason, when translating an algorithm to code we must ask, for each loop in the algorithm, whether the test is a continuation or a termination test.  If it is a termination test, that does not mean that we cannot use the While-Wend construct.  We can, if we convert the termination test to a continuation test by coding its logical negation.

 

 

Do-Until

 

  Syntax ::                                        Example ::

 

          Do                                           Do

             statement1                                x = 5 * z

             ...                                            y = y + x

             statementn                             Loop Until  y  >  w

          Loop Until condition      <==  Notice ::  termination test

 

  Execution Flow ::

 

                       

Figure  4.3

 

 

 

     Loop tests are also classified according to when the test occurs.  For the While-Wend this occurs at the very outset, prior to execution of the loop body.  This is called a pretest.  The Do-Until construct, on the other hand, places the test following the loop body.  This is called a post-test.

 

Do-Until

     The Do-Until construct is very much like the While-Wend.  It differs from its cousin in two respects.  The placement of the test is in the post-test position and the test must be written as a termination test.  Like the While-Wend, conceptually it has two parts, the loop body and the condition test.  From Figure 4.3 we see that the initial arrow leads directly into the rectangle labeled Statement(s), which represents the loop body.  From there control passes to the Test diamond.  The arrow labeled True exits from the construct, while the arrow labeled False leads back to the loop body, completing the loop.  Thus, it is a termination test since it keeps looping as long as the test condition fails, but exits as soon as the test succeeds.

 

The syntax is simple.  The construct starts with the keyword Do by itself on a line.  Following that is the loop body consisting of one or more statements.  The closing line consists of the keyword Until followed by the test condition.

Since, when describing repetitive processes, we tend to state the test condition in the form of a termination, the Do-Until is a natural construct to use.  We must be careful, however, since, being also post-test in form, the loop body will be executed at least once, not matter what the conditions are initially.  If, for our particular application, there are times when we want to completely prevent execution of the loop body, this would not be the construct of choice.

 

Except for the pre-test/post-test difference, the While-Wend and the Do-Until can be used interchangeably.  To convert from one to the other, use the logical negation of the test condition.  The code sample code of Figure 4.2 could be written using the Do-Until as below.

          Do

             principal = principal - prpay

             ipay = irate * principal

             prpay = mopay - ipay

          Until principal <= 0


Notice that the line:

          While principal > 0

has been converted to:

          Until principal <= 0

 

For-Next

     Easily the most complicated looping construct, both syntactically and with respect to execution flow, is the For-Next.  Conceptually, it consists of four parts: initialization, test, loop body, and incrementation.  Looking at Figure 4.4, the beginning arrow leads to the rectangle labeled Initialization which, in turn, leads to the Test diamond.  The arrow labeled False exits the construct.  The arrow labeled True leads to the loop body.  From the loop body we move to the rectangle labeled Incrementation.  Then control passes back to the test, completing the loop.

 

The syntax is also more complicated than in the other looping constructs.  The first line begins with the keyword For followed by an assignment.  A variable, called the loop index, is assigned a value, which we will call the initial value.  Then comes the keyword To followed by another value, which we will call the final value.  This is all on the first line.  On subsequent line(s) come one or more statements of the loop body.  Marking the end of the construct is a line containing the keyword Next followed by the loop index identifier.

 

The For-Next is a count-controlled loop and the key to understanding its operation is the loop index, also called the loop control variable, LCV, loop counter, or simply counter.  When execution of this construct begins, the loop index variable is set to the initial value and the test condition is established.  This test condition, for the standard case, is

          Loopindex <= FinalValue

In other words, the loop will continue executing as long as the value of the loop index is less than or equal to the prescribed FinalValue.

 

Once the loop has been initialized in this way, the loop operates similarly to a While-Wend loop with one step added.  Being a pretest loop, the test condition is checked.  If the test succeeds, the loop body is executed.  Following that, the loop index is incremented.  This means that a set value is automatically added to the loop index.  Unless otherwise specified, this value is 1.  For example, if the loop index has a value of 5 at this point in the

 

For-Next

 

  Syntax ::

          For LoopIndex = InitialValue To FinalValue

             statement1

            ...                                           Example ::

            statementn                               For i = 1 to number

          Next LoopIndex                           fact = fact * i

                                                             frmFact.print fact

                                                          Next i                    

  Execution Flow ::

 

                       

Figure  4.4

 

 

execution, its value is automatically set to 6.  Clearly, this automatic incrementation, on each pass through the loop, brings the value of the loop index closer and closer to the final value.  When the final value is reached (or exceeded) the test fails and the program exits the loop.

 

If we write code for doing initialization and incrementation and write our test condition based on a loop index, we can reproduce the logic of a For-Next with  the While-Wend or Do-Until.  For example, the code below is equivalent to the sample code of Figure 4.4.

          i = 1

            While i <= number

                fact = fact * i

                frmFact.Print  fact

            Wend

 

The loop counter can play two distinct roles in this construct.  First, it is a counter keeping track of how many times the loop is being executed.  Often that is all we need and we make no further use of it.  But it can also play a second role.  Being a variable it can actually enter into the computation performed within the loop body.  The sample code of Figure 4.4 computes the factorial of number and the loop counter, i, is used in that computation.

 

Being a variable, the loop index can also be changed within the loop body.  This is not recommended, however, as it violates the principles of modular design.

 

The For-Next has many additional features.  For example, the programmer can specify the amount of the incrementation with the keyword Step.  Giving Step a negative value would cause the loop to count down instead of up.  Some of these features will be explored in labs.  Others will be left to the adventurous soul to try out on her own.  If you are inclined to such exploration, you may wish to start with the code below.

            Private Sub cmdTestFor_Click()

              Dim val As Single

                For val = 1.3 To 27.4 Step 1.7

                  frmTest.Print val

                Next val

            End Sub


Sel