Arrays


An array is a data structure in which similar elements of data are arranged in an indexed structure-for example, a column of names or a table of numbers . See Table 8 . An array allows you to store many different values in a single variable, and uses parentheses to define and access array elements. OOo Basic does not support the use of square brackets as used by other languages such as C and Java.

Table 8: Defining an array is easy!

Definition

Elements

Description

Dim a(5) As Integer

6

From 0 through 5 inclusive.

Dim b(5 To 10) As String

6

From 5 through 10 inclusive.

Dim c(-5 to 5) As String

11

From -5 through 5 inclusive.

Dim d(5, 1 To 6) As Integer

36

Six rows with six columns from 0 through 5 and 1 through 6.

Dim e(5 To 10, 20 To 25) As Long

36

Six rows with six columns from 5 through 10 and 20 through 25.

Array variables are defined using the Dim statement. Think of a one-dimensional array as a column of values and a two-dimensional array as a table of values. Higher dimensions are supported but difficult to visualize. An array index may be any Integer value from -32,768 through 32,767.

Tip  

You must declare array variables before using them, even if you don't use "Option Explicit."

If the lower dimension of an array is not specified, the default lower bound of an array is zero. (Programmers call these arrays " zero-based .") Thus, an array with five elements will have elements numbered a(0) through a(4). Use the keywords "Option Base 1" to change the default lower bound of an array to start at 1 rather than 0. This must be done before any other executable statement in the program.

 Option Base { 0  1 } 
Tip  

Specify the lower bound of an array rather than relying on the default behavior. This is more portable and it will not change when the Option Base statement is used.

Dim a(3) allows for four elements: a(0), a(1), a(2), and a(3). Option Base does not change the number of elements that an array can store; it only changes how they are indexed. Using Option Base 1, the same statement still allows for four elements: a(1), a(2), a(3), and a(4). I consider this behavior unintuitive and recommend against using Option Base. If you want specific array bounds, the preferred option is to explicitly declare the array bounds. For example, Dim a(1 To 4). Option Base has risks in terms of communicating clear documentation and ensuring portability.

Compatibilty  

Visual Basic handles Option Base 1 differently than OOo Basic. VB changes the lower bound to 1 but does not change the upper bound. Visual Basic .NET no longer supports Option Base. When OOo Basic supports "Option Compatible," then "Option Base 1" will not increase the upper bound by 1. In other words, OOo Basic will act like VB.

Accessing and changing the values in an array is easy (see Listing 18 ). Initializing an array this way is tedious .

Listing 18: ExampleSimpleArray1 is found in the Variables module in this chapter's source code files as SC02.sxw.
start example
 Sub ExampleSimpleArray1   Dim a(2) As Integer, b(-2 To 1) As Long   Dim m(1 To 2, 3 To 4)   REM Did you know that multiple statements can be placed   REM on a single line if separated by a colon?   a(0) = 0    : a(1) = 1   : a(2) = 2   b(-2) = -2  : b(-1) = -1 : b(0) = 0 : b(1) = 1   m(1, 3) = 3 : m(1, 4) = 4   m(2, 3) = 6 : m(2, 4) = 8   Print "m(2,3) = " & m(2,3)   Print "b(-2) = " & b(-2) End Sub 
end example
 

To quickly fill a Variant array, use the Array function (see Listing 19 ), which returns a Variant array with the included data (see Figure 2 ). The functions LBound and Ubound return the lower bound and upper bound of an array. Routines supported by OOo Basic are summarized in Table 9 and discussed thoroughly later.

Table 9: Summary of subroutines and functions related to arrays.

Function

Description

Array(args)

Return a Variant array that contains the arguments.

DimArray(args)

Return an empty Variant array. The arguments specify the dimension.

IsArray(var)

Return True if this variable is an array, False otherwise .

Join(array) Join(array, delimiter )

