Arrays
Up to this point, all discussion has centered on the use of variables as the primary means of storing information in memory during script execution. Variables are limited in their ability to effectively handle large amounts of data. Scripts are generally designed to process data that is related in some manner. VBScript provides the array construct as a means of more efficiently managing large amounts of related data. In this chapter, you will learn how to work with single dimensional and multidimensional arrays. In addition, you will learn various techniques for resizing arrays and how to process and erase their contents.
Storing Related Data in Arrays
Typically, scripts process data that is related in some fashion. When the amount of data to be processed is relatively small, it can be stored in individual variables. However, as the amount of data processed by scripts grows, it becomes increasingly difficult to rely on variables. For example, a script may need to process a collection of user names. Defining 100 unique variable names would be an arduous process. Instead, VBScript provides arrays as a construct for storing large quantities of related data.
An array is an indexed list of related data. Arrays provide the ability to store related pieces of information in a manner that is easy to manage. Most arrays are made up of a single dimension and can be thought of as a single column table. VBScript arrays are zero-based, meaning that their first element is always assigned an index number of 0. The second element stored in the array is assigned an index number of 1, and so on. By specifying the name of an array and an index number, you can reference any element stored within the array.
However, VBScript arrays are not limited to a single dimension. For example, a two-dimensional VBScript array can be thought of as a table consisting of multiple columns and rows, as depicted in Figure 5.1.
Cust_No |
Cust_Name |
Cust_Phone |
|
---|---|---|---|
Customer1 |
0,0 |
1,0 |
2,0 |
Customer2 |
0.1 |
1,1 |
2,1 |
Customer3 |
0,2 |
1,2 |
2,2 |
Figure 5.1: Examining the structure of a two-dimensional array
As additional dimensions are added, arrays become more complex. For example, a three-dimensional array can be thought of as a cube. Anything beyond three dimensions is difficult for most people to conceptualize and is equally difficult to represent graphically. Fortunately, even though VBScript can support arrays with up to 60 dimensions, most situations only call for one or two dimensional arrays.
Each element in an array can hold one value. For single-dimension arrays, an element is a row in the table or column. For two-dimensional arrays, an element is the intersection of a row and a column.
Working with Single Dimension Arrays
A single-dimension array is used to store related collections of data, such as the names of a collection of files, users, or customers. VBScript arrays are zero-based. Therefore, the first element stored in a single-dimension array is assigned an index position of 0. The actual length of an array is equal to the number of elements in the array minus 1.
Defining Single Dimension Arrays
VBScript supports the establishment of both static and dynamic arrays. A static array is one whose length is defined in advance and cannot be changed. A dynamic array, on the other hand, can be resized as many times as necessary. You may define a static array using the Dim keyword. The syntax for the Dim statement when used to define arrays is outlined below.
Dim ArrayName(dimensions)
ArrayName is the name assigned to the array, and dimensions is a comma-separated list that specifies the number of dimensions in the array as well as their length.
Dim astrCustomerList(4)
The previous statement defines an array called astrCustomerList that can store up to five elements (that is, elements 0 through 4).
Tip |
To make arrays stand out from other variables, develop a unique naming convention for them. In this book, the lowercase letter a is appended to the beginning of array names, followed by a three-character Hungarian styled description of the type of data stored in the array and one or more descriptive words that identify the array's contents. In the case of the previous example, the astrCustomerList array contains string data representing the customer names. |
Populating a Single Dimension Array
Once an array has been defined, you can begin storing elements in it. For example, the following statements create an array called astrCustomerList and assign data to each of its five elements.
Dim astrCustomerList(4) astrCustomerList(0) = "XYZ Corp." astrCustomerList(1) = "ABC Co." astrCustomerList(2) = "Acme Inc." astrCustomerList(3) = "A&B Corp" astrCustomerList(4) = "ZZZ Enterprises"
If you want the user to provide data for the array, you might collect it as demonstrated below.
Dim astrCustomerList(4) For i = 0 to 4 astrCustomerList(i) = InputBox("Please enter a customer name.") Next
A loop has been set up to iterate five times (from 0 to 4). It uses the VBScript InputBox() function to prompt the user to type the name of a customer during each iteration of the loop, as demonstrated in Figure 5.2. It then stores the values typed by the user in the array by associating the value of i with an index number in the array.
Figure 5.2: Populating an array with user input
Processing a Single Dimension Array
There are a couple of different techniques that you can use to access the contents of an array. This includes accessing specific elements by referencing their index number and creating loops that iterate through all of the elements stored within an array. Both of these techniques are reviewed in the sections that follow.
Direct Access
Once an array has been populated with data, you can process it. One way to access the array contents is to specify the index number of a specific array element, as demonstrated below.
Dim astrCustomerList(4) astrCustomerList(0) = "XYZ Corp." astrCustomerList(1) = "ABC Co." astrCustomerList(2) = "Acme Inc." astrCustomerList(3) = "A&B Corp" astrCustomerList(4) = "ZZZ Enterprises" MsgBox "The third customer is " & astrCustomerList(2)
Figure 5.3 shows the output displayed by this script.
Figure 5.3: Accessing a specific element stored in an array
For Each…Next
Processing the contents of an array by specifying individual elements is not usually practical. Instead, you can create a For Each…Next loop that spins though the array, allowing you to programmatically process each element stored in the array. The syntax of the For Each…Next loop is outlined below.
For Each element In group Statements ... Next [element]
Element is a variable used to control the loop as it iterates through the array. Group specifies the name of the array to be processed. Statements are the statements that will be used to process the contents of the array.
The For Each…Next loop iterates until every element stored within the array is processed as demonstrated in the following example.
Script 5.1 Using the For...Each...Next loop to process an array
As you can see, a VBScript has been embedded into the BODY section of an HTML page. This script begins by defining an array called astrCustomerList that can store up to five elements. The next five statements store values in each element of the array. Next, a Document.Write statement is used to display a column heading on the Web page. Finally, a For Each…Next loop is used to iterate through the array and display its contents, which are represented by the variable i. Figure 5.4 shows the output created when this HTML page is loaded.
Figure 5.4: Using a For Each…Next loop to process all the elements stored in an array
Note |
Document is a browser object that represents the currently loaded HTML page. The Document object has a number of methods and properties associated with it, including the Write() method, which provides the ability to display text directly on HTML pages. For more information on the Document object, refer to Chapter 8, "VBScript and Internet Explorer." |
Note |
More information about how to work with the For Each…Next loop is available in Chapter 3, "Conditional Logic and Iterative Structures." |
Using the UBound Function
VBScript provides two functions that allow you to programmatically determine the upper and lower bounds of an array. These are the UBound() and LBound() functions. The LBound() function reruns the value of an array's lower bound (that is, its lowest element). However, as VBScript loops are always zero-based, this function is of little value.
Note |
VBScript is part of the Visual Basic family of programming languages. The other languages in this family are Visual Basic and VBA. VBScript represents a subset of these other languages. In Visual Basic and VBA, programmers have the ability to assign an array's lower bound, whereas in VBScript it is always set to zero. Therefore, while useful in Visual Basic and VBA programs, the LBound() function is redundant in VBScript. |
The UBound() function, on the other hand, has merit. It is used to retrieve the value of an array's upper bound (its highest element). The syntax of the UBound() function, when used to process a single-dimension array, is outlined below.
UBound(ArrayName)
ArrayName is the name of the array. The UBound() function is typically used as shown below.
x = UBound(ArrayName)
The value assigned to x is equal to one less than the actual number of elements in the array. Therefore, to determine the number of elements stored in the array, add 1 to the value returned by UBound(), as shown below.
x = UBound(ArrayName) + 1
For example, the following VBScript uses the UBound() function to terminate the execution of a For…Next loop when processing an array.
'************************************************************************* 'Script Name: Script 5.2.vbs 'Author: Jerry Ford 'Created: 01/17/2003 'Description: Using UBound() to determine an array's upper boundary '************************************************************************* 'Initialization Section Option Explicit Dim intArrayUpperBound, i, strDisplayString Dim astrCustomerList(4) astrCustomerList(0) = "XYZ Corp." astrCustomerList(1) = "ABC Co." astrCustomerList(2) = "Acme Inc." astrCustomerList(3) = "A&B Corp" astrCustomerList(4) = "ZZZ Enterprises" 'Main Processing Section intArrayUpperBound = UBound(astrCustomerList) For i = 0 to intArrayUpperBound strDisplayString = strDisplayString & astrCustomerList(i) & " " & vbCrLf Next MsgBox "Contacts:" & vbCrLf & vbCrLf & strDisplayString, , "Customer Contacts"
Figure 5.5 shows the output displayed by this script.
Figure 5.5: Using the UBound() function to determine an array's upper boundary
You can use the UBound() function to prevent a VBScript from attempting to access elements that do not exist, thus prevent errors from occurring. For example, the following statements define an array and populate it with five elements. The last statement attempts to access an element that does not exist in the array, resulting in the error message shown in Figure 5.6.
Figure 5.6: An error occurs when VBScript attempts to access an element that is beyond an array's upper boundary
Dim astrCustomerList(4) astrCustomerList(0) = "ABC Corp" astrCustomerList(1) = "XYZ Inc" astrCustomerList(2) = "Acme Co." astrCustomerList(3) = "L&F Inc" astrCustomerList(4) = "IV World" X = astrCustomerList(6)
Working with Multidimensional Arrays
Multidimensional arrays provide a powerful tool for storing and manipulating large amounts of data. Multidimensional arrays provide the ability to store information when the data that is collected consists of different types of related data. For example, a VBScript may need to store numerous pieces of information about a customer, including the customer's name, customer number, and phone number as demonstrated in Table 5.1.
Customer_ Name |
Customer_No |
Customer_Phone |
---|---|---|
XYZ Corp. |
12345 |
800-333-3333 |
ABC Co. |
98765 |
877-444-4444 |
Acme Inc. |
11122 |
800-555-5555 |
A&B Corp. |
22233 |
888-888-9999 |
ZZZ Enterprises |
33344 |
877-444-1111 |
Defining Multidimensional Arrays
The Dim statement can be used to define a multidimensional array. When used to define arrays in this manner, the Dim statement has the following syntax:
Dim ArrayName(dimensions)
Tip |
Another way to think of a two-dimensional array is as a one-dimensional array that consists of a collection of one-dimensional arrays. |
ArrayName is the name of the array being defined and dimensions is a comma-separated list of subscripts, each of which defines a dimension of the array. For example, the following statement defines a two-dimensional array.
Dim astrCustomerList(4,2)
The astrCustomerList array, as defined above, will be able to store five rows' and three columns' worth of information, allowing it to store all the information listed in Table 5.1.
Populating a Multidimensional Array
Once a multidimensional array is defined, it can be populated. In order to populate an element in the array, you must specify the element's index number. In the case of a two-dimensional array, the index number will be specified as (X, Y), which represents a point of intersection in the array between each dimension.
The following script demonstrates how to assign the data listed in Table 5.1 to the astrCustomerList array.
Const cCustomerName = 0 Const cCustomerNo = 1 Const cCustomerPhone = 2 Dim astrCustomerList(2,4) astrCustomerList(cCustomerName,0) = " XYZ Corp." astrCustomerList(cCustomerNo,0) = 12345 astrCustomerList(cCustomerPhone,0) = "800-333-3333" astrCustomerList(cCustomerName,1) = " ABC Co " astrCustomerList(cCustomerNo,1) = 98765 astrCustomerList(cCustomerPhone,1) = "877-444-4444" astrCustomerList(cCustomerName,2) = " Acme Inc." astrCustomerList(cCustomerNo,2) = 11122 astrCustomerList(cCustomerPhone,2) = "800-555-5555" astrCustomerList(cCustomerName,3) = " A&B Corp." astrCustomerList(cCustomerNo,3) = 22233 astrCustomerList(cCustomerPhone,3) = "888-888-9999" astrCustomerList(cCustomerName,4) = " ZZZ Enterprises " astrCustomerList(cCustomerNo,4) = 33344 astrCustomerList(cCustomerPhone,4) = "877-444-1111"
Tip |
Notice the use of the constants in the first three statements in the previous example. By assigning constants to represent the value of each of the three columns in the array, the code becomes self-documenting, making it easier to read and support. |
Processing Multidimensional Arrays
Once a multidimensional array has been defined and populated with data, it can be processed. Like static arrays, you can specify the location of individual elements in order to access their values. In the case of a two-dimensional array, this means specifying both the row and column coordinates, as demonstrated below.
WScript.Echo astrCustomerList(cCustomerName,2) WScript.Echo astrCustomerList(cCustomerPhone,2)
However, to process multidimensional arrays with large amounts of data, you will need to establish a loop, as demonstrated in the following example.
'************************************************************************* 'Script Name: Script 5.3.vbs 'Author: Jerry Ford 'Created: 01/17/2003 'Description: A multidimensional array example '************************************************************************* 'Initialization Section Option Explicit Const cCustomerName = 0 Const cCustomerNo = 1 Const cCustomerPhone = 2 Dim intArrayUpperBound, i, strDisplayString Dim astrCustomerList(2,4) 'Main Processing Section LoadArray() intArrayUpperBound = UBound(astrCustomerList,2) For i = 0 to intArrayUpperBound strDisplayString = strDisplayString & _ astrCustomerList(cCustomerName, i) & _ vbTab & astrCustomerList(cCustomerPhone, i) & " " & vbCrLf Next MsgBox strDisplayString, , "Multidimensional Array Example" 'Procedure Section Function LoadArray() astrCustomerList(cCustomerName,0) = "XYZ Corp." astrCustomerList(cCustomerNo,0) = 12345 astrCustomerList(cCustomerPhone,0) = "800-333-3333" astrCustomerList(cCustomerName,1) = "ABC Co. " astrCustomerList(cCustomerNo,1) = 98765 astrCustomerList(cCustomerPhone,1) = "877-444-4444" astrCustomerList(cCustomerName,2) = "Acme Inc." astrCustomerList(cCustomerNo,2) = 11122 astrCustomerList(cCustomerPhone,2) = "800-555-5555" astrCustomerList(cCustomerName,3) = "A&B Corp." astrCustomerList(cCustomerNo,3) = 22233 astrCustomerList(cCustomerPhone,3) = "888-888-9999" astrCustomerList(cCustomerName,4) = "ZZZ Enterprises" astrCustomerList(cCustomerNo,4) = 33344 astrCustomerList(cCustomerPhone,4) = "877-444-1111" End Function
The script begins by defining constants to represent each column in a two-dimensional array. Next, the variables to be used by the script are defined, followed by the definition of a two-dimensional array. Then the LoadArray() function is executed. This function assigns values to each element of the array. Finally, a loop is set up to process the contents of the array. The Ubound() function is used to determine upper boundary of the array's second dimension (the length of the column dimension). A For loop is then set up to process all elements of the array beginning with the first element (0) and going through the last element (intArrayUpperBound). As the loop iterates, a display string is assembled. This string consists of the values stored in the first (astrCustomerList(cCus tomerName, i)) and third (astrCustomerList(cCustomerPhone, i)) columns of the array. The last statement in the script displays the fully assembled string using the VBScript MsgBox() function. Figure 5.7 shows the output produced by this script.
Figure 5.7: Processing data stored in a multidimensional array
Note |
The syntax of the UBound() function when used to work with multidimensional arrays is shown below: LBound(ArrayName, dimension) ArrayName specifies the array to be tested. The Dimension parameter is optional. When used, the dimension parameter specifies the array dimension whose upper bound should be returned. Specify 1 for the first dimension, 2 for the second dimension, and so on. |
Creating Dynamic Arrays
In all of the preceding examples, the number of elements that were to be stored in each array were known at design time. However, in the real world, it is common not to know the number of elements that will need to be stored in advance. For example, if a script is set up to collect information about customers using the VBScript InputBox() function, there is often no way of knowing in advance how many different customers the user will enter data for. VBScript provides a solution to this dilemma in the form of dynamic arrays. A dynamic array is an array that can be resized during the execution of the script, meaning that its size can be increased or decreased.
Defining Dynamic Arrays
One way to define a dynamic array is to use the Dim statement to define it without specifying its size, as demonstrated below.
Dim astrCustomerList()
This allows you to come back later in your script and redimension the size of the array using the ReDim statement, as follows.
ReDim astrCustomerList(4)
In this example, the astrCustomerList array has been redimensioned so that it can store five elements. Another option when working with dynamic arrays is to define them initially with the ReDim statement instead of the Dim statement. This option allows you to assign an initial size to the array. There is no limit to the number of times that a dynamic array can be resized.
Resizing Single Dimension Dynamic Arrays
By default, all the data stored in a dynamic array is lost when it is resized. However, you can prevent this behavior by adding the Preserve keyword to the ReDim statement, as demonstrated below.
ReDim Preserve astrCustomerList(49)
In the case of this example, the array astrCustomerList is resized to allow it to store 50 elements without causing it to lose any data that it contained before it was increased in size.
Note |
If you resize a dynamic array by making it smaller, all of the data stored in the elements of the array that were removed are lost, even if you use the Preserve keyword when redimensioning the array. For example, if you define a single-dimension dynamic array, assign 10 elements to it, and then later resize it so that it can only store 5 elements, then the last 5 elements in the array will be lost. |
The following example provides a simple demonstration of how to redimension a dynamic array.
'************************************************************************* 'Script Name: Script 5.4.vbs 'Author: Jerry Ford 'Created: 01/17/2003 'Description: A demonstration of how to resize an array '************************************************************************* 'Initialization Section Option Explicit Dim strMessage, astrCustomerList, i strMessage = "Dynamic Array Demonstration" & vbCrLf & vbCrLf 'Main Processing Section DimTheArray() ReDimTheArray() DisplayResults() 'Procedure Section Function DimTheArray() ReDim astrCustomerList(2) astrCustomerList(0) = "XYZ Corp." astrCustomerList(1) = "ABC Co." astrCustomerList(2) = "Acme Inc." End Function Function ReDimTheArray() ReDim Preserve astrCustomerList(4) astrCustomerList(3) = "A&B Corp" astrCustomerList(4) = "ZZZ Enterprises" End Function Function DisplayResults() For Each i In astrCustomerList strMessage = strMessage & i & vbCrLf Next MsgBox strMessage, , "Resizing an Array" & Space(25) End Function
Three statements in the script's Main Processing Section control the overall execution of the script by calling upon three functions located in the Procedure Section. The DimTheArray() function defines a single-dimension dynamic array with an initial size of three elements. It then assigns values to each of these elements.
Next, the ReDimTheArray() function executes. This function redimensions the size of the array to allow it to store up to five elements. The Preserve keyword is included in order to ensure that no data currently stored in the array is lost. The function then assigns values to the two new array elements.
The final function that is executed is DisplayResults(). It uses a For Each…Next loop to process the contents of the newly expanded array so that it can display its contents. Figure 5.8 shows the output displayed by this script.
Figure 5.8: A demonstration of how to resize a dynamic array
The previous example demonstrated how to resize a dynamic array based on the assumption that you know in advance what size the array will need to be expanded to. However, in many cases you will not know in advance how big the dynamic array should be. This following example demonstrates how to write a script that dynamically resizes an array each time a new element is added. This allows the script to increase the size of the array as necessary to accommodate whatever amount of data is required.
'************************************************************************* 'Script Name: Script 5.5.vbs 'Author: Jerry Ford 'Created: 01/17/2003 'Description: Resizing a dynamic array based on user input '************************************************************************* 'Initialization Section Option Explicit Dim strUserInput, strMessage ReDim astrCustomerList(0) 'Main Processing Section CollectInputData() ProcessInputData() 'Procedure Section Function CollectInputData() Dim i i = 0 Do While UCase(strUserInput) <> "QUIT" strUserInput = InputBox("Type a customer name") If UCase(strUserInput) <> "QUIT" Then astrCustomerList(i) = strUserInput Else Exit Do End If i = i + 1 ReDim Preserve astrCustomerList(i) Loop End Function Function ProcessInputData() Dim i i = 0 For Each i In astrCustomerList strMessage = strMessage & i & vbCrLf Next MsgBox strMessage End Function
The script begins by defining its variables and defining an array called astrCustomerList with an initial size of 0. This allows the array to store a single element. The controlling logic of the script is located in the Main Processing Section, and it consists of two function calls. The first function called is CollectInputData(). This function uses a Do…While loop to control data collection. The VBScript InputBox() function is used to collect text input from the user. Data collection occurs until the user types the word quit. The Ucase() function is used to test each piece of data typed by the user to search for the word Quit. Each time a new entry is typed, the script assigns it as the last element in the array and then resizes the array to accommodate a new element.
Tip |
The Ucase() function can be used to convert text to all uppercase. This allows you to perform an all uppercase text comparison without being concerned about the case that the user uses. For example, in the previous script the user could type QUIT, quit, or QuIt to terminate the data entry process. |
The last function called in the script uses a For Each…Next loop to process each element stored in the array, to build a display string, and to display its results.
Resizing Multidimensional Dynamic Arrays
When preserving data stored in a multidimensional array, only the last dimension that is defined can be resized. For example, in the two-dimensional array presented earlier in this chapter, an array was set up to store the customer names, customer numbers, and customer phone numbers. Because the second dimension of the array was used to store customer phone numbers, it is the only dimension that can be resized. Fortunately, this works out well in this case, because it is unlikely that customers will change their names. It is also unlikely that the number assigned to the customer will change. However, the customer's phone number may change from time to time.
As another example, consider the following two-dimensional array.
ReDim astrCustomerList(2,2)
The array defined by this statement can be viewed as a table made up of three columns and three rows. However, since only the last dimension of a multidimensional array can be resized, only the elements stored in the second dimension of the array can be resized. To resize the array to contain additional data, you could increase the size of its second dimension as demonstrated below.
ReDim astrCustomerList(2,9)
This statement allows to you expand the size of the second dimension to store 10 elements.
Keep the following points in mind when resizing multidimensional arrays.
- You can redimension a multidimensional array by changing both the number of dimensions and the size of each dimension, but doing so will result in the loss of its data.
- To prevent the loss of data when resizing a multidimensional array, you may add the Preserve keyword to the ReDim statement, but in doing so, you limit the ability to modify the array to resizing only the length of the last dimension.
Erasing Arrays
VBScript provides the ability to erase the contents of an array using the Erase statement. The syntax of this statement is outlined below.
Erase arrayname
The Erase statement erases the contents of a static array but does not reduce the size of the array. When used to erase a dynamic array, the Erase statement erases the contents of the array and deallocates all storage used by the array, thus freeing up memory.
For example, the following statement erases the contents of an array called astrCustomerList.
Erase astrCustomerList
Using VBScript Functions to Work with Arrays
VBScript supplies two functions that are useful when working with arrays. These functions are briefly defined below.
- Array(). Retrieves a variant that contains an array
- IsArray(). Provides the ability to determine whether a variable is an array
Using the VBScript Array() Function
The Array() function provides a tool for quickly defining arrays. Its syntax is outlined below.
Array(arglist)
Arglist is a comma-separated list of elements to be stored in the array. If arglist is omitted, then a zero length array is set up. Otherwise the initial size of the array is determined by the number of elements supplied in the arglist. For example, the following statement defines an array that contains five elements.
astrCustomerList = Array("ABC Corp", "XYZ Inc", "Acme Co.", "L&F Inc", "IV World")
The Array() function allows you to reduce the number of statements required to create small arrays. For example, the above array could have just as easily been defined as shown below.
ReDim astrCustomerList(4) astrCustomerList(0) = "XYZ Corp." astrCustomerList(1) = "ABC Co." astrCustomerList(2) = "Acme Inc." astrCustomerList(3) = "A&B Corp" astrCustomerList(4) = "ZZZ Enterprises"
Using the IsArray() Function
The VBScript IsArray() function is used to test whether the specified variable is an array. It returns a value of True if the tested variable is an array. Otherwise it returns a value of False.
Except for arrays, VBScript variables are scalar, meaning that they only contain one value. If a VBScript attempts to use an array-related function such as UBound() or LBound() against a scalar variable, an error occurs, terminating script execution. An error will also occur if the script attempts to treat a scalar variable like an array by specifying an index number when referencing it. One way to guard against accidentally attempting to treat a scalar variable as if it were an array is to first test it using the IsArray() function.
The syntax of the IsArray() function is outlined below.
IsArray(variablename)
For example, the following statements define an array and then demonstrate how to use the IsArray() function.
ReDim astrCustomerList(4) X = IsArray(astrCustomerList) If x = "True" then MsgBox "This variable is an array." Else MsgBox "This is a scalar variable." End If
Summary
In this chapter, you learned how to work with single-dimension and multidimensional arrays. You also learned how to work with static and dynamic arrays. In addition, you learned different techniques for processing array contents, including how to access data stored in specific array cells and how to create loops that iteratively process the contents of an entire array. Other topics covered in this chapter included how to resize arrays as well as how to both preserve and erase their contents.