As programs become larger it become necessary to divide them into sub-tasks. This is necessary to:
So far we have indicated the sub-tasks in a program by separating it into sections, and used blank lines to separate these sections. However with the marks problem, validating the marks required the same code to be inserted in the program at different places (duplicate code). Inputting and validating a mark is an identifiable sub-task that could be written separately. A sub-program (called a subroutine or function in Basic) can be used to perform a sub-task. In this lecture we will look at writing subroutines and using pre-written functions.
Display a picture of a rocket composed of a triangle on top of two rectangles.
Run
* * * ***** ***** * * * * * * ***** ***** * * * * * * ***** * * * *****
displayRocket()
displayTriangle()
displayRectangle()
displayRectangle()
displayTriangle()
STOP
displayTriangle()
Display " *"
Display " * *"
Display "*****"
EXIT
displayRectangle()
Display "*****"
Display "* *"
Display "* *"
Display "* *"
Display "*****"
EXIT
displayRocket()
└───┐
displayTriangle() ────┐
displayTriangle()
Display " *"
Display " * *"
Display "*****"
EXIT
┌─────────────────────┘
displayRectangle() ───┐
displayRectangle()
Display "*****"
Display "* *"
Display "* *"
Display "* *"
Display "*****"
EXIT
┌─────────────────────┘
displayRectangle() ───┐
displayRectangle()
Display "*****"
Display "* *"
Display "* *"
Display "* *"
Display "*****"
EXIT
┌─────────────────────┘
displayTriangle() ────┐
displayTriangle()
Display " *"
Display " * *"
Display "*****"
EXIT
┌─────────────────────────┘
STOP
1 displayRocket() 2 displayTriangle() 3 displayRectangle() 4 displayRectangle() 5 displayTriangle() 6 STOP
7 displayTriangle() 8 Display " *" 9 Display " * *" 10 Display "*****" 11 EXIT
12 displayRectangle() 13 Display "*****" 14 Display "* *" 15 Display "* *" 16 Display "* *" 17 Display "*****" 18 EXIT
Data: none
' Name: displayRocket
' Purpose: Display a picture of a rocket
' Author: Tim Whitfort
Sub Main()
displayTriangle
displayRectangle
displayRectangle
displayTriangle
End Sub
' Display a triangle
Sub displayTriangle()
Debug.Print " *"
Debug.Print " * *"
Debug.Print "*****"
End Sub
' Display a rectangle
Sub displayRectangle()
Debug.Print "*****"
Debug.Print "* *"
Debug.Print "* *"
Debug.Print "* *"
Debug.Print "*****"
End Sub
Calling a subroutine is executing the subroutine (do the instructions specified
in the declaration)
Declaring a subroutine is stating what it will do if it is called (a set of
instructions)
sub-name()
sub-name()
statement
statement
...
EXIT
sub-name
Note: don't put () after the subroutine name when calling it.
Sub sub-name()
statement
statement
...
End Sub
In Basic, Main is a special subroutine. When a program is run it automatically runs the subroutine called Main. Main may then call other subroutines.
When variables are declared inside a subroutine they can only be used inside that subroutine. Each time the subroutine finishes running the values held in the variables are lost. These are known as local variables. So far we have used local variables. This has worked as we have had only one subroutine, called Main.
Variables that are declared outside of subroutines can be used throughout the whole program (module). The values held in the variables are remembered throughout the program run, and are lost when the program ends. Global variables are normally declared near the top of a program after the Option statements. Using global variables is one way to access variables that are used in more than one subroutine (other methods will be looked at in Programming Concepts).
Option Compare Database Option Explicit
' Declare global variables Dim global-variable1 As datatype
Sub Main()
' Declare variables local to Main
Dim local-variable1 As datatype
' Code for Main
OtherSub
End Sub
Sub OtherSub
' Declare variables local to OtherSub
Dim local-variable2 As datatype
' Code for OtherSub
End Sub
The club membership fee problem again with validation of input, and subroutines.
| Inputs | Processing | Output |
| membershipType | Input and validate the membershipType Determine the membershipFee Display membershipFee Total the membershipFees Display totalFees |
membershipFee totalFees |
A WHILE loop is required for the main loop, with a sentinel value of "X" for
the membershipType
A WHILE loop is required to validate the membershipType
Nested IFs are required to determine the membershipFee from the membershipType
smallest.
1 calcMembership() 2 totalFees = 0 3 inputMembershipType() 4 WHILE membershipType <> "X" DO 5 calcMembershipFee() 6 totalFees = totalFees + membershipFee 7 Display membershipFee 8 inputMembershipType() 9 ENDWHILE 10 Display totalFees 11 STOP
12 inputMembershipType()
13 Input membershipType
14 WHILE membershipType <> "F" AND membershipType <> "J" AND
membershipType <> "L" AND membershipType <> "X" DO
15 Display "Error: membership type must be F, J, L or X"
16 Input membershipType
17 ENDWHILE
18 EXIT
19 calcMembershipFee()
20 IF membershipType = "F" THEN
21 membershipFee = 160
22 ELSE
23 IF membershipType = "J" THEN
24 membershipFee = 80
25 ELSE
26 membershipFee = 10
27 ENDIF
28 ENDIF
29 EXIT
Discussion
The program main (or mainline) is now simplified, showing the main things the program does rather than showing a lot of detail. If details of the subroutines are required, then the programmer can look at the appropriate subroutine. Each subroutine is a simple, easy to check and performs one sub-task. The names of the subroutines should accurately describe what the subroutine does.
inputMembershipType() - this is an identifiable sub-task that asks the user to
input the membershipType and validates it. This occurs twice, allows the same
code to be-used, rather than duplicated.
calcMembershipFee() - is an identifiable sub-task to calculate a membership fee
based on the membershipType.
| Name | Data Type | Description |
| membershipFee | Double | The membership fee for a club member in $ |
| membershipType | String | The type of membership in the club. F=Full, J=Junior, L=Life. |
| totalFees | Double | The total fees for all members input in $ |
Inputs: membershipType = J; Correct results: membershipFee = 80
Inputs: membershipType = X; Correct results: totalFees = 80
' Name: calcMembership
' Purpose: Calculate and total the membership fees for club members
' Author: Tim Whitfort
Option Compare Database
Option Explicit
' Global variable declarations. These variables can be used throughout the program
Dim membershipFee As Double
Dim membershipType As String
Dim totalFees As Double
' The main subroutine. This is to be executed first
Sub Main()
' Local variable declaration. This variable can be used in this subroutine
Dim totalFees As Double
totalFees = 0
' Call the inputMembershipType subroutine
inputMembershipType
While membershipType <> "X"
' Call the calcMembershipFee subroutine
calcMembershipFee
' Total the fees so far
totalFees = totalFees + membershipFee
' Display the membership fee for the member
Debug.Print "Membership fee = "; membershipFee
' Call the inputMembershipType subroutine
inputMembershipType
Wend
' Display the total fees for members input
Debug.Print "Total fees = "; totalFees
End Sub
' Input and validate a membership type
Sub inputMembershipType()
membershipType = InputBox("Membership type (F=Full, J=Junior, L=Life, X=eXit) ?")
While membershipType <> "F" And membershipType <> "J" And _
membershipType <> "L" And membershipType <> "X"
Debug.Print "Error: membership type must be F, J, L or X"
membershipType = InputBox("Membership type (F=Full, J=Junior, L=Life, X=eXit) ?")
Wend
End Sub
' Determine the membership fee based on the membership type
Sub calcMembershipFee()
If membershipType = "F" Then
membershipFee = 160
Else
If membershipType = "J" Then
membershipFee = 80
Else
membershipFee = 10
End If
End If
End Sub
Written by Tim Whitfort.