Difference between revisions of "Documentation/DevGuide/ProUNO/Basic/Mapping of Sequences and Arrays"

From Apache OpenOffice Wiki
Jump to: navigation, search
m (1 revision(s))
m (Robot: Changing Category:Professional UNO)
Line 203: Line 203:
  
 
{{PDL1}}
 
{{PDL1}}
[[Category: Professional UNO]]
+
 
 +
[[Category:Documentation/Developers Guide/Professional UNO]]

Revision as of 15:02, 8 May 2008



Many UNO interfaces use sequences, as well as simple types. The OpenOffice.org 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 OpenOffice.org 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%() )


Template:Documentation/Note

It can be useful to use a OpenOffice.org 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


Template:Documentation/Note

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