Concatenate the array elements separated by the optional string delimiter and return as a String. The default delimiter is a single space.

LBound(array) LBound(array, dimension)

Return the lower bound of the array argument. The optional dimension specifies which dimension to check. The first dimension is 1.

ReDim var(args) As Type

Change the dimension of an array using the same syntax as the DIM statement. The keyword Preserve keeps existing data intact.

Split(str) Split(str, delimiter) Split(str, delimiter, n)

Split the string argument into an array of strings. The default delimiter is a space. The optional argument "n" limits the number of strings returned.

UBound(array) UBound(array, dimension)

Return the upper bound of the array argument. The optional dimension specifies which dimension to check. The first dimension is 1.

click to expand
Figure 2: There are different variable types in the same array.
Listing 19: ExampleArray is found in the Variables module in this chapter's source code files as SC02.sxw.
start example
 Sub ExampleArrayFunction   Dim a, i%, s$   a = Array("Zero", 1, Pi, Now)   Rem String, Integer, Double, Date   For i = LBound(a) To UBound(a)     s$ = s$ & i & " : " & TypeName(a(i)) & " : " & a(i) & CHR$(10)   Next   MsgBox s$, 0, "Example of the Array Function" End Sub 
end example
 

A variable defined as an array but not dimensioned, such as Dim a(), is called an empty array. Test for an empty array by comparing the upper bound of the array to the lower bound. If the upper bound is less than the lower bound, you have an empty array for which no dimensions have been set. An array that has been dimensioned, such as Dim a (5), is not empty.

It is possible to reference an entire array. For example, in Listing 19, the statement "Lbound(a)" returns the lower bound of the array a(). An array declared with the dimensions specified must always be followed by parentheses "()". For example, the variable b() in Listing 20 must be used as "b()". An array declared without the dimensions specified may be written with, or without, the trailing parenthesis. For example, the variable a() in Listing 20 may be used as either "a" or "a()".

Listing 20: Parentheses are not always required but are always allowed.
start example
 Sub ArrayDimensionError   Dim a(), b(1 To 2), c   REM Valid constructs   LBound(a()) : LBound(a) : LBound(b()) : LBound(c()) : Lbound(c)   REM Invalid use of LBound(b) yields the run-time error   REM Dimension specifications do not match   LBound(b) End Sub 
end example
 

Changing the Dimension of an Array

The desired dimension of an array is not always known ahead of time. Sometimes the dimension is known but it changes periodically and the code must be changed. An array variable can be declared with or without specifying the dimensions. OOo Basic provides a few different methods to set or change the dimensions of an array.

The Array function generates a Variant array that contains data. This is a quick way to initialize an array. You are not required to set the dimension of the array, but if you do, it will change to become the array returned by Array.

 Dim a() a = Array(3.141592654, "PI", 9.81, "Gravity") 

The arguments passed to the Array function become data in the returned Variant array. The DimArray function, on the other hand, interprets the arguments as the dimensions of an array to create (see Listing 21 ). The arguments can be expressions, so a variable can be used to set the dimension.

Listing 21: ExampleDimArray is found in the Variables module in this chapter's source code files as SC02.sxw.
start example
 Sub ExampleDimArray   Dim a(), i%   a = Array(10, 11, 12)   Print "" & LBound(a()) & " " & UBound(a())        Rem 0 2   a() = DimArray(3)                                 REM the same as Dim a(3)   a() = DimArray(2, 1)                              REM the same as Dim a(2,1)   i = 4   a = DimArray(3, i)                                Rem the same as Dim a(3,4)   Print "" & LBound(a() ,1) & " " & UBound(a() ,1)  Rem 0, 3   Print "" & LBound(a() ,2) & " " & UBound(a() ,2)  Rem 0, 4   a() = DimArray()      REM an empty array End Sub 
end example
 

