TechnologyUK - Programming (VB6) Logo

Arrays

A simple Visual Basic variable can be assigned a single value. An array variable is a collection of variables, all having the same type, to which a list of values can be assigned. Each member of an array is known as an array element, and is identified by a number in parentheses immediately following the array variable name. For example, the statement:

Student(5) = "Fred Smith"

assigns the string "Fred Smith" to the fifth element in the array Student(). The number inside the parentheses is known as an array subscript. An array variable is declared as follows:

Dim arrayName(1 to n) As varType

This will create n variables of the type varType.

Array elements can be assigned values and used in a program in the same way as any other variable. The main benefits of using arrays include the ability to use a single statement to create a range of variables, and the use of subscripts in loops to access each element of an array variable in turn.



Example 1

The following code fragment creates a string array consisting of the names of students in a class, and assigns values to each array element.

Dim Students(1 To 4) As String
Students(1) = "Stephanie Brown"
Students(2) = "Colin Casey"
Students(3) = "John Evans"
Students(4) = "Linda Hunter"

Data for large arrays is often stored in data files and read into the array using Input statements. To illustrate this, create a text file called "Results.txt" to hold the names of students and their examination results, as shown below:



The contents of the "Results.txt" text file
"Charlie Brown", 53
"Colin Carruthers", 66
"John Walker", 42
"Betty Rubble", 95
"Andy Capp", 32
"James Beam", 80
"Thomas Petty", 63
"Ruby Murray", 59


We are going to create a program that reads the names of students and their examination results from the "Results.txt" file and assigns the values read to suitable array variables. The program will display a list of student names and exam results, and calculate and display the average mark for the group. A string array will be created to hold the names of the students, and a numeric array will be created to hold their examination scores. The first element of each array holds data for the first student, the second element holds data for the second student, and so on. Note that the two arrays can be created using a single Dim statement.

Open a new Visual Basic project, save it to a new folder, and create a form similar to the one illustrated below.


The Student Exam Results form



The Student Exam Result Form Controls
ControlName CaptionAdditional Properties
Form Form1 Student Exam Results  
Button cmdList List Results  
PictureBox picList    
Button cmdAverage Calculate Average  
PictureBox picAverage    


Enter the following code in the form's code window:

Option Explicit
Dim Students(1 To 8) As String * 20
Dim Results(1 To 8) As Integer
Dim Counter As Integer

Private Sub cmdList_Click()
    picList.Cls
    Open App.Path & "\Results.txt" For Input As #1
    For Counter = 1 To 8
        Input #1, Students(Counter), Results(Counter)
        picList.Print Students(Counter); Results(Counter)
    Next
    Close #1
End Sub

Private Sub cmdAverage_Click()
    Dim total As Integer
    Dim Average As Single
    picAverage.Cls
    total = 0
    For Counter = 1 To 8
        total = total + Results(Counter)
    Next
    Average = total / 8
    picAverage.Print Average
End Sub

Run the program and click the List Results button to see the list of students and their results, then click the Calculate Average button to see the average score. The result should be similar to the screen shot below.


The output from the program for Example 1

In the above example, we know the number of exam results in the file, and can dimension the arrays accordingly. In real life, we often don't know in advance how many array variables our program may be called upon to deal with. The number may well vary from one situation to another. In Visual Basic, we can set the size of an array using a statement like:

ReDim arrayName(1 to n) As varType

ReDim can accept either variables or expressions as subscripts (whereas Dim cannot). The only constraint is that ReDim statements can only be used inside procedures.



Example 2

Re-write the code for the previous example as shown below.

Option Explicit
Dim numStudents As Integer, sTemp As String, Score As Integer, Total As Integer

Private Sub cmdList_Click()
    Dim n As Integer, Counter As Integer
    picList.Cls
    numStudents = 0
    Total = 0
    Open App.Path & "\Results.txt" For Input As #1
    Do While Not EOF(1)
        Input #1, sTemp, Score
        numStudents = numStudents + 1
        Total = Total + Score
    Loop
    Close #1
    n = numStudents
    ReDim Students(1 To n) As String, Results(1 To n) As Integer
    Open App.Path & "\Results.txt" For Input As #1
    For Counter = 1 To n
        Input #1, Students(Counter), Results(Counter)
        picList.Print Students(Counter); Results(Counter)
    Next
    Close #1
