Re: 4GL Display Array Question
Posted in 1994
dauns@andrews.edu (Frank Dauns) writes: >In r4gl 4.11 is there any way to "automatically" scroll to a specific >row before turning control over to the user when using a display array >statement? >I have seen the scroll statment which can be used in the before input clase >of an input array statement but I don't see the ability to simulate a >"before display" for the display array statement. >Have I overlooked something obvious or is this just not possible ? Like I just said ... (but will post here too, in case you missed it). DISPLAY ARRAY is fairly limited, but you can use INPUT ARRAY to control specific row addressing: Emulating "NEXT ROW" syntax in INPUT ARRAY 1) Create a screen record in which the last field in a NOENTRY field. This field can be one that actually stores data for display or a CHAR(1) designed just for this purpose. Remember that the last field in the screen record doesn't have to be the right-most field on the screen, but it usually is SCREEN { [a ][b ][c ][n] ... } ATTRIBUTES a = ... b = ... c = ... n = FORMONLY.ne TYPE CHAR, NOENTRY; INSTRUCTIONS ... SCREEN RECORD s_array[##] (...,FORMONLY.ne) END 2) Define your array with the last field that matches the NOENTRY in the screen record: DEFINE ma_array ARRAY[##] OF RECORD ... ne CHAR(1) END RECORD ... 3) In your INPUT ARRAY function, you need counters for arr_curr, scr_line, arr_count, and one to mark if we want to jump rows: DEFINE arr SMALLINT DEFINE scr SMALLINT DEFINE act SMALLINT DEFINE arrg SMALLINT 4) We surround the entire INPUT ARRAY with a WHILE loop, because the trick to moving backward is to mark the row to go to, then exit the input and loop back around to begin input again. LET arrg = 1 LET act = number of rows filled in the array already WHILE arrg > 0 CALL set_count(act) INPUT ARRAY ma_array WITHOUT DEFAULTS FROM s_array.* BEFORE ROW LET arr = arr_curr() LET scr = scr_line() IF arrg > arr THEN # this means we want to go to a row below us in the # array, so NEXT FIELD the NOENTRY field, which means # jump to the next row NEXT FIELD ne END IF # reset arrg to 0 if we get to this point, which allows # us to leave the WHILE loop around the INPUT ARRAY if # the user hits the ACCEPT or INTERRUPT key LET arrg = 0 ... AFTER ROW # I have found that AFTER ROW is the best place to track # the last filled in row. LET act = arr_count() ... # below is an example of how we can implement a function key # to act as a HOME key. When the user types the function key # designated as HOME, the cursor will move to array row 1 ON KEY (F##) LET arrg = 1 EXIT INPUT ... # below is an example of how we can implement a function key # to act as an END key. When the user types the function key # designated as END, the cursor will move to the last filled # in row. ON KEY (F##) IF arr < act THEN # if we're not on the last row now, go there LET arrg = act NEXT FIELD ne END IF ... END INPUT # in case we're looping we need to track arr_count here # because an EXIT INPUT call avoids the AFTER ROW block LET act = arr_count() END WHILE IF int_flag THEN ... The only drawback to this approach is that for very large arrays the looping can take some time. But for arrays that are 50 rows or less, this is suitable. BUG #11364 WORK AROUND The only problem, now, is that with version 4.10 there is a bug that causes exiting from an AUTONEXT field into the NOENTRY field (and thus to the next row) to put the cursor into an infinite loop. This bug (#11364) is scheduled for a fix in version 4.10.UE1, which is currently shipping on some platforms. If you can't get the fixed version, there are two approaches to fixing the problem. The first approach is to remove the AUTONEXT from the field just before the NOENTRY field. This is the simplest, and thus recommended, approach. If your user can't live with hitting the RETURN key after this field, though, you can use some of the new 4.10 library functions as a work around: ... AFTER FIELD before_ne IF fgl_lastkey() = fgl_keyval("autonext") THEN IF arr < maximum array size THEN # go to the next row, avoiding bug 11364 LET arrg = arr + 1 ELSE # we're on the last row already, loop back to the top LET arrg = 1 END IF EXIT INPUT END IF ... "before_ne" in the example above is the name of the AUTONEXT field that is listed just before the NOENTRY field in the screen record, and "maximum array size" is the size of array ma_array. This work around has the same problem as the jumping solution in that for very large arrays a lot of screen repainting is done to get back down to the desired row. ============================================================ Dennis J. Pimple Informix Software Inc Senior Consultant Denver Colorado USA dennisp@informix.com Voice:303-850-0210 Fax:303-779-4025