[DUG] Stringgrids
John Bird
johnkbird at paradise.net.nz
Fri Feb 2 12:44:11 NZDT 2007
Here is the stringgrid sort routine - I use the stock standard VCL
stringgrid in many places and sort it using this.
I usually add a row of buttons above the grid which the user can click to
sort the column it is above, and no fixed rows, so it looks similar to the
Windows Explorer sort options.
The onclick event for each button just calls the relevant sort:
eg
procedure Tform1.SortGridbyName;
begin
xcSortGrid(strgrdSearch,3,4,'A',true);
strgrdSearch.setfocus;
end;
The sorting is a Tstringlist sort, that is alpha, but there is facility in
the routine to specify other column types eg Integer or Date.
(Internally the routine formats these into a string so the alpha sort works
- se the jkblSortGridKeyType1 etc)
procedure xcSortGrid(var
PGrid:TStringGrid;SortColumn1:Integer;SortColumn2:integer;AscDesc:char;CaseI
nSensitive:Boolean);
//NOTE there are extra sort types possible, defined in
jkblSortGridKeyType1&2
var
TmpSortList:TStringList;
olddefrow,newdefrow:integer; //keep same data row as default
oldrow,datalhs,ptr,colptr,rowptr:integer;
keydata1,keydata2,tempstr:string;
firstrow:integer; //first row after fixed rows
lAscDesc:char;
tempcells:array of array of string;
begin
if PGrid.rowcount < 2 then exit; //nothing to sort
TmpSortList:=TStringList.Create;
TmpSortList.sorted:=false;
olddefrow:=-1;
NewDefRow:=-1;
if PGrid.row>0 then oldDefRow:=PGrid.row;
firstrow:=0;
if PGrid.FixedRows >0 then
firstrow:=PGrid.FixedRows; //1 fixed row-> 1=1st data row
for ptr:=firstrow to PGrid.rowcount-1 do
begin
//put sort col plus orig pointer into stringlist
keydata1:=PGrid.cells[SortColumn1,ptr];
keydata2:=PGrid.cells[SortColumn2,ptr];
//this can be extended to specify decimal columns/Date - ideally need
more data checking though
//if jkblSortGridKeyType1='I' then
keydata1:=format('%12d',[strtoint(keydata1)]);
//if jkblSortGridKeyType2='I' then
keydata2:=format('%12d',[strtoint(keydata2)]);
tempstr:=keydata1+keydata2;
if CaseInsensitive=true then uppercase(tempstr);
xcstrpad(tempstr,60); //see below
tempstr:=tempstr+inttostr(ptr);
TmpSortList.Add(tempstr);
end;
//sort it
TmpSortList.sorted:=true;
//now copy original cells to tempcells dynamic array
//this is to keep original data as grid is now being overwritten
setlength(tempcells,PGrid.colcount,PGrid.rowcount);
for rowptr:=firstrow to PGrid.rowcount-1 do
begin
for colptr:=0 to PGrid.colcount-1 do
begin
tempcells[colptr,rowptr]:=PGrid.cells[colptr,rowptr];
end;
end;
//now write tempcells back to grid - note grid may have more than sorted
list if
//fixed rows, so 2 counters, ptr (list) and rowptr(grid)
lAscDesc:=upcase(AscDesc);
if lAscDesc='A' then
begin
for ptr:=0 to TmpSortList.Count-1 do
begin
tempstr:=copy(TmpSortList[ptr],61,10);
oldrow:=strtoint(tempstr);
if oldrow=oldDefRow then NewDefRow:=ptr;
//oldptr is orig row number, ptr is new row number
rowptr:=ptr+firstrow;
for colptr:=0 to PGrid.colcount-1 do
begin
PGrid.cells[colptr,rowptr]:=tempcells[colptr,oldrow];
end;
end;
end
else
begin
for ptr:=TmpSortList.count-1 downto 0 do
begin
tempstr:=copy(TmpSortList[ptr],61,10);
oldrow:=strtoint(tempstr);
if oldrow=oldDefRow then NewDefRow:=ptr;
//oldptr is orig row number, ptr is new row number
rowptr:=ptr+firstrow;
for colptr:=0 to PGrid.colcount-1 do
begin
PGrid.cells[colptr,rowptr]:=tempcells[colptr,oldrow];
end;
end;
end;
TmpSortList.free;
tempcells:=nil;
if (OldDefRow>0) and (NewDefRow > FirstRow) then PGrid.row:=NewDefRow;
//in case row not set, makes sure is valid...otherwise grid can sort of
scroll
//or duplicate fixed row...
if (PGrid.Row<firstrow) or (PGrid.Row > PGrid.RowCount-1) then
PGrid.Row:=firstrow+1;
jkblSortGridKeyType1:='';
jkblSortGridKeyType2:='';
end;
procedure xcstrpad(var strec:string;stlen:integer);
var
Rsize,I:integer;
begin
Rsize:=length(strec);
if Rsize < Stlen then
for i:=Rsize+1 to Stlen do Strec:=Strec+' ';
end;
Note:
These are global variables, if wanted (remove them if not needed) to further
extend the sort column types.
I added these later to extend the possible sort types.
jkblSortGridKeyType1,jkblSortGridKeyType2:string; //for more sort types
John
Web www.jbcl.co.nz <http://www.jbcl.co.nz/>
-----Original Message-----
From: delphi-bounces at ns3.123.co.nz [mailto:delphi-bounces at ns3.123.co.nz] On
Behalf Of Eion McIntosh (Christchurch)
Sent: Friday, 2 February 2007 9:07 a.m.
To: NZ Borland Developers Group - Delphi List
Subject: [DUG] Stringgrids
Hi
I havd a look, but can't see anything, but can you take 2 rows within a
TStringGrid and swap them? I have some details in a stringgrid but would
like to sort it on one of the rows after it has been filled. I can't fill it
in order to start with because the source data is coming from two different
sources.
Regards
Eion McIntosh
PPCS Ltd
__________ NOD32 1.1461 (20060329) Information __________
This message was checked by NOD32 antivirus system.
http://www.eset.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://ns3.123.co.nz/pipermail/delphi/attachments/20070202/4f5451fc/attachment.html
More information about the Delphi
mailing list