On completion of this chapter you will know how to make the programme
perform more complex decisions using the case
construct
The If..Else construct is fine when we have only to choose
between two alternatives as above. On the other hand if we have to choose
between a larger number of alternatives, the If..Else
construct, even though it can handle the situation, can be very clumsy. In this
situation we use the Select Case
construct.
In order to explore this construct we shall extend our payroll
application further so that it can handle superannuation calculation.
Superannuation calculation normally involves taking a percentage of an
employee’s pay and putting it into his superannuation account. We shall devise
a way of calculating this upper contribution. Each employee is given a super
code number and this number determines the percentage of his gross that will be
deducted and put into his super account. In our case the percentage taken will
be according to the following table:
Listing 5‑1
|
Superannuation code |
Percentage |
|
0 |
0% |
|
1 |
5% |
|
2 |
7% |
|
3 |
10% |
|
4 |
20% |
What this means is that if the superannuation code is 0 then the
employee pays no superannuation, whereas if the superannuation code is 1 then
the employee pays 5% of his gross pay towards the superannuation. The same
applies for the other possible values of the superannuation code.
On the other hand, if the value for superannuation is any number other
than those in the range 0 – 4, then calculation of the payroll ceases and a
message is printed indicating that faulty data has been entered.
The modified code appears below in Listing 5‑2.
Listing 5‑2
|
1 |
Sub
Pay() |
|
2 |
Dim sngHours As Single |
|
3 |
Dim curRate As Currency |
|
4 |
Dim curGross As Currency |
|
5 |
Dim curTax As Currency |
|
6 |
Dim curNett As
Currency |
|
7 |
Dim curSuper As Currency |
|
8 |
Dim intSuperCode
As Integer |
|
9 |
sngHours = InputBox("Enter Hours
worked") |
|
10 |
curRate = InputBox("Enter
Rate") |
|
11 |
intSuperCode =
InputBox("Enter superannuation code") |
|
12 |
curGross = sngHours * curRate |
|
13 |
If curGross <= 500 Then |
|
14 |
curTax = curGross * 0.25 |
|
15 |
Else |
|
16 |
curTax = 125 + (curGross - 500) *
0.33 |
|
17 |
End If |
|
18 |
Select Case intSuperCode |
|
19 |
Case 0 |
|
20 |
curSuper = 0 |
|
21 |
Case 1 |
|
22 |
curSuper = curGross * 0.05 |
|
23 |
Case 2 |
|
24 |
curSuper = curGross * 0.07 |
|
25 |
Case 3 |
|
26 |
curSuper = curGross * 0.1 |
|
27 |
Case 4 |
|
28 |
curSuper = curGross * 0.2 |
|
29 |
Case Else |
|
30 |
Debug.Print "Faulty data
entered for super code" |
|
31 |
End |
|
32 |
End Select |
|
33 |
curNett =
curGross - curTax - curSuper |
|
34 |
Debug.Print "Gross ", curGross |
|
35 |
Debug.Print "Tax", curTax |
|
36 |
Debug.Print "Super", curSuper |
|
37 |
Debug.Print "Nett",
curNett |
|
38 |
End Sub |
The first change we notice here is that two new variables have been
added. At line 7 a new Currency
variable – curSuper has been added and at line 8 an Integer variable – intsuperCode has
been added. There is no further change from Listing 4‑1 until we get to line 18. Here we meet the Select..Case construct. As with all of the constructs we have met so far
it starts with the name of the construct – Select
Case in this instance - and ends with End
followed by the name of the construct. In this example the construct starts at
line 18 and finishes at line 32. Lines 19-31 are the body of the construct and
for this reason they are indented one tab space beyond the Seelct Case and End Select.
There are further indentations but we shall look at those in a minute.
The code at line 18 – Select Case intSuperCode
– is equivalent to the statement check the value of the variable intSuperCode. Check it against what? At lines 19, 21, 23,
25 and 27 we have Case 0, Case 1
etc. These lines are equivalent to saying “if
the value of superCode is 0” or “if the value of superCode
is 1” etc. Thus the code at line 19 is equivalent to saying “if the value of intSuperCode
is 0 then execute the code at line 20”. If this is the case i.e. if intSuperCode is zero then the body of this Case is executed at line 20 and the
variable curSuper is given the value zero. At this stage no other
testing is made since a match has been found and so all of the other Case statements are ignored and control
passes to line 33 where execution of the rest of the code continues.
Of course if the value of intSuperCode is
not zero then line 20 is skipped and at line 21 the value for the same variable
is tested for being equal to 1. This skipping to each of the Case statements continues until a match
has been found. If, however, no match is found then testing finally arrives at
line 29 where we meet Case Else.
This is equivalent to saying “if the value
of intSuperCode is not 0, 1, 2, 3 or 4”. If this
is the case, or, in other words, if the value of intSuperCode
is a negative number or greater than 4 then the body of the Case Else is executed. This is the
lines 30 and 31. Line 30 simply states that a faulty value has been received
for the superannuation code and at line 31 the keyword End terminates the
execution of the programme.
Again notice the indentation of the code. Lines 18 and 32 begin and end
the Select Case construct and thus
they are at the same level of indentation as the main body of the code.
Everything between those two lines form the body of the construct and therefore
are indented at least one extra tab space. Lines 19, 21, 23, 25, 27 and 29 are
indented 1 tab space more than lines 18 and 32. Lines 20, 22, 24, 26, 28, 30
and 31 are indented two tab spaces. Line 20 is the body of the Case 0 construct which is why it is
tabbed one more space than line 19. Similarly line 22 is the body
of the Case 1 construct which
is why it is indented to the same level as line 20. The same applies to lines
24, 26, 28, 30 and 31
In the example above, for each different value of intSuperCode
a different action was performed. But what about if
superannuation was calculated at 5% if the value of the code was 1, 2 or 3.
The table below is an example of this situation.
Listing 5‑3
|
Superannuation code |
Percentage |
|
0 |
0% |
|
1 |
5% |
|
2 |
5% |
|
3 |
5% |
|
4 |
7% |
|
5 |
10% |
|
6 |
10% |
|
7 |
20% |
|
8 |
20% |
|
9 |
20% |
The modified code for the new Select
Case construct is shown in Listing 2‑5. The rest of the code both before and after
it has been omitted since it has not changed.
Listing 5‑4
|
1 |
Select
Case intSuperCode |
|
2 |
Case 0 |
|
3 |
curSuper = 0 |
|
4 |
Case 1, 2, 3 |
|
5 |
curSuper = curGross * 0.05 |
|
6 |
Case 4 |
|
7 |
curSuper = curGross * 0.07 |
|
8 |
Case 5, 6 |
|
9 |
curSuper = curGross * 0.1 |
|
10 |
Case 7, 8, 9 |
|
11 |
curSuper = curGross * 0.2 |
|
12 |
Case Else |
|
13 |
Debug.Print "Faulty data entered
for super code" |
|
14 |
End |
|
15 |
End
Select |
In the case where intsuperCode has a
value of 0 then there is no difference between this and the previous version.
On the other hand if intsuperCode has a value of
1, 2 or 3 then control enters at line 4 and only line 5 will be executed. After
this control will pass to the line after the End Select statement . Thus the Case
statement can trap more than one value. In order to specify the values we
simply enter them after the keyword Case
and separate them with commas.
If we wish to make a choice between two different pathways, depending on
the value of a condition then we use the if..else
construct. The body of the if is executed if the condition is true, otherwise the body of the else is executed. The bodies
of both can be as small as one line of code or as large as we wish.
If we wish to test a variable and take a number of different paths
depending on its value then we use the Select..case statement.
Programme testing involves running a programme, entering sample data and
check that the programme’s output is correct, or in
other words checking that the programme processes the data correctly.
In the case of Listing 5‑1 we would create a table as below and enter various
values for hours and rate. Next we would calculate the different values of
gross, tax and nett that the hours-rate combinations
would give us and enter those values under Expected output. Next we would run
the programme a number of times and each time enter
the values that the programme would calculate for us under Actual output.
Finally we would compare the data in Expected output and Actual output and if
they were the same then we would presume that our programme is processing the
data correctly.
Listing 5‑5
|
Input |
Expected output |
Actual output |
|||||
|
Hours |
Rate |
Gross |
Tax |
Nett |
Gross |
Tax |
Nett |
In Listing 5‑1 the gross is calculated by multiplying the hours
by the hourly rate. If the gross is 500 or less then the tax is calculated as
25% of the gross. On the other hand if the gross is greater than 500 then tax
is calculated as 25% of the first 500 and 33% of the remainder. Nett is calculated by subtracting the tax from the gross.
In the above table fill in your own data for hours and rate. Ensure that
some of the hours-rate combinations will give you a gross less than 500 and
that some will give a gross above 500. For each combination
of hours and rate work out the gross, tax and nett
using either pen and paper or a calculator. Enter those values under
Gross, Tax and Nett in the Expected Values part of
the table.
Now run the programme a number of times. Each time you run it enter one
of the hours-rate combinations and use the results to fill in the gross tax and
nett in the Actual output. Finally compare the data
in Expected output and Actual output.
Finally we shall look at testing the code in Listing 5‑2. For this create a table as shown below.
Listing 5‑6
|
Input |
Expected Output |
Actual Output |
||||||||
|
Hours |
Rate |
Super code |
Gross |
Tax |
Super |
Nett |
Gross |
Tax |
Super |
Nett |
This time enter values for hours, rate and super code. For the values in
super code ensure that you will only enter codes that are in the superannuation
reference table on Listing 5‑1.
1.
Describe the structure of the if..else construct.
2. In Listing 4‑1 state what lines would be executed and what lines
would be skipped if the user entered 20 for hours and 20 for rate.
3. Repeat the above for values of 30 for hours and 20
for rate.
4. Describe the structure of the Select..case construct.
5. In what situations would you use the Select..case construct instead of
the if..else construct?
6. In Listing 5‑2 what lines would be executed and what lines would
be skipped if the value of intsuperCode was 1.
7. Repeat the above for a value of 4 for intsuperCode.
Modify the code you created for Assignment Part 3 so that it can
accommodate a select case construct. The
method of calculating the discount is to be altered. Now the user will have to enter a discount
code into the system. He will be
prompted for this in the same way as for the amount sold and the unit
price. Discount will be calculated according
to the following table.
|
Discount Code |
Percentage |
|
1 |
0 |
|
2 |
3 |
|
3 |
7 |
|
4 |
10 |
The calculation of the total will remain the same as in Assignment Part
3.
In order to test the correctness of the code prepare test input data and
manually calculate what the output should be.
Now run the programme a number of times with the various input data sets
that you had prepared and check the output from the programme matches the
expected output every time.
Use Listing 5‑5 and Listing 5‑6 as models for
preparing your test data.