Creating a VB Application | Data Structures | Functions | Program Control
Before any programming can begin Visual Basic itself must be located and run. There are two ways to do this:
Using �Start� button Shortcut:
Click on �Start�
Microsoft Visual Basic 6.0
Visual Basic 6.0
Directly from the Network:
Change directory to N:\Msoft\DevStudio\VB6
Then double-click VB6.EXE
If VB has been sucessfully started a dialog box. At this point select either �Standard EXE� or �VB Professional Edition Controls�. The professional option contains a wider variety of controls in the toolbox.
Designing the interface. This is done interactively without the need to program. Screen objects (or controls) are selected from the toolbox, placed and sized using the mouse.
Setting the properties of the screen objects to change such things as colours and labels.
Writing program code to specify what will happen as users interact with the screen objects. This step is often described as providing the �functionality�.
Before setting out to write a program, one must have a task in mind. One must also understand the characteristics of the various screen objects in order to make good choices for the interface. VB Help gives a brief description of each toolbox icon (click on the �search� button then enter �tool�, double click on �toolbox� in the lower window), refer to this if unsure about which item to choose.
When you launch VB the environment is in design mode (see title bar). This means that the system is ready for you to start to build an application. You may also load an application that has been previously saved, run it, or continue to work on it. In design mode VB presents a blank form, labelled Form1. This is where the interface (or the first screen of the interface) is constructed.
To place a control on Form1, double click on a toolbox icon. That object appears in the centre of the form. From here the object may be dragged into place using the mouse. Clicking on the object reveals sizing handles as shown around the horizontal scroll bar.
Moving the mouse over a sizing handle changes the cursor to a double headed arrow. Clicking and dragging on sizing handles allows the object to be sized horizontally and/or vertically.
Here is the interface for the calculator that is supplied as a sample application in ...\VB\samples\PGuide\calc\Calc.vbp. The familiar buttons are created using command buttons and the readout appears in a label.
Properties are set using the properties window. If this is not visible use the Windows menu to invoke it. In the calculator example above, the command buttons have been given captions corresponding to symbols such as �1�, �2�, �%�, �=�.
To set the properties of a screen object. Click on the object. The object box (under the properties title bar) then displays the name of the object. This is a list box that can be used to select any of the objects on the current form. Just below the object box is the settings box. This displays the current value of the property selected from the properties list underneath it. When the property value you want appears in the settings box it can be edited. This done by typing, or by selecting from a pre-defined list of possible values (obtained by clicking on the down arrow to the right of the settings list - if this is activated).
In the VB sample application, the calculator readout background colour is yellow. This was achieved by selecting the label object. Selecting the property BackColor, dropping down the colour palette and selecting the required colour cell.
The final step is writing the code that activates the application, or makes it run. The screen shot below shows a window displaying code for the �CE� command button (CancelEntry).
Once the correct control object has been selected the next step is to choose which event the control is going to respond to. Any event for the current control can be selected by using the right hand drop-down menu. In the example below the window is currently showing code associated with the �Click� event of the �CancelEntry_Click� control object.
Note: Since version 4 of VB the code window can display multiple procedures. The horizontal line drawn half way down the window signifies a division between two different subroutines. The top one is �CancelEntry_Click� and the bottom is �Decimal_Click�.
Below is a list of all Visual Basic events. It should be noted than each control only uses a subset of events. The top right combo box in the code window will display all relevant events for the current control object.
After completing the above three steps (design interface, set properties, and write code), the application can be run. When you have finished running the application you can terminate its execution. After stopping an application you will be returned back to design mode again where further changes can be made to the interface or program code.
Variables are data structures which are used to store information. There are two main types of information which can be stored: numbers and text. Before using a variable it must first be created:
Dimvariable_name As Type Example:
Dim price As Long Dim registration_plate As String
Once a new variable has been created a value can be assigned to it for storage. To do this the �=� operator is used. The first example assigns a constant to a variable, while the second assigns the contents of another variable multiplied by ten.Example 1: price = 29.95
The scope of a variable is defined as its operating range. There are three types of varible scope:
Declaring variables and arrays (see below) as local to the current procedure/function is useful because it minimises strange side-effects which can occur with public variables. However, when using a local variable in a procedure VB creates memory space to hold the variable�s contents when it reads the Dim statement, but when it gets to the end of the procedure (End Sub) it frees the space allocated to the local variable. Add the following code to a command button and see what values are printed:
Private Sub Command1_Click () Dim number As Integer ' Create a normal local variable number = number + 1 Print number End Sub
After clicking on the command button a few times you should see a whole column of 1�s down the left hand side of the form. The value never gets above 1 even though 1 is added to the variable each time. This is because each time the procedure is called, by clicking on the command button, VB is working with a different variable. It has exactly the same name in the program but it is a completely different variable. To stop this happening enter the keyword Static instead of Dim:
Private Sub Command1_Click () Static number As Integer ' Create a static local variable number = number + 1 Print number End Sub
This time instead of the local variable being destroyed when the procedure terminates its value remains until the whole program ends. Thus, we can now see a list of numbers being incremented by 1 every time the command button is clicked.
Note: The new static variable is still local in scope, if any other procedure tries to access this variable it will be unable to do so. Add a second command button, which will add a new �Click� procedure, and try amending or printing the value of the static variable.
The contents of local arrays can also be preserved while the program is still running. To do this add the �Static� keyword instead of �Dim� just like the variable example above.
Static salaries(199) As Long
Constants are similar to variables but only have a single value throughout the execution of a program. The contents of variables can change as often as necessary. So why use a constant if it can only hold one value? Well often in a program it is neccassary to use the same number or string repeatedly. For example, in a program to calculate end of year accounts there will be several parts of the program refering to the current value of V.A.T. We could hard code the value into the program everywhere it is used, but it would be tedious to change if the government altered the rate. Alternatively we could use a standard variable called �VAT� to hold the value and set it on the Form_Load event. However, what happens if there is a bug in the program and the contents of this variable is changed accidentally to something else.
One solution which solves the above two problems is to use a constant. In the following example a constant named �VAT� is declared and assigned the value 1.175. It is used in the Print statement with the variable bill_total to calculate the total bill amount. Notice that instead of writing 1.175 in the formula we refer to the constant by name.
Const VAT = 1.175 ' Declare and set the value of the constant Dim bill_total As Currency ' Declare a local variable to hold bill total bill_total = 560.95 Print "Total = "; bill_total * VAT
Like variables, constants also have scoping rules. There are public constants available to any module or unit in the current project, module wide constants available to any unit within the current module, and local constants accessable only within the current unit (procedure/function).
Variables are useful for storing small pieces of information, but not good for large amounts of very similar information. For example, to hold the salaries of two hundred employees would require 200 different variable names. A much more efficient way is to use a data structure called an array.
An array is similar to a row of pigeon-holes. The whole array has one name, and each pigeon-hole has an address. For the above salaries problem we need an array which has 200 elements (pigeon-holes). To do this we use the Dim command that we used to create new variables. However, a size is also allocated.
Dim array_name (size) [As Type]
Example: Dim salaries(199) As Long
The above example creates an array with 200 elements. The size is set to 199 because by default VB starts numbering from 0.
If we know that �Fred� is employee number 24 and has a salary of 25,000 then we can enter this amount into the array using:
salaries(23) = 25000
Conversely, if we want to know how much employee 189 earns then we can use:
lblEarnings.Caption = salaries(188)
Note: The above two examples both access the element one below the required number. This is because VB numbers the array from 0, not 1. However, VB can be forced to start at 1 by entering the statement �Option Base 1� in the declarations section of a form or a module.
There may be times when writing an application, however, when a program needs to change the size of the array. To do this a �dynamic� array can be used. First the array must be declared in the same way but without a number of elements specified:
Dim books() As String
To change the size of this array use the �ReDim� command and a specific number of elements:
Normally the contents of an array is erased when redimensioning, however to stop this use:
ReDim Preserve books(99)
Like variables, arrays can also have different scopes:
Functions are similar to procedures but always return a value of some sort. If a procedure does not return a value then it can just be called, but with functions the value passed back must be handled some how.
A useful function to start with is Time. This role of this function is to return the current system clock time; it does not take any parameters. To try this function out create a new label control on a suitable form. Next place a Timer control on the form as well and set its Interval to 1000. Double click on the Timer control and enter the line Label1.Caption = Time. When you run the program you should see the label control showing the time updated every second.
The above Time function is simple to use because it does not require any parameters. However, most functions require parameters to supply key information to the module in order for it to work out the return value. The Time function does not require a parameter because all it needs to do is interogate the system clock. The function UCase is a simple function requiring only one parameter to be passed. To pass variables and constants as parameters they must be enclosed in brackets after the function name. Multiple parameters must be separated by commas. Create a text control on a form and then in the KeyPress event write: If KeyAscii = 13 then Text1.Text = UCase(Text1.Text). Run the program, enter some text and press RETURN. The result should be that the text in the text box turns to upper-case.
In example 2 the function returned different text depending on the string sent to it in the parameter. Other functions require additional parameters to tell it how to handle the other parameters. For example, the function Mid$ takes one parameter to pass in the text to be used, one parameter to set the starting point (measured in characters), and then a third and optional parameter to specify how many characters to return. We can use this Mid$ function to return the word 'University' out of the string 'Napier University, Edinburgh'. In the Form Activate event enter the following code: Label1.Caption = Mid$("Napier University, Edinburgh", 8, 10). When run all that will be displayed in Label1 will be the word 'University'. Try leaving out the last parameter which is optional and see what happens.
Can the returning value of one function be used as the input parameter for another? The answer is yes, the example below does just that.
Suppose we need to build an input text box on a form to enter a person's name but later in the program we do not want to use the full name just the surname. An easy (or perhaps lazy) solution would be to use two separate text box controls, one for the first name and the other for the surname. However, this uses up more screen real estate and could be slower to enter. Where possible it is better to get the computer to do the hard work instead of the user. To do this we are going to create only one text input box and use a label control to output the result of the function. In the KeyPress event of the text box place the following code:
Private Sub Text1_KeyPress (KeyAscii As Integer) Dim strFullName, strSurname As String If KeyAscii = 13 Then strFullName = Text1.Text strSurname = Mid$(strFullName, InStr(1, strFullName, " ") + 1) Label1.Caption = "Surname = " + UCase(strSurname) End If End Sub
This example uses three of Visual Basic's built in functions: Mid$, InStr, and UCase. The function Mid$ in this case is using two parameters (the option third parameter is not being used). However, the second parameter which sets the starting character has been replaced by the function InStr which is used to return the position of located characters. In this case InStr is looking for the first occurrance of the character " " (space). We will use this to determine where the first name ends and the surname begins. One is added to this returning value because we do not want to return the space, we want to start one letter after the space. In Visual Basic an functions that return values that will be used as input parameters to other functions are evaluated first. The example above uses two local varaibles to try and make the code look less complicated and make it easier to read. However, it could be rewritten so that the the result from the Mid$ function is used as the input to UCase:
Private Sub Text1_KeyPress (KeyAscii As Integer) If KeyAscii = 13 Then Label1.Caption = UCase(Mid$(Text1.Text, InStr(1, Text1.Text, " ") + 1)) End Sub
This shortened example will do exactly the same as the previous example except the label will not show 'Surname = ' before displaying the name. It should be noted that although both examples perform the same job the first is much more readable and thus less prone to bugs. When too many functions are used on a single line it is difficult matching closing brackets. If you find you are using too many functions on a single line split them up over several lines with the help of some temporary local varaibles.
If Visual Basic does not have a suitable built in function then it is possible to build your own. To create a user defined function open up a code window and move the cursor down to the bottom past the last End Sub statement. Here, enter Function function_name (). Replace the word 'function_name' with the exact name you wish to call the function. After pressing RETURN the code window should clear and display the new function on its own with the added line End Function at the end.
In this example we will write our own function to return the current time in New York. We will create a new form with a label control and a command button control on it (see below).
Using the method outlined above create a new function with the code shown below:
Function NY_time () Dim strTempTime As String Dim intNY_hour As Integer strTempTime = Time$ intNY_hour = Val(Left$(strTempTime, 2)) - 5 Rem Correct for passing back over a day If intNY_hour < 0 Then intNY_hour = intNY_hour + 24 intNY_time = Str(intNY_hour) + Right$(strTempTime, 6) End Function
Next double click on the command button and enter the following code:
Private Sub cmdGetTime_Click () lblTime.Caption = "Time in New York is " + intNY_time() End Sub
This function is quite simple it just reads the system clock and takes five hours off the hour. A check to see if the hour is less than zero is require in case the time in New York is the evening before.
Exercise: Try expanding this function to make it more generalisable. Create a parameter to pass in the time zone difference (in hours) from Greenwich.
Below are listed some of the more important functions in Visual Basic. To find out exactly how many parameters each function requires and what type of data the parameter should be use the online help within Visual Basic.
|Branching Structures:||Repeating Structures:|
Visual Basic like other programming languages executes lines of code from the top of the program downwards. However, often a programmer does not wish all lines to be executed every time the program is run. Instead of writing several different programs for this job, branching and repeating commands can be used.
Branching commands are used to determine when to execute a small section of code and when not to run it. One example is the �If� command. If something is true then the code will be run, if not it will not be executed and VB will continue further down the program.
Repeating commands are useful for running small sections of code several times. If a programmer needs to read 200 lines of text from a file he could use 200 lines of code, one for every read statement, or alternatively a �For Next� loop could do a similar job using just three or four lines!
Single line If (Example):
If bytDayOfWeek = 1 Then Label1.Caption = "Sunday"
Multi-line If (Example):
If blnLeapYear = True And bytMonth = 2 Then Print "Current year is a leap year" Print "Month is February" Print "Thus number of days in month = 29" End If
The multi-line If command requires the extra statement �End If� to define the end of the If block.
In the following code a check is made to determine the price of cinema seats. Normal seats are priced at �4.40 while luxury seats are �6.00. Since there are only two types of seats the code only checks for standard and assumes luxury if this is false.
If and Else (Example):
If strSeatType = "normal" Then Label1.Caption = "Price = �4.40" Else Label1.Caption = "Price = $6.00" End If
However, if we adapt this cinema example to the theatre where there are more types of seats then we will require an �ElseIf� statement.
If and ElseIf (Example):
If strSeatType = "stalls" Then Label1.Caption = "Price = �8.25" ElseIf seat = "circle" Label1.Caption = "Price = �10.50" Else ' Assume the Upper Circle Label1.Caption = "Price = �12.00" End If
If more branches are required then a �Select Case� command can be used. Notice that in the following example, several values can trigger the same case statement. For example, the months 1, 3, 5, 7, 8, 10 and 12 all are 31 days long. Instead of writing 12 separate case statements, all these values can be included in one case by using commas.
Select Case bytMonth Case 1, 3, 5, 7, 8, 10, 12 number_of_days = 31 Case 2 number_of_days = 28 Case 4, 6, 9, 11 number_of_days = 30 End Select
The �End Select� statement defines the end of the Case block. To �trap� any values not picked up by earlier cases used the �Case Else� construct.
... Case 2 number_of_days = 28 Case 4, 6, 9, 11 number_of_days = 30 Case Else MsgBox "ERROR: Month must be between 1 and 12!" End Select
The easist way to understand repetition is with the aid of a practical example. Consider the steps a milkman performs has he delivers pints of milk to all the houses in a street. There are four basic steps: 1) check number of pints requested on customer�s note, 2) fetch required pints from milk float, 3) carry back empties, and 4) move to next house in street. If the street has 20 houses then the milkman has to carry out 80 individual steps to deliver all the milk. A computer simulation of this could be written in Visual Basic using 80 lines of code, one line for each step. However, this is very inefficient. A much better way is to �wrap� the four basic steps in some kind of repeating structure. Visual Basic supports the following types:
This type of repeating structure will always be executed at least once because the loop exit statement is at the end. The milkman problem could be solved in the following way:
intHouseNumber = 1 Do ' Check the order ' Fetch correct order ' Carry back empties intHouseNumber = intHouseNumber + 1 Loop Until intHouseNumber > 20
A �Do...Loop While� loop is very similar to the previous �Do...Loop Until�. The difference is in the logic of the exit condition. For example, the �Loop While� will repeat a block of instructions while a condition remains true, but the �Loop Until� loop will exit when the exit condition turns true.
This loop is functionally equivalent to the �Do...Loop While� except that the loop test condition is tested at the start of the loop. In practice this means that the �Do While...Loop� might not be executed at all (if condition is false), whereas the �Do...Loop While� will always be executed at least once.
Do While...Loop (Never executes loop):
Dim a as Byte a = 1 Do While a > 10 a = a - 1 Loop
Do While...Loop (Example which will execute loop):
Dim a as Byte a = 20 Do While a > 10 a = a - 1 Loop
This loop, like the previous �Do While...Loop� type, tests the condition at the beginning of the loop. However, whereas the previous loop repeated while the condition was true, the �Do Until...Loop� repeats until the condition is true. The milkman simulation, discussed above, could be re-coded to use a �Do Until...Loop� as follows:
intHouseNumber = 1 Do Until intHouseNumber > 20 ' Check the order ' Fetch correct order ' Carry back empties intHouseNumber = intHouseNumber + 1 Loop
All the loops discussed so far have been non-deterministic, that is the number of times the loop will execute is unknown. However, there is one type of loop where the number of times it will execute is already known, this is known as a deterministic loop. The �For...Next� loop can be used in any situation where the number of times it will repeat is known and fixed. For example, in the milkman situation it is known that there are 20 houses. In other situation it is known that there are so many miles between two towns, 7 days in a week, 10 floors in a particular office block, etc.
Dim intHouseNumber As Integer For intHouseNumber = 1 To 20 ' Check the order ' Fetch correct order ' Carry back empties Next
If this �For...Next� loop is compared with the other non-deterministic loops then one omission becomes apparent - a statement adding one to the house number is missing. This line is no longer needed because this type of loop automatically increments the value of its condition variable.
The �For...Next� loop condition variable does not always have to be incremented by one. Larger increments can be set by using the �Step� parameter. Using this the milkman simulation could be changed so that he walks up one side of the street first (odd numbered houses), stops at number 19, crosses over the street to number 20, and works his way back down the even numbered houses. �Print� statements have been added so that the order of houses visited can be seen.
Dim intHouseNumber As Integer For intHouseNumber = 1 To 19 Step 2 ' Check the order ' Fetch correct order ' Carry back empties Print intHouseNumber Next intHouseNumber For intHouseNumber = 20 To 2 Step -2 ' Check the order ' Fetch correct order ' Carry back empties Print intHouseNumber Next intHouseNumber
The �While...Wend� loop is functionally equivalent to the �Do While...Loop� discussed above. Once again this type of repeating structure should be used in situations where the loop will execute at least once. For example, a program which checks ban PIN numbers would always execute at least once:
Private Sub Form_Activate() Dim intEntered_PIN As Integer Const intCorrect_PIN = 1927 While intEntered_PIN <> intCorrect_PIN intEntered_PIN = InputBox("Please enter your PIN:", "PIN", "") Wend End Sub
Note: In reality an InputBox would not be used since the typed PIN can be seen on the screen and also the correct PIN would not be held in a constant but instead retrieved from an encrypted file, but as an example it demonstrates the potential of �While...Wend� loops.
In the milkman example above the milkman performs the basic 4 steps at each of the 20 houses he serves. However, consider the more complex problem of simulating the pouring of cups of tea at a Church meeting. The problem is more complex because the tea pot holds only 5 cups of tea and there are 100 to serve. To do solve this problem two loops can be used, one inside another (nested):
Dim cups_filled as Byte bytCupsFilled = 0 Do ' boil water ' add tea bags to pot ' fill pot with boiling water For bytPour = 1 to 5 ' pour tea into cup ' move to next cup bytCupsFilled = bytCupsFilled + 1 Next bytPour Loop Until bytCupsFilled = 100
Note: Different types of loops can be nested inside one another. In the above example the �For...Next� loop is nested within a �Do...Loop Until� structure.