Ask Reuben
Refreshing Tables
How can I refresh a Table without leaving the current dialog?
In legacy 4gl code, to refresh a Table you might have had some DISPLAY statements in a FOR loop. In the last Ask-Reuben I demonstrated how you could use DISPLAY ARRAY with BEFORE DISPLAY EXIT DISPLAY to redisplay the Table. There was another scenario where legacy 4gl code was clunky in that to refresh a Table, this involved exiting the current dialog, repopulate the array, and then starting the dialog again.
What the developer was unaware of was that by using Multiple Dialog and UNBUFFERED, that Table could be updated from the current dialog.
By using UNBUFFERED, then changes to a program variable are reflected right away in the current dialog. So if using Multiple Dialog and UNBUFFERED, changes to a Table can be made by simply updating the underling array variable based on values in the other parts of the dialog. This includes using array methods that change multiple rows of an array such as clear, copyTo, sort.
Best illustrated by example, the code example below consists of a DIALOG statement that has the UNBUFFERED attribute and has two DISPLAY ARRAY blocks. When the selected row on the left hand side array changes, the array on the right hand side is cleared and re-populated. Note in the two screenshots, in the left hand side I have moved down one row, the values in the right hand side have changed to reflect the left hand side value. At no point do I exit the dialog, I simply change the values of the right hand side array (including using the clear method to remove all rows before adding new rows). The use of the UNBUFFERED attribute means that the rendering of the right hand side array changes immediately.
IMPORT util
DEFINE arrm DYNAMIC ARRAY OF RECORD
master_id INTEGER,
detail_count INTEGER
END RECORD
DEFINE arrd DYNAMIC ARRAY OF RECORD
detail_id STRING
END RECORD
MAIN
DEFINE i INTEGER
CLOSE WINDOW SCREEN
OPEN WINDOW w WITH FORM "askreuben194"
-- Populate master
FOR i = 1 TO 99
LET arrm[i].master_id = i
LET arrm[i].detail_count = util.Math.rand(40) + 5
END FOR
DIALOG ATTRIBUTES(UNBUFFERED)
DISPLAY ARRAY arrm TO scrm.*
BEFORE ROW
-- Update right hand side with detail for current row
-- No need to exit dialog as UNBUFFERED will cause display to be updated
CALL refresh_detail(DIALOG.getCurrentRow("scrm"))
END DISPLAY
DISPLAY ARRAY arrd TO scrd.*
END DISPLAY
ON ACTION close
EXIT DIALOG
END DIALOG
END MAIN
FUNCTION refresh_detail(row INTEGER)
DEFINE i INTEGER
CALL arrd.clear()
FOR i = 1 TO arrm[row].detail_count
LET arrd[i].detail_id = SFMT("%1-%2", row USING "<&", i USING "&&")
END FOR
END FUNCTION
#! askreuben194.per
LAYOUT
HBOX
TABLE
{
[f01 ]
}
END
TABLE
{
[g01 ]
}
END
END
END
ATTRIBUTES
EDIT f01 = formonly.master_id, TITLE="Master";
PHANTOM formonly.detail_count;
EDIT g01 = formonly.detail_id, TITLE="Detail";
INSTRUCTIONS
SCREEN RECORD scrm(master_id, detail_count)
SCREEN RECORD scrd(detail_id)