Mapping of Sequences and Arrays

From Apache OpenOffice Wiki
< Documentation‎ | DevGuide
Revision as of 13:36, 23 December 2020 by DiGro (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search



Many UNO interfaces use sequences, as well as simple types. The Apache OpenOffice Basic counterpart for sequences are arrays. Arrays are standard elements of the Basic language. The example below shows how they are declared:

  Dim a1( 100 )    ' Variant array, index range: 0-100 -> 101 elements
 
  Dim a2%( 5 )     ' Integer array, index range: 0-5 -> 6 elements
 
  Dim a3$( 0 )     ' String array, index range: 0-0 -> 1 element
 
  Dim a4&( 9, 19 ) ' Long array, index range: (0-9) x (0-19) -> 200 elements

Basic does not have a special index operator like [] in C++ and Java. Array elements are accessed using normal parentheses ():

  Dim i%, a%( 10 )
  for i% = 0 to 10           ' this loop initializes the array
      a%(i%) = i%
  next i%
 
  dim s$
  for i% = 0 to 10           ' this loop adds all array elements to a string
      s$ = s$ + " " + a%(i%)
  next i%
  msgbox s$                  ' Displays the string containing all array elements
 
  Dim b( 2, 3 )
  b( 2, 3 ) = 23
  b( 0, 0 ) = 0
  b( 2, 4 ) = 24             ' Error ”Subscript out of range”

As the examples show, the indices in Dim commands differ from C++ and Java array declarations. They do not describe the number of elements, but the largest allowed index. There is one more array element than the given index. This is important for the mapping of Apache OpenOffice Basic arrays to UNO sequences, because UNO sequences follow the C++/Java array semantic.

When the UNO API requires a sequence, the Basic programmer uses an appropriate array. In the following example, oSequenceContainer is an object that has a property TheSequence of type sequence<short>. To assign a sequence of length 10 with the values 0, 1, 2, ... 9 to this property, the following code can be used:

  Dim i%, a%( 9 ) ' Maximum index 9 -> 10 elements
  for i% = 0 to 9 ' this loop initializes the array
      a%(i%) = i%
  next i%
 
  oSequenceContainer.TheSequence = a%()
 
  ' If “TheSequence” is based on XPropertySet alternatively
  oSequenceContainer.setPropertyValue( “TheSequence”, a%() )

The Basic programmer must be aware of the different index semantics during programming. In the following example, the programmer passed a sequence with one element, but actually passed two elements:

  ' Pass a sequence of length 1 to the TheSequence property:
  Dim a%( 1 )   ' WRONG: The array has 2 elements, not only 1!
  a%( 0 ) = 3   ' Only Element 0 is initialized, 
                 ' Element 1 remains 0 as initialized by Dim
 
  ' Now a sequence with two values (3,0) is passed what 
  ' may result in an error or an unexpected behavior!
  oSequenceContainer.setPropertyValue( “TheSequence”, a%() )
Documentation note.png When using Basic arrays as a whole for parameters or for property access, they should always be followed by '()' in the Basic code, otherwise errors may occur in some situations.

It can be useful to use a Apache OpenOffice Basic RTL function called Array() to create, initialize and assign it to a Variant variable in a single step, especially for small sequences:

  Dim a ' should be declared as Variant
  a = Array( 1, 2, 3 )
 
  ' is the same as
 
  Dim a(2)
  a( 0 ) = 1
  a( 1 ) = 2
  a( 2 ) = 3

Sometimes it is necessary to pass an empty sequence to a UNO interface. In Basic, empty sequences can be declared by omitting the index from the Dim command:

  Dim a%() ' empty array/sequence of type Integer
 
  Dim b$() ' empty array/sequence of String

Sequences returned by UNO are also represented in Basic as arrays, but these arrays do not have to be declared as arrays beforehand. Variables used to accept a sequence should be declared as Variant. To access an array returned by UNO, it is necessary to get information about the number of elements it contains with the Basic RTL functions LBound() and UBound().

The function LBound() returns the lower index and UBound() returns the upper index. The following code shows a loop going through all elements of a returned sequence:

  Dim aResultArray ' should be declared as Variant
  aResultArray = oSequenceContainer.TheSequence
 
  dim i%, iFrom%, iTo%
  iFrom% = LBound( aResultArray() )
  iTo% = UBound( aResultArray() )
  for i% = iFrom% to iTo% ' this loop displays all array elements
    msgbox aResultArray(i%)
  next i%

The function LBound() is a standard Basic function and is not specific in a UNO context. Basic arrays do not necessarily start with index 0, because it is possible to write something similar to:

  Dim a (3 to 5 )

This causes the array to have a lower index of 3. However, sequences returned by UNO always have the start index 0. Usually only UBound() is used and the example above can be simplified to:

  Dim aResultArray ' should be declared as Variant
  aResultArray = oSequenceContainer.TheSequence
 
  Dim i%, iTo%
  iTo% = UBound( aResultArray() )
  For i% = 0 To iTo% ' this loop displays all array elements
      MsgBox aResultArray(i%)
  Next i%

The element count of a sequence/array can be calculated easily:

  u% = UBound( aResultArray() )
  ElementCount% = u% + 1

For empty arrays/sequences UBound returns -1. This way the semantic of UBound stays consistent as the element count is then calculated correctly as:

  ElementCount% = u% + 1' = -1 + 1 = 0
Documentation note.png The mapping between UNO sequences and Basic arrays depends on the fact that both use a zero-based index system. To avoid problems, the syntax
  Dim a ( IndexMin to IndexMin )

or the Basic command Option Base 1 should not be used. Both cause all Basic arrays to start with an index other than 0.

UNO also supports sequences of sequences. In Basic, this corresponds with arrays of arrays. Do not mix up sequences of sequences with multidimensional arrays. In multidimensional arrays, all sub arrays always have the same number of elements, whereas in sequences of sequences every element sequence can have a different size. Example:

  Dim aArrayOfArrays ' should be declared as Variant
  aArrayOfArrays = oExample.ShortSequences ' returns a sequence of sequences of short
 
  Dim i%, NumberOfSequences%
  Dim j%, NumberOfElements%
  Dim aElementArray
 
  NumberOfSequences% = UBound( aArrayOfArrays() ) + 1
  For i% = 0 to NumberOfSequences% - 1' loop over all sequences
      aElementArray = aArrayOfArrays( i% )
      NumberOfElements% = UBound( aElementArray() ) + 1
 
      For j% = 0 to NumberOfElements% - 1 ' loop over all elements
          MsgBox aElementArray( j% )
      Next j%
  Next i%

To create an array of arrays in Basic, sub arrays are used as elements of a master array:

  ' Declare master array
  Dim aArrayOfArrays( 2 )
 
  ' Declare sub arrays
  Dim aArray0( 3 )
  Dim aArray1( 2 )
  Dim aArray2( 0 )
 
  ' Initialise sub arrays
  aArray0( 0 ) = 0
  aArray0( 1 ) = 1
  aArray0( 2 ) = 2
  aArray0( 3 ) = 3
 
  aArray1( 0 ) = 42
  aArray1( 1 ) = 0
  aArray1( 2 ) = -42
 
  aArray2( 0 ) = 1
 
  ' Assign sub arrays to the master array
  aArrayOfArrays( 0 ) = aArray0()
  aArrayOfArrays( 1 ) = aArray1()
  aArrayOfArrays( 2 ) = aArray2()
 
  ' Assign the master array to the array property
  oExample.ShortSequences = aArrayOfArrays()

In this situation, the runtime function Array() is useful. The example code can then be written much shorter:

  ' Declare master array
  Dim aArrayOfArrays( 2 )
 
  ' Create and assign sub arrays
  aArrayOfArrays( 0 ) = Array( 0, 1, 2, 3 )
  aArrayOfArrays( 1 ) = Array( 42, 0, -42 )
  aArrayOfArrays( 2 ) = Array( 1 )
 
  ' Assign the master array to the array property
  oExample.ShortSequences = aArrayOfArrays()

If you nest Array(), more compact code can be written, but it becomes difficult to understand the resulting arrays:

  ' Declare master array variable as variant
  Dim aArrayOfArrays
 
  ' Create and assign master array and sub arrays
  aArrayOfArrays = Array( Array( 0, 1, 2, 3 ), Array( 42, 0, -42 ), Array( 1 ) )
 
  ' Assign the master array to the array property
  oExample.ShortSequences = aArrayOfArrays()

Sequences of higher order can be handled accordingly.

Content on this page is licensed under the Public Documentation License (PDL).
Personal tools
In other languages