Visual Basic/Arrays
Introduction
Arrays are extremely useful in Visual Basic, and are present in many other programming languages. Arrays are used to group similar data together, to make it easier to search and sort through this data. The best way to look at an array is to show you one. Say you want to make a phone book for your computer. Rather than make a new variable with a new name whenever you want to add a name, you can make an array. Arrays consist of the variable name and a subscript, which is put in parentheses for computer use. So, if you want to make a phone book of say, 100 people, rather than make a bunch of variables named 'person1, person2, person3....person100', you may use an array. All you have to do is dimension the array (see above). So now those 100 variables turn into person(1 to 100) in a dim statement. Now you may be asking, what do I do now? Each object stored in an array is called an element. What you have done is created an array which can hold 100 elements. If you want to print the 32nd person in your phone book, you simply would type:
Debug.Print Person(32)
Use of Arrays
Arrays have far more uses other than just making phone books. But before we get into specific uses, let's look at some of the basic techniques used when working with arrays. The first thing you may want to do is learn how to easily fill an array. Filling an array with random numbers is a popular technique for starting off programs, and testing other techniques such as sorting. To fill an array, a simple For Loop may be used.
Option Explicit Dim lngIndex as Long Dim strArray(0 to 9) as String ' Create an array with 10 values Dim intCounter as Integer intCounter = 1 For lngIndex = LBound(strArray) to UBound(strArray) intCounter = intCounter + 1 strArray(lngIndex) = intCounter Next lngIndex
Dynamic Arrays
Arrays are more flexible than you think. Say you have a phone book program running and it has an array of your friends' names, like this:
Option Explicit Dim StrNames(0 to 2) As String StrNames(0) = "Alec" StrNames(1) = "Jack" StrNames(2) = "Pie"
But say I want to add more friends to your phone book, when a button is clicked, for example. What do I do?! Don't worry, arrays are more flexible than you think! You can define a dynamic array instead:
Dim Names() As String
This array initially has no elements. You can add more elements, by using the ReDim keyword:
ReDim Names(0 to 1) As String
This would create two new elements. You can assign names to these elements in the same way as before:
Names(0) = "Alec" Names(1) = "Jack"
If you want to add more entries then use, for example:
ReDim Names(0 to 2) As String
But you'll end up losing all the old records! If you want to keep them, you must also use the Preserve keyword:
ReDim Preserve Names(0 To 3) As String Names(1) = "Eugene H / Orage" 'Whoa this person's name is too long to remember
Now before we go on, it's important to learn about some built-in functions related to arrays first: UBound and LBound. UBound is an abbreviation which stands for "Upper Bound" and LBound for "Lower Bound". Every type of array has an upper and a lower bound. In this case, our upper bound for "names" is 3 and the lower bound is 1 (see the definition above). However, those functions are not made to help you with your short term memory problem. Although you definitely can use those to check what the LBound and the UBound are if you forget. Anyway those functions really help you out when using dynamic arrays, where the bounds of an array may change at run-time. In the following example, we will print whatever's in our phone book using both functions:
For I = LBound(Names) To UBound(Names) 'This statement is equivalent to "For i=0 to 2" Debug.Print Names(I) Next I
Will print:
Alec Jack Eugene H / Orage
Now, to add more flexibility with ReDim? Use the following code to add people: (This code can be placed inside a command button event so that new friends can be added when the button is clicked)
ReDim Preserve Names(0 To UBound(Names) + 1) As String Names(UBound(Names)) = "my new friend"
It is worth noting at this point that the LBound and UBound functions do not work with an un-initialized dynamic array. The following would cause a run-time error:
Dim MyArray() As String Debug.Print UBound(MyArray)
How can you avoid this run-time error?
Using the above code that dynamically adds a new member would not work. Instead a flag has to be kept:
Dim ArrayIsEmpty As Boolean Dim MyArray() As String ArrayIsEmpty = True If Not ArrayIsEmpty Then ReDim Preserve MyArray(0 To UBound(MyArray) + 1) As String Else ReDim Preserve Names(0 To 0) As String ArrayIsEmpty = False End If Names(UBound(Names)) = "my new friend"
There is also a slightly obscure but quite neat hack to check if a dynamic array has been initialized.
Dim MyArray() As String If (Not MyArray) = -1 Then MsgBox "Array is uninitialised." End If
This rather C-like construct feels like it shouldn't work in VB, but it does.
Variant Arrays
Dynamic arrays can be handled more efficiently by using the Variant type. You can declare an array like this:
Dim VariantArray As Variant VariantArray = Array()
This works in a way analagous to that for conventional dynamic arrays in the previous section. You can add members in a similar way:
ReDim VariantArray(0 To 1) As Variant VariantArray(0) = "John" VariantArray(1) = "Janet"
The main difference between Variant arrays and conventional arrays is the LBound and UBound functions work with an un-initialized Variant array:
Dim VariantArray As Variant VariantArray = Array() Debug.Print LBound(VariantArray) Debug.Print UBound(VariantArray)
This would display 0 and -1 respectively. This can be used to test if a Variant array is unitialized, by knowing that the upper bound is less than the lower bound (as either of the bounds can be negative). Also this simplifies the code for adding new members, as a check for an un-initialized array does not have to be carried out:
ReDim Preserve VariantArray(0 To UBound(VariantArray) + 1) As Variant VariantArray(UBound(VariantArray)) = "Jennifer"
Note that for very large arrays, the overhead of using Variants may well be restrictive in which case conventional arrays should be used.
Multi-Dimensional Arrays
Arrays can be defined to have any number of dimensions (or indices), by listing the sizes of each dimension:
Dim FunkyArray(2,3,1,4) As String
An element can be referenced like this:
FunkyArray(1,2,0,3) = 24
Dynamic arrays can also be re-dimensioned to have any number of dimensions:
Dim VeryFunkyArray() as String ReDim VeryFunkyArray(2,2,2) As String
The LBound and UBound functions can be used to find the bounds of a particular dimension:
Debug.Print UBound(FunkyArray, 4)
Would give 4.
Using UBound without the second parameter gives the first dimension
Debug.Print UBound(FunkyArray) ' Displays 2 Debug.Print UBound(VeryFunkyArray) ' Displays 2
Erasing Arrays
Any type of array can be re-set to empty by using:
Erase SomeArray
Mixing Arrays
The real power of arrays comes when defining arrays of arrays. What does this mean? Declare an array:
Dim VariantArray() As Variant VariantArray = Array() ReDim VariantArray(1) As Variant VariantArray(0) = Array(1,2,3) VariantArray(1) = Array(4,5,6)
What do we have here? Essentially two arrays inside another. They can be referenced like this:
Debug.Print VariantArray(0)(2)
Would show 3.
You can nest arrays like this to any depth and in any order and they can be of any size. A note of caution must be taken when using the ReDim statement, however. You cannot specifically re-dimension a particular dimension of an array; instead you need to temporarily copy to a variant.
Dim vtemp As Variant vtemp = VariantArray(0) ReDim vtemp(1+UBound(vtemp)) As Variant vtemp(UBound(vtemp)) = 7 VariantArray(0) = vtemp
Use of Matrices
Matrices are not as commonly used as arrays, but are an important element of programming. Rather than just one dimension, a matrix may have 2 or more. So, to make a matrix, the Dim statement would be:
Dim Matrix(0 To 9, 0 To 9) as Integer
This will create a matrix that is 10 by 10 and comprised of integers. In reality, a matrix is much like an array of arrays. The first thing you'll want to do is know how to create a loop for reading and filling a matrix. But before that, even, you should know how matrices are structured. An example matrix would be:
1 2 3 4 5 6 7 8 9
1 1 1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1 1 1
3 1 1 1 1 1 1 1 1 1
4 1 1 1 1 1 1 1 1 1
This is a 4 by 9 matrix. When talking about matrices, rows are always stated before columns. You will also notice column numbers travel from left to right, while row numbers travel from top to bottom. This is very important. And of course, matrices need not consist of merely 1s. So, now you want to fill a matrix? Its very similar to an array.
For Row = 0 To 3 For Column = 0 To 8 Matrix(Row, Column)=1 Next Next
This will of course fill the matrix with nothing but ones, but random numbers may be used (see references). As you may notice, this involves nested loops. The loop fills left to right, top to bottom (the same directions we use when reading).
Sorting
For sorting variant arrays, see http://stackoverflow.com/questions/152319/vba-array-sort-function.
| Previous: Strings | Contents | Next: Files |