End Sub

Private Sub cmdAverage_Click()
    Dim Average As Single
    picAverage.Cls
    Average = Total / numStudents
    picAverage.Print Average
End Sub

Form level (General) declarations can contain Dim statements of the form:

Dim arrayName() As varType

where the subscripts of the array are unspecified. The array cannot be used until a ReDim statement is executed in a procedure that establishes the subscript range to be used (the "As varType" clause can be omitted from the ReDim statement). Note that any reference within a procedure to an array subscript outside the defined range will result in an error message. Note also that the elements of an array will have a default value until they are initialised, or have a value assigned to them by the program. For numeric array variables, the default value is 0. For string array variables, the default value is "" (the empty string).

An array created with a ReDim statement is said to be dynamic. A dynamic array can be resized with another ReDim statement, although the resized array loses all information unless it is resized with the words ReDim Preserve, in which case as much information as possible is retained.

Arrays may be ordered (in ascending or descending order) or unordered. Arrays of numerical variables are ordered by numerical value, while string arrays are ordered using their ASCII character code values. Ordered arrays are easier to search, since a search for an element having a specific value will end either when the element is found, or an element is found whose value is greater than the value being sought. A search of an ordered array will, on average, only need to examine half of the array elements.

In some circumstances, an array must be dimensioned before the number of data items it will hold is known. In most cases, however, it should be possible plan for all reasonable contingencies by making the array suitably large. A counter variable is often used in such cases to keep track of the number of data items actually stored in the array.



Example 3

Open a new Visual Basic project, save it to a new folder, and create a form similar to the one illustrated below.


The Student Register form



The Student Register Form Controls
ControlName CaptionAdditional Properties
Form Form1 Student Register  
TextBox InputBox    
Button cmdAdd Add Student  
PictureBox picList    


The code for the program is shown below. An array large enough to hold ten students is created, and the names of students can be added by typing them into the text box at the top of the application window, and clicking on the Add Student button. Once the array is full, the program will not accept any more entries.

Option Explicit
Dim Students(9) As String
Dim Counter As Integer
Dim n As Integer

Private Sub cmdAdd_Click()
    If InputBox.Text = "" Then
        MsgBox "You must enter a student name.", , "Student Register"
    ElseIf Counter > 9 Then
        MsgBox "No space to record additional Students.", , "Student Register"
        InputBox.Text = ""
    Else
        picList.Cls
        Students(Counter) = InputBox.Text
        InputBox.Text = ""
        For n = 0 To Counter
           picList.Print Students(n)
        Next
        Counter = Counter + 1
    End If
End Sub

Private Sub Form_Load()
    Counter = 0
End Sub



Control Arrays

Visual Basic allows the construction of arrays of text boxes, labels, command buttons, and other Visual Basic controls. Such arrays are called Control arrays. At least one element of a control array is created when the form is designed. The remaining elements can be created either at the same time, or at run time.



Example 4

To illustrate the use of control arrays, we are going to create a simple calculator program. Open a new Visual Basic project, save it to a new folder, and create a form similar to the one illustrated below.


The Calculator form

The controls for the calculator are defined below (note that the dimensions of all buttons are 480 x 480).




