| Downloads |
|---|
| 5627.zip |
Last month, I discussed three basic syntax elements: variables, constants, and subtypes. However, I intentionally didn't discuss an important subtype: Array. This month, I take a close look at what Array variables, or simply arrays, are and how you can create, fill, resize, traverse, erase, split, and join them. I also cover multidimensional and nested arrays.
Related: Understanding VBScript: Operators
You can create two types of arrays: static and dynamic. Static arrays stay a fixed size throughout their lifetime—that is, the index size remains constant. Thus, when you create a static array, you must know how many items the array will contain throughout its lifetime. If you don't know this information or you know that the array's index size will change, you need to create a dynamic array. Dynamic arrays don't have a fixed index size. You can increase or decrease the index size at any time.
Related: Sorting Arrays in VBScript
The number in parentheses specifies the maximum value of indexes in the array. The value of 2 denotes that the array's indexes range from 0 to 2, which means the array can contain up to three items. In other words, 2 is the array's upper bound. Arrays also have a lower bound. The lower bound of static (and dynamic) VBScript arrays is always 0 because arrays always start with the 0 index.
When you create a static array, the lower and the upper bound are 0 by default and the array is empty. Once you set a static array's upper bound, you can't change it because the static array's index size remains constant.
You can create a dynamic array in three ways:
However, this array is uninitialized, which means you won't be able to use it until you set its size. To set the array's size, you use a ReDim statement to set the upper bound. For example, if you want to set an upper bound of 2 for arrUsers, you specify
ReDim arrUsers(2)
Although you set arrUsers' index size, the array is empty.
creates a dynamic array whose initial size is 3. The arrUsers array is empty.
You typically use ReDim when you already know a useful initial size for the dynamic array. Using ReDim is more direct and saves you from adding an extra line of code.
Note that the code doesn't explicitly mention the size of the array. VBScript determines the array's size by the number of arguments (e.g., "Mary" is an argument) that you pass to the Array function. Keep in mind that the returned array contains only those items that you pass as arguments.
Table 1 on the Win32 Scripting Journal Web site summarizes the options for creating dynamic and static arrays. Because the table mentions details such as whether you need to fill the array, you can use it as a quick reference guide.
In this case, the value in the parentheses after the common name isn't the array's upper bound but rather the particular index that you're filling. For example, you're filling the 0 index with the "bread" data value. Figure 1 graphically depicts the filled arrGroc static array.
The items you're assigning to the arrGroc indexes are in quotation marks because the data's subtype is String. In this case, the array's indexes contain homogeneous data (i.e., data with the same subtype). An array's indexes can also contain heterogeneous data (i.e., data with different subtypes).
You can choose not to fill an index. If you leave an index empty, the array's index positions don't change. For example, if you leave the 0 index empty, it still remains in the first position.
Although leaving an index empty doesn't result in an error, assigning an item to an inappropriate index does. For example, in arrGroc, if you specify either of these lines
you'll get an error message when you run the code. Using the -1 index produces an error because indexes always start from 0. You can't use negative indexes. The 3 index produces an error because you declared arrGroc as an array with an upper bound of 2. You can't use an index that exceeds the upper bound that you previously set.
To use an array's values, you can use the array's common name and the index of interest. For example, you can use the VBScript's MsgBox function to display an item in a dialog box. If you want to find the item in the first position of the arrGroc array, you use the code
MsgBox arrGroc(0)
which prompts MsgBox to display the result of "bread".
If you want to find out how many indexes an array contains, you can use VBScript's LBound and UBound functions, which return the lower and upper bounds, respectively, for a given array. To use these functions, you specify either LBound or Ubound, followed by the array's common name in parentheses. For example, if you want to display the lower and upper bound of arrGroc, you specify
The result of MsgBox LBound is 0. The result of MsgBox UBound is 2.
At any point in a script, you can use the ReDim statement to change a dynamic array's size or to initially set the size if you create an uninitialized dynamic array. For example, if you use the code
to create an uninitialized dynamic array at the beginning of your script, you can later set the array's size to 4 by specifying
You can also use ReDim to resize an array to a smaller dimension (e.g., go from an index size of 11 to 5). You can resize an array as many times as you want.
Whether the new index size is smaller or larger, ReDim reallocates the original array's memory block to the new sized array, which means you lose all information about the original array's indexes. For example, suppose you create arrUsers, set the initial size to 4, assign the 0 index to the username "Mary", and use MsgBox to display the item that the 0 index represents:
At this point, MsgBox displays the result "Mary". However, if you resize arrUsers to 6 and again use MsgBox to display the item that the 0 index represents
the result is an empty display. Resizing the array to 6 causes the loss of all the original array's data.
Fortunately, you can prevent data loss by specifying the keyword Preserve after ReDim. When you increase an array's size, Preserve saves all array data. When you decrease an array's size, Preserve limits the loss of data to only those items no longer represented by the new indexes. For example, the code
ReDim Preserve arrUsers(5)
resizes arrUsers to 6 items and preserves all the existing items represented by indexes 0 through 5. So, if you apply Preserve to the previous example, the second use of MsgBox returns the name "Mary" rather than an empty display.
For example, suppose you use the Array function to create and fill arrUsers with "Mary", "Bob", and "Ann". You then decide to add "John" to arrUsers. If you specify
you're using a constant value (3) to set the array's new upper bound and index. A better approach is to use UBound to set the new upper bound and index:
In the ReDim Preserve statement, UBound refers to the array's old size. You add a value of 1 to UBound because you're adding another index. You use UBound again to set the new index to "John". In this instance, UBound refers to the index number. You don't need to add 1 to UBound this time because the previous line already set arrUsers to the new value.
Dim arrGroc(2)
Instead of using three MsgBox functions
to display each item in a separate message box, you can use one For...Next statement to display all the items in one message box. For...Next repeats a group of statements (in this case, the MsgBox line) a specified number of times. You use the lower and upper bounds to specify that number:
For...Next traverses arrGroc in three steps. The letter i is a variable index that represents the index MsgBox is displaying at any particular step. In other words, i represents the 0 index in the first step, the 1 index in the second step, and the 2 index in the third step.
Traversing dynamic arrays isn't as simple because you don't know the upper bound. To traverse dynamic arrays (and even static arrays), you can use LBound and UBound to dynamically return the lower and upper bounds for a given array. So, instead of specifying an array's lower and upper bounds, you use LBound and UBound:
Another technique you can use to traverse dynamic and static arrays applies VBScript's For Each...Next statement, which repeats a group of statements for each item in an array. Because this technique doesn't use index-based navigation, you don't have to deal with lower and upper bounds. This technique assigns all the items in an array to the elem variable. Once the items are in the variable, you can manipulate them. For example, to display all the items in arrUsers, you use the code
For dynamic arrays, Erase releases an array's allocated memory. For example, if you run the code in Listing 1 that erases the dynamic array, you get an error because Erase releases all the memory that refers to the array. The variable still exists, but the information about the bounds doesn't. Erase returns a dynamic array to the state immediately after its declaration when its bounds are uninitialized and unusable.
the function returns an array in which the 0 index represents "One", the 1 index represents "Two", and the 2 index represents "Three".
The Join function performs the reverse task. It combines the substrings that each array index contains into one string and assigns that string to a String variable (not an array—the prefix str denotes a variable whose subtype is String). For example, the code
combines the substrings in the arrList indexes and assigns the result—the original string "One,Two,Three"—to strNumbers.
Figure 2 provides a graphical view of a two-dimensional array. Similar to a table, a 2-D array has a specific number of rows and columns. The first dimension forms the rows, and the second dimension forms the columns. Each cell represents an index.
You create static and dynamic 2-D arrays the same way you create 1-D arrays, except in 2-D arrays you have two upper bound values in the parentheses: the upper bound of the first dimension followed by the upper bound of the second dimension. For example, to create the 2-D static array, arrMultiGroc, in Figure 2, you specify
If you create a dynamic multidimensional array and you want to resize it with the ReDim Preserve statement, by design you can modify only the last dimension of the array. (If you use ReDim without Preserve, you can modify any dimension.) For example, suppose you create a dynamic 2-D array, arrMultiUsers, with the code
and later you want to resize it, preserving the original array indexes. If you specify
you'll get an error message because you changed the first dimension. If you specify
the code will successfully execute. If you specify
ReDim arrMultiUsers(2,2)
the code will execute, but you'll lose all the original index data because you didn't specify Preserve.
You manipulate the indexes of static and dynamic 2-D arrays the same way you manipulate the indexes of their 1-D counterparts. However, you must include the indexes of first and second dimensions, respectively, in parentheses. For example, to fill and display the 2,1 index of arrMultiGroc, you specify
VBScript supports up to 60 dimensions. However, you'll probably never use more than three dimensions. If you're curious about what a 3-D array looks like, check out Figure A on the Win32 Scripting Journal Web site.
Listing 2 shows how to nest an array. You first create and fill the array that you'll nest inside another array. In this case, that array is arrChild. You then assign arrChild as the third item (the 2 index) of the arrMain array. Note that arrMain contains heterogeneous data values.
The last line in Listing 2 displays the value of the index you just filled. As this line shows, you must use a special syntax to manipulate the items in a nested array. The code to address the first item of the child array is
Because a nested array isn't a multidimensional array, you can't use two conjunct indexes such as (2,0). Actually, you're just addressing the first item of a 1-D array called arrMain(2).
Arrays aren't only easy to use but also powerful. Some of their many advantages include the following:
Learn more: Arrays and Temporary Files