Was this helpful?
Example--Passing an Array to a 3GL Procedure
Assume, for example, a frame that displays a line chart constructed dynamically from values in a database table. This frame calls a 4GL procedure named scale_y_array to calculate an array of Y-axis values. The scale_y_array procedure can be written in embedded SQL to enhance performance when calculating many graph points.
The following sections describe a 3GL version of the scale_y_array procedure.
How You Can Call the 3GL Procedure
When the frame calls the scale_y_array procedure, the frame passes an array (sales_array) whose data type is the saleschart_data user class. Two of the attributes in this class are significant to the 3GL procedure:
sales_value (float not null)
Contains the dollar sales for a given quarter of the fiscal year quarter (quarter)
y (integer not null)
Contains the Y-axis coordinate for each quarter to be displayed, after completion of the procedure
The frame also passes simple variables to the 3GL procedure. These variables are used to calculate the scale factor used to plot each point on the graph.
The line in the script that calls the scale_y_array procedure would be replaced by the following code if scale_y_array were an embedded SQL procedure:
/* Pass highest and lowest dollar amounts by
** reference to ensure portability when passing
** floating point parameters to C procedures. */
vmax = 1000.0;
vmin = 0.0;
callproc scale_y_array(byref(vmin), byref(vmax),
    ymax - (labelheight*2), 0, sales_array);
The frame passes several parameters:
vmax
Specifies the highest dollar amount to be displayed on the chart (represents the top of the chart)
vmin
Specifies the lowest dollar amount to be displayed on the chart (represents the bottom of the chart)
labelheight
Specifies the amount of space used by labels on the dynamically created chart; used to calculate the window position of the lowest Y point
sales_array
Specifies an array that contains the sales dollar amounts and contains the Y axis values
The vmax and vmin values are passed as variables, rather than directly as values, to ensure portability. For a discussion of passing floating point parameters to C procedures, see How You Can Pass Parameters to 3GL Procedures.
Scale_y_array Procedure
This procedure declares the following parameters:
Parameter
Description
Source in Calling Frame
array_handle
Handle for the 4GL array containing values of data to scale
sales_array object
low_value
Lowest value of data
vmin
high_value
Highest value of data
vmax
low_y_point
Lowest y point
0
high_y_point
Highest y point
ymax - (labelheight*2)
On an OpenROAD window, the point of origin is the upper left corner, which has the X,Y coordinates of 0,0. The X and Y coordinates increase as you move to the right and down the window. Consequently, the value for low_y_point is always greater than the value of high_y_point.
The 3GL procedure also declares the following local variables:
scale_factor
Used to calculate each Y-axis position
nrows
Specifies the number of rows in the array; used in the while loop and returned to the calling frame
i
Specifies the index for the while loop
row_handle
Specifies a handle for a row in the array
The following code is the declaration section of the 3GL procedure:
int     scale_y_array (low_value, high_value,
        low_y_point, high_y_point, array_handle)
double  *low_value, *high_value;
int     low_y_point, high_y_point;
exec sql begin declare section;
    int array_handle;
exec sql end declare section;
{
  exec sql begin declare section;
    double  scale_factor, value;
    int     nrows; /* number of rows in array */
    int     i;     /* index for while loop */
    int    row_handle;
exec sql end declare section;
}
Note: Variables used in exec 4GL or exec SQL statements must be:
Declared in the following statements:
exec SQL begin declare section
exec SQL end declare section
Preceded by a colon when used in a statement
To determine the scale factor, this procedure performs the following calculation:
/* Calculate scale factor one time only */
scale_factor = (low_y_point-high_y_point)
    /(*high_value-*low_value);
The procedure uses the inquire_4gl statement to determine the number of rows in the array. It then uses this number as the maximum iteration of a while loop, for example:
/* Find out how many rows in the array */
exec 4gl inquire_4gl (:nrows = lastrow(:array_handle));
The while loop gets a handle for each row in the array. This loop uses the handle to get the value in that row's sales_value attribute. The value obtained is subtracted from the highest dollar value and multiplied by the scale value to determine the Y value for that row. Finally, the loop sets the value of the y attribute in the appropriate row of sales_array.
The following code shows how the while loop processes each row in the array to determine and set its Y value:
/* Loop through sales values in the array and
** put scaled values into y. */

i = 0;
while (i++ < nrows)
{
  exec 4gl getrow :array_handle :i
    (:row_handle = ROW);
  exec 4gl get attribute :row_handle
    (:value = sales_value);
  value = scale_factor * (*high_value - value);
  exec 4gl set attribute :row_handle (y = :value);
}
The following statement, the last in the 3GL procedure, returns control to the calling frame:
return;
Last modified date: 12/20/2023