The Calculator Form Controls
Control Name Caption Index Additional Properties
Form Form1 Calculator   Width = 3390, Height = 3375
Button Number 0 0 Left = 120, Top = 2400
Button Number 1 1 Left = 120, Top = 1800
Button Number 2 2 Left = 720, Top = 1800
Button Number 3 3 Left = 1320, Top = 1800
Button Number 4 4 Left = 120, Top = 1200
Button Number 5 5 Left = 720, y = 1200
Button Number 6 6 Left = 1320, Top = 1200
Button Number 7 7 Left = 120, Top = 600
Button Number 8 8 Left = 720, Top = 600
Button Number 9 9 Left = 1320, Top = 600
Button Decimal .   Left = 720, Top = 2400
Button Operator / 0 Left = 2640, Top = 1800
Button Operator + 1 Left = 2020, Top = 1200
Button Operator X 2 Left = 2020, Top = 1800
Button Operator - 3 Left = 2640, Top = 1200
Button Operator = 4 Left = 1320, Top = 2400
Button Cancel C   Left = 2020, Top = 600
Button CancelEntry CE   Left = 2640, Top = 600
Button Percent %   Left = 2640, Top = 2400
Label Readout 0.   Alignment: 1 - Right Justify
Appearance: 1 - 3D
BackColor: &H00FFFFFF&
BorderStyle: 1 - Fixed Single
Left = 120, Top = 100
Width = 3000, height = 375


The ten buttons (0-9) with the name Number are members of an array, as are the five buttons (+, -, x, /, =) with the name Operator. When you have created the first button in each array, find the Index property in the Properties window, which is initially blank, and change it to 0 (zero).

Once the first element in a control array has been created, you can create as many copies as you need using copy and paste commands. Visual basic will automatically assign the next available index number to each copy created. All you need to do is to change the caption to the correct text, and place the new button in the correct position on the form. The properties that are common to all controls in a control array should be set for the first element created before it is used to create additional array elements, which will make the process of creating the array more efficient.

The code for the Calculator program is shown below. Note that, although there are several buttons with the name Number, the value of the Index property for the button actually clicked will be sent to the sub routine Number_Click(). The same thing applies to the buttons that share the name Operator, and the sub routine Operator_Click(). In other words, the Index property is used to tell the program which command button in a control array consisting of several command buttons has been clicked on by the user. As a general rule, therefore, event procedures for a control array have an additional parameter (Index As Integer).

Option Explicit
Dim Op1, Op2
Dim DecimalFlag As Integer
Dim NumOps As Integer
Dim LastInput
Dim OpFlag
Dim TempReadout

Private Sub Cancel_Click()
    Readout = Format(0, "0.")
    Op1 = 0
    Op2 = 0
    Form_Load
End Sub

Private Sub CancelEntry_Click()
    Readout = Format(0, "0.")
    DecimalFlag = False
    LastInput = "CE"
End Sub

Private Sub Decimal_Click()
    If LastInput = "NEG" Then
        Readout = Format(0, "-0.")
    ElseIf LastInput <> "NUMS" Then
        Readout = Format(0, "0.")
    End If
    DecimalFlag = True
    LastInput = "NUMS"
End Sub

Private Sub Form_Load()
    DecimalFlag = False
    NumOps = 0
    LastInput = "NONE"
    OpFlag = " "
    Readout = Format(0, "0.")
End Sub

Private Sub Number_Click(Index As Integer)
    If LastInput <> "NUMS" Then
        Readout = Format(0, ".")
        DecimalFlag = False
    End If
    If DecimalFlag Then
        Readout = Readout + Number(Index).Caption
    Else
        Readout = Left(Readout, InStr(Readout, Format(0, ".")) - 1) + Number(Index).Caption + Format(0, ".")
    End If
    If LastInput = "NEG" Then
        Readout = "-" & Readout
    End If
    LastInput = "NUMS"
End Sub

Private Sub Percent_Click()
    Readout = Readout / 100
    LastInput = "Ops"
    OpFlag = "%"
    NumOps = NumOps + 1
    DecimalFlag = True
End Sub

