Of course sorting rows (visually) during an INPUT ARRAY makes only sense if the program array rows are independent from each other. If the order of the rows in the program array matters, sort should be disabled, and this can be done with the UNSORTABLECOLUMNS attribute of the TABLE container.
I see that all the questions about BEFORE/AFTER events evaporate with the current view-only sorting. Very simple! However, the pressure from our demo team (led by our master of customer-appeal) is to bring on universal column sorting. Switching it off in programs that could really benefit from a physical sort sounds like it would be unpopular and/or unacceptable. I'll have to meditate on people's expectations and have a chat with a few people to get a rough count of affected programs. The danger for me is, once word gets out that array-sorting is Very Close, the pressure will be enormous!
Note there are other requests related to sort, such as:
- defining the default sort (#1499),
- being notified after sort (#16776).
- get the visual index of current row to display "current/total" info (#14740),
- multiple-column sort (#11736),
- program array sorting (#3491),
- take the control on sort events to write your own sort (using SQL for ex) (#7837),
- querying the sort info to order the rows in reports or fill the array with SQL (part of #7837)
Thanks, I'll have a look at them for ideas. I have noticed that if I put a sequentially numbered noentry column (but it can't be a phantom) then the ordering of the rows is reflected partially in the //Table/TableColumn/ValueList for that column. But as you know, the 'partial' is because the value list only reflects what is visible to the user. Having the sort order for 10 out of 100 rows is not going to allow me to reorder them.
Instead of sorting by writing a temp table and reloading it (is that the idea in 7837?) it should be possible to grab the array with base.typeInfo() and then sort it using a generic routine. The only custom-code needed per array would then be something to extract the data back out of the sorted dom-tree and put it into the array again.
For me to make it automagical, would require hooking into every ON ACTION and AFTER event, rush off and do a physical sort, and then reset the sortColumn attribute. Would assigning a value to sortColumn and sortOrder cause immediate re-ordering of the visual data? Otherwise this idea would need a method call demanding that physical order is reinstated. This would probably have to be used like this:
ON ACTION all_of_them
call check_the_sorting()
......
function check_the_sorting()
if reliably-detect-sorting then
save sortColumn and sortOrder
set sortColumn and sortOrder to null # back to natural order to match the physical about to be assigned
ui.interface.refresh
physically sort the rows according to the nominated column # unbuffered will immediately display them
set sortColumn and sortOrder back to the saved values # even if it resorts, will match the new physical order
ui.interface.refresh
or something like that. There's a fair number of what-ifs in there. I haven't even begun to look at the BEFORE/AFTER events. Honestly, I'm not sure this code could really fly. The best might be to offer a button to physically sort the data; I'm not sure that would be popular either.
Ahh well, more ideas welcome. I expect we're not the only people in the world who would have similar needs.
why we have the todays input or display array sort behavior? Sorting is a feature of the view. When sorting we never touch the model (the 4gl array). This has at least two good reasons:
- an array may be used in more than one display or input array statement. Each dialog may sort in a different way.
At the same time? Interesting; I wonder if I can think of any use for this...
- a display array statement must not modify the the array - it's a display.
True. DISPLAY ARRAY should not mess with the actual data. However maybe it needs to be an option? Otherwise, printing in the order the user has just sorted would not be possible. In such a situation, the programmer would have to know that the array must be thrown away or the unnatural data-change would leak out.
Yes, in some special cases it could be useful to sort the model. A new attribute like SORT ARRAY could easily solve your problem.
Example:
INPUT myArray.* FROM myTable.* ATTRIBUTE(UNBUFFERED, SORT ARRAY)
...
The result would be: the array myArray is (physically) sorted as the view.
Yes, this could work, however it leaves
you with the interesting challenge of deciding what to do about BEFORE/AFTER events. I still haven't decided which of my two original suggestions is the proper one. Perhaps leaving the user on the same logical row (ie moving them physically) is the only appropriate action, however technically, the current row HAS changed because it's sequence number is different. This may affect some programs that track and assign the sequence number. I haven't yet derived a "proof" that one approach or the other is flawed or preferred.
If the 2nd approach is used (fire the AFTER events, sort, fire the BEFORE events) then as far as the programmer and the runtime is concerned, the sort will take place when there is no "current" row, and it would be just like that moment when the user is between rows - ie between the last AFTER ROW and before the next BEFORE ROW. This sounds like a very safe state to be in when performing the sort.
All in all, a very interesting subject!