Example of paged mode
In the first example, the records in the customer table are
                        loaded into the program array and the user uses the form to scroll through
                        the program array. In this example, the user is actually scrolling through
                        the result set created by a SCROLL CURSOR. This
                                    SCROLL CURSOR retrieves only the store number,
                        and another SQL SELECT statement is used to retrieve the
                        remainder of the row as needed.
Module
cust_lib2.4gl:
01 SCHEMA custdemo 
02
03 FUNCTION display_custarr()
04
05  DEFINE cust_arr DYNAMIC ARRAY OF RECORD
06         store_num     LIKE customer.store_num,
07         store_name    LIKE customer.store_name,
08         city          LIKE customer.city,
09         state         LIKE customer.state,
10         zip_code       LIKE customer.zip_code,
11         contact_name  LIKE customer.contact_name,
12         phone         LIKE customer.phone 
13     END RECORD,
14     ret_num      LIKE customer.store_num,
15     ret_name     LIKE customer.store_name,
16     ofs, len, i  SMALLINT,
17      sql_text     STRING,
18      rec_count    SMALLINT,
19      curr_pa      SMALLINT
20
21  OPEN WINDOW wcust WITH FORM "manycust"
22
23  LET rec_count = 0
24  SELECT COUNT(*) INTO rec_count FROM customer 
25  IF (rec_count == 0) THEN
26     RETURN 0, NULL
27  END IF   
28  
29  LET sql_text =  
30     "SELECT store_num, store_name, city,"
31     || " state, zip_code, contact_name,"
32     || " phone"
33     || " FROM customer WHERE store_num = ?"
34  PREPARE rec_all FROM sql_text 
35  
36  DECLARE num_curs SCROLL CURSOR FOR
37         SELECT store_num FROM customer    
38  OPEN num_curs 
39
40  DISPLAY ARRAY cust_arr TO sa_cust.*
41       ATTRIBUTES(UNBUFFERED, COUNT=rec_count)
42
43    ON FILL BUFFER
44      LET ofs = FGL_DIALOG_GETBUFFERSTART()
45      LET len = FGL_DIALOG_GETBUFFERLENGTH()
46      FOR i = 1 TO len 
47        WHENEVER ERROR CONTINUE
48       FETCH ABSOLUTE ofs + i - 1 num_curs 
49                    INTO cust_arr[i].store_num 
50         EXECUTE rec_all INTO cust_arr[i].* 
51                 USING cust_arr[i].store_num 
52        WHENEVER ERROR STOP
53        IF (SQLCA.SQLCODE = NOTFOUND) THEN
54          MESSAGE "Row deleted by another user."
55          CONTINUE FOR
56        ELSE
57          IF (SQLCA.SQLCODE < 0) THEN
58            ERROR SQLERRMESSAGE
59            CONTINUE FOR 
60          END IF
61        END IF
62      END FOR
62
64    AFTER DISPLAY
65      IF (INT_FLAG) THEN
66         LET ret_num = 0
67         LET ret_name = NULL
68      ELSE
69         LET curr_pa = ARR_CURR()- ofs + 1
70         LET ret_num = cust_arr[curr_pa].store_num 
71         LET ret_name = cust_arr[curr_pa].store_name 
72      END IF
73
74  END DISPLAY
75
76  CLOSE num_curs
77  FREE num_curs
78  FREE rec_all 
79
80  CLOSE WINDOW wcust 
81  RETURN ret_num, ret_name 
82
83 END FUNCTIONNote: 
- Lines 
16thru19define some new variables to be used, includingcont_dispto indicate whether the function should continue. - Line 
24uses an embedded SQL statement to store the total number of rows in thecustomertable in the variablerec_count. - Lines 
25thru27If the total number of rows is zero, function returns immediately0andNULL. - Lines 
29thru33contain the text of an SQLSELECTstatement to retrieve values from a single row in thecustomertable. The?placeholder will be replaced with thestore numberwhen the statement is executed. This text is assigned to a string variable,sql_text. - Line 
34uses the SQLPREPAREstatement to convert the string into an executable statement,rec_all. This statement will be executed when needed, to populate the rest of the values in the row of the program array. - Lines 
36thru37DECLAREaSCROLL CURSORnum_cursto retrieve only thestore numberfrom thecustomertable. - Line 
38opens theSCROLL CURSORnum_curs. - Lines 
40and41call theDISPLAY ARRAYstatement, providing theCOUNTto let the statement know the total number of rows in the SQL result set. - Lines 
43thru62contain the logic for theON FILL BUFFERclause of theDISPLAY ARRAYstatement. This control block will be executed automatically whenever a new page of data is required. - Line 
44uses the built-in function to get the offset for the page, the starting point for the retrieval of rows, and stores it in the variableofs. - Line 
45uses the built-in function to get the page length, and stores it in the variablelen. - Lines 
46thru62contain aFORloop to populate each row in the page with values from thecustomertable. The variableiis incremented to populate successive rows. The first value ofiis 1. - Lines 
48and49use theSCROLL CURSORnum_curswith the syntaxFETCH ABSOLUTE<row_number> to retrieve the store number from a specified row in the result set, and to store it in row i of the program array. Sinceiwas started at 1, the following calculation is used to determine the row number of the row to be retrieved:(Offset for the page) PLUS i MINUS 1Notice that rows 1 thru (page_length) of the program array are filled each time a new page is required.
 - Lines 
50and51execute the prepared statementrec_allto retrieve the rest of the values for row i in the program array, using thestore numberretrieved by theSCROLL CURSOR. Although this statement is within theFORloop, it was prepared earlier in the program, outside of the loop, to avoid unnecessary reprocessing each time the loop is executed. - Lines 
53thru61test whether fetching the entire row was successful. If not, a message is displayed to the user, and theCONTINUE FORinstruction continues theFORloop with the next iteration. - Lines 
64thru72use anAFTER DISPLAYstatement to get the row number of the row in the array that the user had selected. If the dialog was canceled,ret_numis set to 0 andret_nameis set to blanks. Otherwise the values ofret_numandret_nameare set based on the row number. The row number in theSCROLL CURSORresult set does not correlate directly to the program array number, because the program array was filled starting at row 1 each time. So the following calculation is used to return the correct row number of the program array:(Row number returned by ARR_CURR) MINUS (Offset for the page) PLUS 1 - Line 
74is the end of theDISPLAY ARRAYstatement. - Lines 
76and77CLOSEandFREEthe cursor. - Line 
78frees the prepared statement. - Line 
81closes the window. - Line 
82returns the values of the variablesret_numandret_nameto the calling function.