0
0
Tri rapide d'une grille (TStringGrid)
Bonjour,
pour trier une colonne, j'utilise une unité d'Olivier Dahan qui fonctionne bien (peut être pas aussi vite qu'avec QuickSort ?) et qui peut trier des valeurs alphabétiques, numériques, des dates ou des heures. Le voici
unit SortGrid;
{ © Olivier Dahan - odahan@cybercable.fr }
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, Grids, StdCtrls;
type
TodColType = (odct_Date,odct_time,odct_DateTime,odct_numeric,odct_CaseString,odct_NoCaseString);
Procedure ODSortGrid(grid:TStringGrid;ColToSort:Integer;TypeCol:TodColType;FromRow,ToRow:integer;Ascending:Boolean);
implementation
Procedure ODSortGrid(grid:TStringGrid;ColToSort:Integer;TypeCol:TodColType;FromRow,ToRow:integer;Ascending:Boolean);
var Ts:TStringList; i:integer; sg:tstringgrid;
Function ToDate(const s:string):string;
var y,m,d : word;
begin
DecodeDate(StrToDate(s),y,m,d);
result := FormatFloat('0000',y)+FormatFloat('00',m)+FormatFloat('00',d);
end;
Function ToTime(const s:string):string;
var h,m,sx,ms:word;
begin
DecodeTime(StrToTime(s),h,m,sx,ms);
result := FormatFloat('00',h)+FormatFloat('00',m)+FormatFloat('00',sx)+FormatFloat('00',ms);
end;
Function ToDateTime(const s:string):string;
var p:integer;
begin
p:=pos(' ',s);
if p>0 then
begin
Result := ToDate(copy(s,1,p-1))+ToTime(copy(s,p+1,length(s)));
end else result := '0000000000000000';
end;
Function ToNumeric(const s:string):string;
var p:integer; sx:string;
const z30 = '000000000000000000000000000000';
function pad(z:integer):string;
begin
if z in [1..30] then result := copy(z30,1,z) else result :='';
end;
begin
sx:='';
for p:=1 to length(s) do
if s in (['0'..'9','-',',','.']-) then sx:=sx+s;
p:=pos(DecimalSeparator,sx);
if p>0 then
result := pad(25-length(copy(sx,1,p-1)))+copy(sx,1,p-1)+'.'+copy(sx,p+1,length(sx))+pad(25-length(copy(sx,p+1,length(sx))))
else result := pad(25-length(sx))+sx;
end;
begin
ts:=tstringlist.Create;
try
For i:=FromRow to ToRow do
begin
Case TypeCol of
odct_Date : ts.AddObject(ToDate(grid.cells[ColToSort,i]),tobject(i));
odct_Time : ts.AddObject(ToTime(grid.cells[ColToSort,i]),tobject(i));
odct_DateTime : ts.AddObject(ToDateTime(grid.cells[ColToSort,i]),tobject(i));
odct_Numeric : ts.AddObject(ToNumeric(grid.cells[ColToSort,i]),tobject(i));
odct_CaseString : ts.AddObject(grid.cells[ColToSort,i],tobject(i));
odct_NoCaseString : ts.AddObject(AnsiUpperCase(grid.cells[ColToSort,i]),tobject(i));
end;
end;
ts.sorted := true;
sg := TStringGrid.Create(application);
try
sg.ColCount := grid.colcount;
sg.rowcount := ToRow-FromRow+1;
sg.FixedCols := 0;
sg.FixedRows := 0;
if Ascending then
For i:=0 to ts.count-1 do
sg.Rows := grid.Rows[integer(ts.objects)]
else
For i:=ts.count-1 downto 0 do
sg.Rows[(ts.count-1)-i] := grid.Rows[integer(ts.objects)];
For i:=FromRow to ToRow do
Grid.Rows := sg.Rows[i-FromRow];
finally
sg.free;
end;
finally
ts.free;
end;
end;
end.
Tu pourrais peut être faire un mix des 2, car ton exemple est plus complet ?
A+
Charly