Dynamic arrays

You use a dynamic array if you want to defer declaring the number of the array's elements and dimensions until run time, or if you want to vary the array size at one or more points during execution of the application. To declare a dynamic array, you use a Dim statement (or one of its variations) with an empty subscript list (empty parentheses), as in this example:

Dim myDynamicArray() As String

Since this Dim statement contains no information about the dimensions of the array, the statement simply reserves the name myDynamicArray as the name of a dynamic array whose elements will be of type String:

When you declare a dynamic array, it has no dimensions or elements, and no storage is allocated for it. The array is unusable until you specify its dimensions and their bounds in a ReDim statement, which defines the array size and allocates storage for the elements and initializes them. The syntax of the ReDim statement is:

ReDim [ Preserve ] arrayName ( bounds ) [ As dataType ]

where arrayName is the name of an array that you previously declared with an empty bounds list, bounds is the bounds list with which you now want to define the number and extent of the array's dimensions, and As dataType specifies the data type of the elements that the array will hold. This must be the same as the data type in the original Dim statement. The optional Preserve keyword instructs LotusScript® to retain the current values of the elements in arrayName. This is useful if you have declared a dynamic array with Dim, defined its size with ReDim, assigned values to its elements, and then want to expand the array to accommodate additional elements and assign them values, as in this example:

Option Base 1
' Declare a dynamic String array. Later, this is
' defined as a one-dimensional array whose elements
' are assigned values that the user enters. 
Dim myNames() As String
Dim ans1 As Integer
Dim ans2 As Integer
Dim counter As Integer
Dim userInput As String
' Ask the user to enter a number and assign it to ans1%.
ans1% = CInt(InputBox$ _
   ("How many names would you like to enter?"))
' Use ans1% as the upper bound of the array's only dimension.
ReDim myNames(ans1%)
' Elicit ans1% strings from the user, and assign them
' to successive elements in the array.
For counter% = 1 to ans1%
  myNames(counter%) = InputBox$("Enter a name: ")
Next
' Print the contents of the array on a single line
' with a space between the value of each element.
For counter% = 1 to ans1%
   Print myNames(counter%) " " ;
Next
' Output: a newline
Print ""
' Ask the user for another number and assign it to ans2%.
ans2% = CInt(InputBox$("How many more names?"))
' If the number is greater than 0, resize the
' array, preserving its original values, so that the
' user can enter additional values.
If ans2% > 0 Then
  ReDim Preserve myNames(ans1% + ans2%)
  ' Elicit the new values and assign them to the
  ' elements that have been allocated after the old ones.
  For counter% = 1 to ans2%
    myNames(counter% + ans1%) = InputBox$("Enter a name: ")
  Next 
  ' Print the contents of the array on a single line
  ' with a space between the value of each element.
   For counter% = 1 to ans1% + ans2%
    Print myNames(counter%) " " ; 
  Next   
  Print ""
End If

Using the Preserve keyword

When you define the size of a dynamic array in the first ReDim statement that applies to it, this permanently defines the number of dimensions for that array. You can later change the values of any of the lower or upper bounds in the bounds list as long as the ReDim statement you use does not include the Preserve keyword. LotusScript® then reallocates the amount of storage for the array that the bounds list specifies and initializes the array's elements to the default values appropriate to their data type. If you do include Preserve in a ReDim statement, the only bound that LotusScript® lets you change (by incrementing) is the upper bound of the last array dimension, in which case LotusScript® allocates the appropriate amount of additional storage and initializes the additional array elements. You cannot change the number of dimensions of an array or the data type of its elements with a ReDim statement.

Using the Erase statement

You can use the Erase statement to recover all of the storage currently allocated to a dynamic array. Applied to a fixed array, the Erase statement only reinitializes the array elements (to zeros, empty strings, EMPTY, or NOTHING, depending on the data type of the array's elements).

Using the built-in functions

You can determine whether an identifier is the name of an existing array with the IsArray function. You can determine whether an array is a fixed array or a dynamic array with the DataType function, and you can ascertain the data type of an array's elements with either the DataType or the TypeName function. You can use any of the LotusScript® built-in functions that operate on scalar values to operate on the elements of an array, as in this example:

' Declare arrays with a base of 1 and containing 10 elements
Dim myDblArray(1 To 10) As Double
Dim anIntArray(1 To 10) As Integer
Dim counter As Integer

' Seed the random number generator.
Randomize
' Populate myDblArray with random numbers
' greater than 0 and less than 1.
For counter% = 1 To 10
    myDblArray(counter%) = Rnd()
Next

' Populate anIntArray with the elements of myDblArray
' after rounding to one decimal place, multiplying
' by 10, dividing by 10 and adding 1 to the remainder
' to yield a whole number between 1 and 10.
For counter% = 1 To 10
    anIntArray(counter%) = _
      ((Round(myDblArray(counter%), 1) * 10) Mod 10) + 1
Next

' Test the first element of anIntArray for its data type.
Print TypeName(anIntArray(1))
' Output: INTEGER

' Print the contents of myDblArray and anIntArray.
For counter% = 1 To 10
   print myDblArray(counter%) & "    " & anIntArray(counter%)
Next
' Output: something like the following:
' .402520149946213    5
' .530154049396515    6
' .309299051761627    4
' 5.76847903430462E-02    2
' 2.41877790540457E-02    1
' .988802134990692    1
' .688120067119598    8
' .493557035923004    6
' .28598952293396    4
' .610387742519379    7

Dim aStringArray(1 to 5, 1 to 2)
aStringArray(1,1) = "Roman" 
aStringArray(1,2) = "Minsky"
aStringArray(2,1) = "Sara"
aStringArray(2,2) = "Nala"
aStringArray(3,1) = "Raymond"
aStringArray(3,2) = "Nala"
aStringArray(4,1) = "Sandra"
aStringArray(4,2) = "Brooks"
aStringArray(5,1) = "Simon"
aStringArray(5,2) = "Anders"
' Check to see if the first two characters of each element
' in the first dimension of aStringArray would be SA
' if they were uppercase. If so, print the corresponding
' element in the second dimension of the array, making
' its first character uppercase and the rest lowercase.
For counter% = 1 to 5
   If UCase$(Left$(aStringArray(counter%, 1), 2)) = "SA" Then
      Print UCase$(Left$(aStringArray(counter%, 2), 1)) _
      & LCase$(Mid$(aStringArray(counter%, 2),  2, _
      Len(aStringArray(counter%, 2))))
   End If
Next
' Output:
' Nala
' Brooks
 

There is no built-in function to tell whether an dynamic array is initialized. However, you can write a function that will trap the error condition generated by an attempt to use the array, and use that to tell.

IsArrayInitialized(arr As Variant) As Boolean	
Dim intTemp As Integer	
On Error Goto uninit	
intTemp = Ubound(arr)	
IsArrayInitialized = True	
Exit Function 
Function

It is only slightly more efficient to use a specific type for the arr parameter instead of variant (e.g. "arr( ) As String" instead of "arr As Variant").