Introduction
[edit | edit source]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
[edit | edit source]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.
OptionExplicit DimlngIndexasLong DimstrArray(0to9)asString' Create an array with 10 values DimintCounterasInteger intCounter=1 ForlngIndex=LBound(strArray)toUBound(strArray) intCounter=intCounter+1 strArray(lngIndex)=intCounter NextlngIndex
The above shows an example of read-write iteration over an array. For Each loop can be used for read-only iteration over an array:
DimMyArray(9) Fori=0To9 MyArray(i)=i Next ForEachItemInMyArray Debug.PrintItem Next
Indices
[edit | edit source]Per default, array indices start at 0, unless "Option Base 1" declaration is used. Without the declaration used, an array declared as "Dim MyArray(5)" has 6 elements: 0, 1, 2, 3, 4, 5.
The index range of an array has to be a continuous sequence of integers, including negative numbers. Thus, the following is possible:
DimMyArray1(-5to5) DimMyArray2(-10to-5) Fori=LBound(MyArray1)toUBound(MyArray1) MyArray1(i)=i+5 Debug.Printi,MyArray1(i) Next Fori=LBound(MyArray2)toUBound(MyArray2) MyArray2(i)=i+5 Debug.Printi,MyArray2(i) Next
Size
[edit | edit source]The size of an array can be obtained using LBound and UBound as follows:
DimMyArray1(-5to5) DimMyArray2(10-1) Size1=UBound(MyArray1)-LBound(MyArray1)+1 Size2=UBound(MyArray2)+1'For a same array with indexing starting at zero Debug.PrintSize1,Size2
Keywords: length, item count, element count.
Dynamic Arrays
[edit | edit source]An array with the number of elements specified upon its declaration, as in Dim Names(0 to 9), is a static one: the number of its elements cannot be changed in runtime. By contrast, an array declared without the number of elements, as in Dim Names(), is a dynamic array, and its number of elements can be changed using ReDim. To preserve the element content of the array when using ReDim, Preserve keyword has to be used after ReDim.
Say you have a phone book program running and it has an array of your friends' names, like this:
OptionExplicit DimStrNames(0to2)AsString StrNames(0)="Alec" StrNames(1)="Jack" StrNames(2)="Pie"
But say you want to add more friends to your phone book, when a button is clicked, for example. What do you do? You can define a dynamic array instead:
DimNames()AsString
This array initially has no elements. You can add more elements, by using the ReDim keyword:
ReDimNames(0to1)AsString
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:
ReDimNames(0to2)AsString
But you'll end up losing all the old records! If you want to keep them, you must also use the Preserve keyword:
ReDimPreserveNames(0To3)AsString Names(1)="Eugene H / Orage"'Whoa this person's name is too long to remember
To iterate AKA loop over the elements of a dynamic array, you have to use LBound and UBound functions or For Each loop, as described at #Use of Arrays.
To add an element to an initialized dynamic array, you can proceed as follows, using UBound function:
ReDimPreserveNames(0ToUBound(Names)+1)AsString Names(UBound(Names))="my new friend"
However, UBound does not work with an un-initialized dynamic array, so the following would cause a run-time error:
DimMyArray()AsString Debug.PrintUBound(MyArray)
One way to avoid this run-time error is to keep a flag:
DimArrayIsEmptyAsBoolean DimMyArray()AsString ArrayIsEmpty=True IfNotArrayIsEmptyThen ReDimPreserveMyArray(0ToUBound(MyArray)+1)AsString Else ReDimPreserveNames(0To0)AsString ArrayIsEmpty=False EndIf Names(UBound(Names))="my new friend"
Another way to avoid the run-time error is to catch the error created by the use of "UBound" on an uninitialized array:
DimMyArray()AsString NumberOfElements=0 OnErrorResumeNext NumberOfElements=UBound(MyArray)+1 OnErrorGoTo0 ReDimPreserveMyArray(0ToNumberOfElements)AsString MyArray(UBound(MyArray))="my new friend"
Finally, you can use the following hack to check if a dynamic array has been initialized:
DimMyArray()AsString If(NotMyArray)=-1Then NumberOfElements=0'The array is uninitialised Else NumberOfElements=UBound(MyArray)+1 EndIf ReDimPreserveMyArray(0ToNumberOfElements)AsString MyArray(UBound(MyArray))="my new friend"
Variant Arrays
[edit | edit source]Variant arrays are dynamic arrays declared using the Variant type, and initialized using "= Array()". Their advantage is that, after they are initialized using "= Array()", LBound and UBound functions work with them even when they have no elements, as follows:
DimVariantArrayAsVariant VariantArray=Array() Debug.PrintLBound(VariantArray)'Prints 0 Debug.PrintUBound(VariantArray)'Prints -1
As a consequence, adding an element is straightforward, with no need to check for UBound failure:
ReDimPreserveVariantArray(0ToUBound(VariantArray)+1)AsVariant VariantArray(UBound(VariantArray))="Jennifer"
Variant arrays can be initialized to a set of values:
DimVariantArrayAsVariant VariantArray=Array(1,2.3,"Hey")
For very large arrays, the overhead of using variant arrays, which have the element type of Variant rather than String or other narrower type, may well be restrictive, in which case conventional dynamic arrays should be used. What seems also much faster than variant arrays for adding items one at a time are Collections.
Multi-Dimensional Arrays
[edit | edit source]Arrays can be defined to have any number of dimensions (or indices), by listing the sizes of each dimension:
DimFunkyArray(2,3,1,4)AsString
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:
DimVeryFunkyArray()asString ReDimVeryFunkyArray(2,2,2)AsString
The LBound and UBound functions can be used to find the bounds of a particular dimension:
Debug.PrintUBound(FunkyArray,4)
Would give 4.
Using UBound without the second parameter gives the first dimension
Debug.PrintUBound(FunkyArray) ' Displays 2 Debug.PrintUBound(VeryFunkyArray) ' Displays 2
Erasing Arrays
[edit | edit source]Any type of array can be re-set to empty by using:
EraseSomeArray
Mixing Arrays
[edit | edit source]The real power of arrays comes when defining arrays of arrays. What does this mean? Declare an array:
DimVariantArray()AsVariant VariantArray=Array() ReDimVariantArray(1)AsVariant 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.PrintVariantArray(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.
DimvtempAsVariant vtemp=VariantArray(0) ReDimvtemp(1+UBound(vtemp))AsVariant vtemp(UBound(vtemp))=7 VariantArray(0)=vtemp
Use of Matrices
[edit | edit source]See also the section #Multi-Dimensional Arrays.
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:
DimMatrix(0To9,0To9)asInteger
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.
ForRow=0To3 ForColumn=0To8 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
[edit | edit source]For sorting variant arrays, see http://stackoverflow.com/questions/152319/vba-array-sort-function.
| Previous: Strings | Contents | Next: Files |
