Was this helpful?
Call4GL Parameter Array
ByValParams and ByRefParams point to the actual data values corresponding to their respective descriptors. The ByVal and ByRef data arrays are both structured the same way. They are only separated so that COM can marshal them differently. Like the descriptors, the data values are communicated as nested array structures.
At the top level, a Params is simply a single VARIANT. This VARIANT contains a two-dimensional array of VARIANTs with one row and a column corresponding to each parameter you want to map to in the 4GL procedure. These columns correspond one-for-one with the columns in the ParamDesc.
If the 4GL parameter is a scalar, its corresponding data VARIANT simply contains the scalar value to be passed (or, after the call, the ByRef value that was returned).
If the 4GL parameter is a user class, its corresponding data VARIANT contains a nested array of data to be mapped to that user class. For singleton user class parameters, the data array contains only one row. For "array of user" class parameters, the data array contains a row corresponding to each row of the user class array.
A second dimension is not necessary at the top level, or for a singleton user class instance, because there will always be only one row in those cases. But sticking with two dimensions, even when there is only one row, allows all the descriptors and all the data arrays (at every level of nesting) to be of a consistent tabular structure regardless of whether they are scalars, user classes, or arrays of user classes.
Continuing the example used for the ParamDesc, pass 99 as the integer value for the MyScalar parameter and six rows of sample data for the MyInArray parameter. Leave the data for MyOutArray empty, because only the ByRef result from that one is of interest.
Before the call, the ByRefParams would contain a structure that looks like this:
After the call, the scalar will have been updated in place, and the empty value for MyOutArray will have been replaced with the ByRef row returned:
Here is how these structures might be set up using VBScript:
Dim ByRefParams(0,2)
 Dim InArray(5,1)
 InArray(0,0) = “DATAVALUE_ONE”
 InArray(0,1) = “DATAVALUE_TWO”
 InArray(1,0) = “Any number of”
 InArray(1,1) = “input data rows”
 ...                 ...
ByRefParams(0,0) = 99
ByRefParams(0,1) = InArray
ByRefParams(0,2) = Empty
(Optional ByValParamDesc, ByValParams omitted)
orRSO.Call4GL “helloworld”, , , ByRefParamDesc, ByRefParams
After the call:
ByRefParams(0,0) will contain 100
ByRefParams(0,1) will be unchanged
ByRefParams(0,2)(0,0) will contain “DATAVALUE_TWO”
ByRefParams(0,2)(0,1) will contain “DATAVALUE_ONE”
To process a variable number of output rows, the LBound and UBound functions can be used, as shown in this sample fragment of an ASP script:
rows = (UBound(ByRefParams(0,2), 1) - LBound(ByRefParams(0,2), 1)) + 1
For i = 1 To rows
%>
<TR>
    <TD> <%= ByRefParams(0,2)(i - 1, 0) %> </TD>
    <TD> <%= ByRefParams(0,2)(i - 1, 1) %> </TD>
</TR>
<%
Next
Note:  This method works even for arrays with zero rows. (UBound will be
-1.) An empty OpenROAD user class array will be returned as a data array with zero rows.
Last modified date: 12/20/2023