Arrays

From Team Developer SqlWindows Wiki
Jump to: navigation, search

Arrays


Contents


Pointer2.png Passing arrays in messages (any datatypes) Pointer.png

(From CenturaPro september 1999)


To pass arrays using messages, use this nice trick to convert the address of any type of array
to a number and send them along as wParam or lParam.


At the source (sending side) do this to pass arrays to a window

   ! Construct an array with weekdays
   Set saWeekDay[0] = "Monday"
   Set saWeekDay[1] = "Tuesday"
   Set saWeekDay[2] = "Wednesday"
   !
   ! Construct an array with customer objects
   Set uaCustomer[0].sivCustomerName = "Brendan Perry"
   Set uaCustomer[0].nivCustomerID = 1
   Set uaCustomer[1].sivCustomerName = "Lisa Gerrard"
   Set uaCustomer[1].nivCustomerID = 2
   !
   ! Get the address of the arrays as number
   Set nAddressStringArray = SalWindowHandleToNumber( saWeekDay )
   Set nAddressUDVArray = SalWindowHandleToNumber( uaCustomer )
   !
   ! Send along the addresses as wParam and lParam
   Call SalPostMsg( frmMain, SAM_User, nAddressStringArray, nAddressUDVArray )


Now at the receiving side (frmMain), convert the array address back to an array variable

   On SAM_User
      Call VisArrayCopy( SalNumberToWindowHandle( wParam ), saWeekDay, DT_String )
      Call VisArrayCopy( SalNumberToWindowHandle( lParam ), uaCustomer, DT_Handle )


Here you can download a sample:
Down.png WIKI_PassingArraysInMessages.zip


Pointer2.png Single function to get number of elements in any array Pointer.png

Having an array (any type) the following piece of code will determine how many elements are in the array:


   Local variables
      String: saMyArray[*]
   Actions
      ...
      If SalArrayIsEmpty( saMyArray )
         Set nArrayCount = 0
      Else
         Call SalArrayGetUpperBound( saMyArray, 1, nUpperBound )
         Set nArrayCount = nUpperBound + 1
      ...


This is a tedious task when you need to get the number elements spread over your sourcecode.
The code above does not even take into account the use of a different lower bound of the array (so not starting at zero index).
It would be simpler having a single function to do this, for any array you pass to it.


   Local variables
      String: saMyArray[*]
      Number: naMyArray[1:*]
      Customer: uaMyCustomerArray[*,5]
      Number: nArrayCount
   Actions
      ...
      Set nArrayCount = PALArrayGetCount( saMyArray )    ! string array count
      Set nArrayCount = PALArrayGetCount( naMyArray )    ! number array count
      Set nArrayCount = PALArrayGetCount( uaMyCustomerArray )    ! object array count
      ...


Problem is you can have arrays of any type: strings, numbers, datetimes,objects etc.


So creating a function in which you pass any array, you need to specify the correct datatype of the parameter.
That would mean multiple functions, each predefined for a specific datatype. And this is not very convenient.


But we can use a trick which works for all datatypes and works on all TD versions (tested up to TD 6.2).


It is secretly known that the TD compiler accepts passing an array to a function which accepts it as Window Handle datatype.
Also the Sal/Vis functions on arrays (like SalArrayGetUpperBound) accept Window Handle datatype to reflect the array.


Have a look at this:

Function: TestArray
    Local variables
        String: saTest[*]
    Actions
        Call ArrayFunction( saTest )

Function: ArrayFunction
    Parameters
        Window Handle: phWndArray[*]
    Local variables
        Number: nUpperBound
    Actions
        Call SalArrayGetUpperBound( phWndArray, 1, nUpperBound )
        ...


As can be seen, the ArrayFunction has a Window Handle array as parameter.
The TestArray function passes a string array to the ArrayFunction.
The compiler accepts this and also the passed array is treated as an array correctly.


BEWARE: maybe you have seen such a trick before, but it could be that the parameter is defined as Window Handle and not as a Window Handle array.
With TD 6.1 and up, the compiler does NOT accept a Window Handle parameter like "Window Handle: phWndArray", you must define it as a real array
like this: Window Handle: phWndArray[*]. Mind the brackets.

ANOTHER BEWARE: this trick does NOT work on .NET projects. The .NET compiler strictly forbids casting datatypes.


Using this "feature", a simple function can be created which is able to get the number of elements of ANY array.


The sample has these two globally defined functions:

    PALArrayGetCount( Array ) -> gets the number of elements in Array for the first dimension only
    PALArrayDimGetCount( Array, nDimension ) -> gets the number of elements in Array for any dimension (1..n)


Here you can download the sample using these two functions:
Down.png WIKI_PALArrayGetCount.zip