The Array and DimArray functions both return an array of Variants. The ReDim statement changes the dimension of an existing array. This can change both individual dimensions and the number of dimensions. The arguments can be expressions because the ReDim statement is evaluated at run time.

 Dim e() As Integer, i As Integer i = 4 ReDim e(5) As Integer       REM 0 To 5 is valid ReDim e(3 To 10) As Integer REM 3 To 10 is valid ReDim e(3, i) As Integer    REM (0 To 3, 0 To 4) is valid 
Tip  

Although neither LBound nor UBound works on an empty array returned from DimArray(), because the array has no dimensions, both methods will work with empty arrays in OOo 2.0. An empty array has one dimension, but the lower bound is zero and the upper bound is -1. Use ReDim to cause an existing array to become empty.

The ReDim statement supports the keyword Preserve. This attempts to save the data when the dimensions of an array are changed. Increasing the dimension of an array should preserve all of the data, but decreasing the dimension causes data to be lost by truncation . Data can be truncated at either end. If an element in the new array existed in the old array, the value is unchanged. Unlike some variants of BASIC, OOo Basic allows all dimensions of an array to be changed while still preserving data.

 Dim a() As Integer ReDim a(3, 3, 3) As Integer a(1,1,1) = 1 : a(1, 1, 2) = 2 : a(2, 1, 1) = 3 ReDim preserve a(-1 To 4, 4, 4) As Integer Print "(" & a(1,1,1) & ", " & a(1, 1, 2) & ", " & a(2, 1, 1) & ")" 

ReDim specifies both the dimensions and the type. The type specified with the ReDim statement must match the type specified when the variable is declared. If the types differ , you'll see the compile-time error "Variable already defined."

Listing 22 is a utility function that accepts a simple array and returns a string with all of the elements in the array. The ReDim example code, also in Listing 22, uses ArrayToString.

Listing 22: ArrayToString and ExampleReDimPreserve are found in the Variables module in this chapter's source code files as SC02.sxw.
start example
 REM ArrayToString accepts a simple array and places the value REM of each element in the array into a string. Function ArrayToString(a() As Variant) As String   Dim i%, s$   For i% = LBound(a()) To UBound(a())     s$ = s$ & i% & " : " & a(i%) & CHR$(10)   Next   ArrayToString = s$ End Function Sub ExampleReDimPreserve   Dim a(5) As Integer, b(), c() As Integer   a(0) = 0 : a(1) = 1 : a(2) = 2 : a(3) = 3 : a(4) = 4 : a(5) = 5   Rem a is dimensioned from 0 to 5 where a(i) = i   MsgBox ArrayToString(a()), 0 , "a() at start"   Rem a is re-dimensioned from 1 to 3 where a(i) = i   ReDim Preserve a(1 To 3) As Integer   MsgBox ArrayToString(a()), 0 , "a() after ReDim"   Rem Array() returns a Variant type   Rem b is dimensioned from 0 to 9 where b(i) = i+1   b = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)   MsgBox ArrayToString(b()), 0 , "b() at initial assignment"   Rem b is dimensioned from 1 to 3 where b(i) = i+1   ReDim Preserve b(1 To 3)   MsgBox ArrayToString(b()), 0 , "b() after ReDim"   Rem The following is NOT valid because the array is already dimensioned   Rem to a different size   Rem a = Array(0, 1, 2, 3, 4, 5)   Rem c is dimensioned from 0 to 5 where a(i) = i   Rem If "ReDim" had been done on c, then this would NOT work   c = Array(0, 1, 2, "three", 4, 5)   MsgBox ArrayToString(c()), 0 , "Integer array c() Assigned to a Variant"   Rem Ironically, this is allowed but c will contain no data!   ReDim Preserve c(1 To 3) As Integer   MsgBox ArrayToString(c()), 0 , "ReDim Integer c() after assigned Variant" End Sub 
end example
 
Compatibility  

Visual Basic has different rules for changing the dimensions of an array, and these rules change between versions of Visual Basic. As a general rule, OOo Basic is more flexible.

