(maybe other users will write their opinion) Now empty cells are always placed at the end of the list (both with Asc and Desc sorting).You can use the OnCompareCells event of the Worksheet to define custom sorting criteria. At first handle the special cases (e.g. move empty cells to the top), then call the default sorting procedure which is accessible now as DefaultCompareCells.
Maybe in one case (for example, Asc) to place them at the top of the list, and in the other (for example, Desc sorting) at the end of the list ?
You can use the OnCompareCells event of the Worksheet to define custom sorting criteria. At first handle the special cases (e.g. move empty cells to the top), then call the default sorting procedure which is accessible now as DefaultCompareCells.I cannot find OnCompareCells in the description on http://wiki.freepascal.org/FPSpreadsheet and visually in the object inspector.
another example of "freezing" and strange sorting. Check, please:
1) form with
Button1: TButton;
Button2: TButton;
sWorksheetGrid1: TsWorksheetGrid;
2) FormCreate:
sWorksheetGrid1.Worksheet.WriteText(0,1,'B1');
sWorksheetGrid1.Worksheet.WriteText(1,1,'B2');
sWorksheetGrid1.Worksheet.WriteText(2,1,'');
sWorksheetGrid1.Worksheet.WriteText(3,1,'B4');
sWorksheetGrid1.Worksheet.WriteText(0,0,'A1');
sWorksheetGrid1.Worksheet.WriteText(1,0,'A2');
sWorksheetGrid1.Worksheet.WriteText(2,0,'');
sWorksheetGrid1.Worksheet.WriteText(3,0,'A4');
3) Button1Click:
var
sp: TsSortParams;
begin
sp := InitSortParams(true,1);
sp.Keys[0].ColRowIndex := 0;
sWorksheetGrid1.Worksheet.Sort(sp,'A1:A4');
4) Button2Click:
var
sp: TsSortParams;
begin
sp := InitSortParams(true,1);
sp.Keys[0].ColRowIndex := 0;
sWorksheetGrid1.Worksheet.Sort(sp,'B1:B4');
The first click on button1 - the column "A" is sorted as: A1, A2, A4, (empty)
And more sorting does not work (another button click).
If click on button 2 - each press changes the sorting from B1, B2, B4, (empty) to B1, B2, (empty), B4 - but initialization with the same parameters.
I cannot find OnCompareCells in the description on http://wiki.freepascal.org/FPSpreadsheet and visually in the object inspector.The OnCompareCells is a way to provide custom sorting criteria for the worksheet. It is not compatible with grid events. Since the grid merely displays the contents of the worksheet it was implemented this way.
Can this event be added to the object inspector with cell1, cell2 and sort params or are these Worksheet event and cannot be added to the object inspector for TsWorksheetGrid ?
I found:Since the compare procedure is active only during the Sort procedure you should immediately see which sorting criteria are used.
{@@ This event can be used to override the built-in comparing function which
is called when cells are sorted. }
TsCellCompareEvent = procedure (Sender: TObject; ACell1, ACell2: PCell; var AResult: Integer) of object;
how I can check which sorting parameters (to return the result of the comparison depending on the parameters) are applied to the current compared cells - what index is currently used inside the keys array, for the current call of custom comparison procedure ?
I think you misunderstand the meaning of the parameters. The Keys[0].ColRowIndex identifies the column (in your case, but it can also be a row) which provides the cells used as sorting criteria. The cell range given as second parameter of the Sort method identifies the cells which will be reordered according to the sorting criteria.
TsCellCompareEvent = procedure (Sender: TObject; ACell1, ACell2: PCell; var AResult: Integer) of object;Since the compare procedure is active only during the Sort procedure you should immediately see which sorting criteria are used.
I think that the sorting support by fpspreadsheet should be rewritten in a more practical way. Since you seem to be more involved in sorting than myself, I ask you for your opinion on the following proposal:(rewrote the message to make it shorter)
I would like to provide the full TsSortKey parameter in the OnCompareCells event (and in DefaultCompareCells, as well) instead of the TsSortOptions alone. The TsSortPriority parameter should be moved to the TsSortKey record.
Would this modification meet your requirements?
I fear, however, that it will break existing code...
Wouldn't it be better to have the complete TsSortKey as an argument in the OnCompareCells event instead of the SortOptions alone? This way it could be determined which column is currently sorted which may be useful when the individual columns have different sorting criteria. At least this is what I understood as iteh's request.Yes, I would like to see the full set of parameters inside OnCompareCells, but I would also like to see a global variable (outside OnCompareCells) where I could see which index (not the column index, but the current index then iterates through SortParams.Keys array) is now processed to display the progressbar if we sort many columns and big table.
And shouldn't the SortPriority be part of the TsSortKey record? Again for the same reason: maybe one columns wants the numbers at the top, the other one at the end.
Wouldn't it be better to have the complete TsSortKey as an argument in the OnCompareCells event instead of the SortOptions alone? This way it could be determined which column is currently sorted which may be useful when the individual columns have different sorting criteria. At least this is what I understood as iteh's request.
And shouldn't the SortPriority be part of the TsSortKey record? Again for the same reason: maybe one columns wants the numbers at the top, the other one at the end.
If you need the index of the column currently compared you get it as the ColRowIndex of the TsSortKey parameter passed to the OnFullCompareCells now.I initially made a mistake, did not look at the sources, and thought that sorting is going over the Key (from 0 to High(FSortParams.Keys)) and wanted to get it to determine what the Key is now (to understand what part of the sorting was already done and draw a progressbar).