Private Sub Operator_Click(Index As Integer)
    TempReadout = Readout
    If LastInput = "NUMS" Then
        NumOps = NumOps + 1
    End If
    Select Case NumOps
        Case 0
            If Operator(Index).Caption = "-" And LastInput <> "NEG" Then
                Readout = "-" & Readout
                LastInput = "NEG"
            End If
        Case 1
            Op1 = Readout
            If Operator(Index).Caption = "-" And LastInput <> "NUMS" And OpFlag <> "=" Then
                Readout = "-"
                LastInput = "NEG"
            End If
        Case 2
            Op2 = TempReadout
            Select Case OpFlag
                Case "+"
                    Op1 = CDbl(Op1) + CDbl(Op2)
                Case "-"
                    Op1 = CDbl(Op1) - CDbl(Op2)
                Case "X"
                    Op1 = CDbl(Op1) * CDbl(Op2)
                Case "/"
                    If Op2 = 0 Then
                        MsgBox "Can't divide by zero", 48, "Calculator"
                    Else
                        Op1 = CDbl(Op1) / CDbl(Op2)
                    End If
                Case "="
                    Op1 = CDbl(Op2)
                Case "%"
                    Op1 = CDbl(Op1) * CDbl(Op2)
            End Select
            Readout = Op1
            NumOps = 1
    End Select
    If LastInput <> "NEG" Then
        LastInput = "OPS"
        OpFlag = Operator(Index).Caption
    End If
End Sub



Sorting an Array

A sort is an algorithm that puts the elements of an array into numerical or alphabetical order. One common sorting technique is the bubble sort. The bubble sort algorithm compares adjacent items, and swaps those that are out of order. If the process is repeated enough times, the list will eventually be ordered. The steps for each pass through the array are as follows:

  1. Compare the first and second elements, and if out of order, swap them.
  2. Compare the second and third items, and if out of order, swap them.
  3. Repeat the process for all remaining pairs. The final comparison is between the last two elements in the array.

The first pass through the array checks each successive pairing in turn, after which the last item will be in its correct place in the array. The second pass repeats the process, but can ignore the last item. After the second pass, the last two items in the array will be in their correct places. Each successive pass therefore has one less comparison to make. The total number of passes required to ensure that all of the array elements are correctly ordered is one less than the number of elements in the array.



Example 5

We are going to create a program that takes a randomly ordered list of names from a file and sorts them into alphabetical order. Here is the unsorted file, "Unsorted.txt".



The contents of the "Unsorted.txt" text file
Warsaw
Paris
New York
Amsterdam
Berlin
London
Brussels
Rome


Open a new Visual Basic project, save it to a new folder, and create a form similar to the one illustrated below.


The European Cities form



The European Cities Form Controls
ControlName CaptionAdditional Properties
Form Form1 European Cities  
Button cmdSort Sort Alphabetically  
PictureBox picList    


The bubble sort algorithm uses two nested loops. The inner loop performs a single pass, while the outer loop controls the number of passes made. The code for the program is shown below.

Option Explicit
Dim Counter As Integer, sTemp As String
Dim Cities() As String

Private Sub cmdSort_Click()
    Dim n As Integer, Pass As Integer, tempString As String
    ReDim ListIndex(1 To Counter) As Integer
    picCity.Cls
    For Pass = 1 To Counter - 1
        For n = 1 To Counter - Pass
            If Cities(n) > Cities(n + 1) Then
                tempString = Cities(n)
                Cities(n) = Cities(n + 1)
                Cities(n + 1) = tempString
            End If
        Next n
    Next Pass
    For n = 1 To Counter
        picCity.Print Cities(n)
    Next
End Sub

Private Sub Form_Load()
    Dim n As Integer
    Counter = 0
    Open App.Path & "\Unsorted.txt" For Input As #1
    Do While Not EOF(1)
        Input #1, sTemp
        Counter = Counter + 1
    Loop
    Close #1
    ReDim Cities(1 To Counter) As String
    Open App.Path & "\Unsorted.txt" For Input As #1
    Form1.Show
    For n = 1 To Counter
        Input #1, Cities(n)
        Me.picCity.Print Cities(n)
    Next
    Close #1
End Sub



Searching an Array

If we had an alphabetical list of several hundred names and wanted to find out whether a particular person's name was on the list, we could simply check each item in the list in turn until a match was found. This kind of search is known as a sequential search. A search for a name beginning with "A", therefore, would bear fruit much faster than a search for a name beginning with "Z". For very long lists, such a search could be somewhat time-consuming. If we are talking about a sorted array, however, there is a much quicker method of searching called a binary search.