The Unexpected Behavior of Arrays

Assigning one Integer variable to another copies the value, and the variables are not related in any other way. See Listing 23 . In other words, if you change the first variable's value, the second variable's value does not change. This is not true for array variables. Assigning one array variable to another makes a reference to the first array rather than copying the data. All changes made to either are automatically seen by the other. It doesn't mater which one is changed; they are both affected. This is the difference between "pass by value " (integers) and "pass by reference" (arrays).

Listing 23: ExampleArrayCopylsRef is found in the Variables module in this chapter's source code files as SC02.sxw.
start example
 Sub ExampleArrayCopylsRef   Dim a(5) As Integer, c(4) As Integer, s$   c(0) = 4 : c(1) = 3 : c(2) = 2 : c(3) = 1 : c(4) = 0   a() = c()   a(1) = 7   c(2) = 10   s$ = "**** a() *****" & CHR$(10) & ArrayToString(a()) & CHR$(10) &_        CHR$(10) & "**** c() *****" & CHR$(10) & ArrayToString(c())   MsgBox s$, 0 , "Change One, Change Both" End Sub 
end example
 

If array a() is assigned to array b(), then a() and b() both reference the same data. If b() is then assigned to a completely different array c(), b() and c() both reference the same data but array a() is left unchanged. In other words, the statement a() = b() does not cause a() to reference the variable b(), but rather to reference the same data. To illustrate this, start by creating three arrays-a(), b(), and c()-as shown in Figure 3 . Internally, OOo Basic creates three arrays that are referenced by a(), b(), and c().

click to expand
Figure 3: Assigning an array assigns a reference.

The next step is to assign the variable a() to the variable b(). These are array variables so a() references the same array that b() references (see Figure 4 ). The original array referenced by a() is no longer referenced.

click to expand
Figure 4: Assigning an array assigns a reference.

If I modify a(), this change is seen by b() because they reference the same array. If I then assign b() to array c(), array b() references the same array that c() references. The variable a(), however, remains unchanged, as shown in Figure 5 .

click to expand
Figure 5: Assigning an array assigns a reference.
Bug  

No type checking is performed when an array is assigned to another array. Do not assign arrays of different types to each other.

Because no type checking is performed when an array is assigned to another array, unexpected and obscure problems can occur. The Array function returns a Variant array and is the quickest method to assign multiple values to an array variable. An obvious problem is that an Integer array may contain String values if it references a Variant array. A less obvious problem is that the ReDim statement works based on the declared type. The statement "ReDim Preserve" on an Integer array assigned to a Variant array fails to preserve the data.

 Dim a() As Integer                  REM Declare a() as an Integer() a() = Array(0, 1, 2, 3, 4, 5, 6)    REM Assign a Variant() to an Integer() ReDim Preserve a(l To 3) As Integer REM This wipes the array 

To safely assign arrays while maintaining the correct data type, another method is required. Copy each element in the array individually. This also prevents two array variables from referencing the same array. See Listing 24 .

Listing 24: ExampleSetIntArray is found in the Variables module in this chapter's source code files as SC02.sxw.
start example
 Sub ExampleSetIntArray   Dim iA() As Integer   SetIntArray(iA, Array(9, 8, "7", "six"))   MsgBox ArrayToString(iA), 0, "Assign a Variant to an Integer" End Sub REM Dimension the first array to have the same dimensions as the second. REM Perform an element-by-element copy of the array. Sub SetIntArray(iArray() As Integer, v() As Variant)   Dim i As Long   ReDim iArray(LBound(v()) To UBound(v())) As Integer   For i = LBound(v) To UBound(v)     iArray(i) = v(i)   Next End Sub 
end example
 



OpenOffice.org Macros Explained
OpenOffice.org Macros Explained
ISBN: 1930919514
EAN: 2147483647
Year: 2004
Pages: 203

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net