A binary search starts looking for the search term by determining which half of the array contains the item. This half of the array is then dealt with as if it was the entire array, and the process is repeated. This goes on until the item is found. The algorithm for a binary search carries out the following steps:

  1. Assign variables first and last to hold the subscript values of the first and last items in the array respectively, and create a Boolean variable flag with an initial value of False that will become True if the search item is found.
  2. Compare the middle element of the current array with the search term. This element will have the subscript middle, and is calculated as:

    middle = (first + last) / 2
  3. If the middle element matches the search term, then flag is set to True, and the search is finished.
  4. If the middle element is greater than the search term, then the search term can only be in the first half of the array, so the new value of last will be middle - 1, and the value of first will be unchanged.
  5. If the middle element is less than the search term, then the search term can only be in the second half of the array, so the new value of first will be middle + 1, and the value of last will be unchanged.
  6. Repeat steps 2 - 5 until the search term is found or until the entire list has been searched (in which case first will be greater than last, and the search term is not in the array).


Example 6

We are going to create a program that reads an alphabetically ordered list of UK towns and cities from a text file and puts them into an array. The user can then enter the name of a town or city, and the program will determine whether or not the town or city entered is in the file. Here are the contents of the text file, "Locations.txt":



UK Towns and Cities
AberdeenLeicester
BathLiverpool
BelfastLondon
BirminghamManchester
BradfordMerthyr Tydfil
BrightonMiddlesbrough
BristolNewcastle
CambridgeNorthampton
CardiffNorwich
CreweNottingham
ChichesterOldham
DerbyOxford
DublinPlymouth
DundeePortsmouth
DurhamPreston
EdinburghSheffield
ExeterSouthampton
GlasgowStoke
GloucesterSunderland
HalifaxSwansea
HullSwindon
LeedsYork


Open a new Visual Basic project, save it to a new folder, and create a form similar to the one illustrated below.


The European Cities form



The Location Search Form Controls
ControlName CaptionAdditional Properties
Form Form1 Location Search  
Button cmdSearch Search  
TextBox txtLocation    


The code for the program is shown below. Note that the built-in Visual Basic function UCase is used in the program to convert the characters in the strings being compared to upper case, so the algorithm will work whether the user types in "London" or "LONDON".

Option Explicit
Dim First As Integer, Last As Integer, Middle As Integer
Dim Locations() As String, sTemp As String, searchTerm As String
Dim Counter As Integer
Dim Flag As Boolean

Private Sub cmdSearch_Click()
    Flag = False
    searchTerm = UCase(txtLocation.Text)
    If searchTerm = "" Then
        MsgBox "You must enter the name of a town or city.", , "Search"
    Else
        First = 1
        Last = Counter
        Do Until Flag = True Or First > Last
            Middle = Int((First + Last) / 2)
            If searchTerm = UCase(Locations(Middle)) Then
                Flag = True
            ElseIf searchTerm > UCase(Locations(Middle)) Then
                First = Middle + 1
            ElseIf searchTerm < UCase(Locations(Middle)) Then
                Last = Middle - 1
            End If
        Loop
        If Flag = True Then
            MsgBox txtLocation.Text & " is in the list.", , "Search"
        Else
            MsgBox txtLocation.Text & " is NOT in the list.", , "Search"
        End If
    End If
End Sub

Private Sub Form_Load()
    Dim n As Integer
    Counter = 0
    Open App.Path & "\Locations.txt" For Input As #1
    Do While Not EOF(1)
        Input #1, sTemp
        Counter = Counter + 1
    Loop
    Close #1
    ReDim Locations(1 To Counter) As String
    Open App.Path & "\Locations.txt" For Input As #1
    For n = 1 To Counter
        Input #1, Locations(n)
    Next
    Close #1
End Sub



Two-Dimensional Arrays

The arrays dealt with so far have been one-dimensional, in the sense that they have held a single list if items, indexed by a single array subscript. A two-dimensional array can hold the contents of a table having a number of rows and columns by employing a second array subscript. The range of the first subscript is determined by the number of rows in the table, and the range of the second subscript is determined by the number of columns. Two dimensional arrays will be the subject of a later tutorial.