Solved

# TStringGrid.sorted

Posted on 2001-07-24
183 Views
It's all in the StringGrid so now I need to sort it by column 0.
The problem is it's pretending it doesn't know anything about TStringGrid.sorted := true;

0
Question by:frog
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points

LVL 27

Expert Comment

ID: 6312257
Procedure SortGrid(AGrid : TStringGrid; ColIndex : Integer; SortOrder : Boolean);
//SortOrder=true->Ascending,SortOrder=False->Descending
//works only, if there is no comma in a cell
//first row is excluded from the sort
var
SL : TStringList;
I  : Integer;
begin
if (assigned(AGrid)) and
(ColIndex > -1) and
(ColIndex < AGrid.ColCount) then
begin
SL := TStringList.Create;
try
SL.Sorted := true;
For I := 0 to AGrid.RowCount - 1 do
Case SortOrder of
True : For I := 0 to SL.Count - 1 do
AGrid.Rows[I].CommaText := Copy(SL[I],pos('|',SL[I])+1,MaxLongInt);
False : For I := SL.Count - 1 downto 0 do
AGrid.Rows[SL.Count  - I].CommaText := Copy(SL[I],pos('|',SL[I])+1,MaxLongInt);
end;
finally
sl.free;
end;
end;
end;

//Sort third col, asc
procedure TForm1.Button1Click(Sender: TObject);
begin
SortGrid(StringGrid1,2,True);
end;

//Sort secon col desc
procedure TForm1.Button2Click(Sender: TObject);
begin
SortGrid(StringGrid1,1,False);
end;

meikl

0

LVL 27

Expert Comment

ID: 6312350
another sample, without the comma-restriction is also available, if needed
0

LVL 3

Expert Comment

ID: 6314321
Can you post it here?!?!

Thanks!
VSF
0

LVL 27

Expert Comment

ID: 6314579
well, here it is, including also a sample of a customsortroutine

unit stringgridsort_u;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Grids;

type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
Button1: TButton;
CheckBox1: TCheckBox;
procedure StringGrid1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Button1Click(Sender: TObject);
procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
private
FSortedColIndex : Integer;
FSortOrder      : Boolean;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{\$R *.DFM}

Var AsIntegerFlag : Boolean;

Function SpecialSort(List: TStringList; Index1, Index2: Integer): Integer;
begin
Result := 0;
try
case AsIntegerFlag of
//AnsiSort
False : If List[Index1] < List[Index2] then Result := -1
else If List[Index1] > List[Index2] then Result := 1;
//IntegerSort
True  : If StrToInt(List[Index1]) < StrToInt(List[Index2]) then Result := -1
else If StrToInt(List[Index1]) > StrToInt(List[Index2]) then Result := 1;
end;
except
Result := 0;  //No Sort on Error;
end;
end;

Procedure SortGrid(AGrid : TStringGrid; ColIndex : Integer; SortOrder : Boolean;
//Optional Parameters
UseCustomSort : Boolean = False;
CustomSortProc : TStringListSortCompare = Nil);
//SortOrder=true->Ascending,SortOrder=False->Descending
//first row is excluded from the sort
var
SL : TStringList;
ARow : TStringList;
I  : Integer;
begin
if (assigned(AGrid)) and
(ColIndex > -1) and
(ColIndex < AGrid.ColCount) then
begin
SL := TStringList.Create;
try
For I := 1 to AGrid.RowCount - 1 do
begin
ARow := TStringList.Create;
ARow.Assign(AGrid.Rows[i]);
end;
if useCustomSort and assigned(CustomSortProc) then
try
SL.CustomSort(CustomSortProc);  //Userdefined sort
except
raise;
end
else
SL.Sorted := true; //AnsiCompareString
Case SortOrder of
True : For I := 0 to SL.Count - 1 do
if Assigned(SL.Objects[I]) then
AGrid.Rows[I+1].Assign(TStringList(SL.Objects[I]));
False : For I := SL.Count - 1  downto 0 do
if Assigned(SL.Objects[I]) then
AGrid.Rows[AGrid.RowCount - I - 1].Assign(TStringList(SL.Objects[I]));
end;
finally
for I := 0 to sl.count-1 do
if Assigned(SL.Objects[I]) then
begin
TStringList(SL.Objects[I]).Free;
SL.Objects[I] := Nil;
end;
sl.free;
end;
end;
end;

Function RandomString(Lngth : Integer; CharSet : TSysCharset) : String;
var C : Char;
begin
Result := '';
if (lngth > 0) and not (CharSet = []) then
while length(Result) < lngth do
begin
Repeat
C := Chr(Random(255));
Until C in CharSet;
Result := Result + C;
end;
end;

procedure TForm1.StringGrid1MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
ACol,ARow : Integer;
ASortProc : TStringListSortCompare;
begin
ASortProc := SpecialSort;
StringGrid1.MouseToCell(x,y,ACol,ARow);
AsIntegerFlag := ACol in [1,2];
if (ARow = 0) and
(ACol > 0) and
(Acol < StringGrid1.RowCount) then
if Button =  mbleft then
begin
FSortedColIndex := ACol;
FSortOrder := True;
SortGrid(StringGrid1,ACol,True,Checkbox1.Checked,ASortProc)  //asc on columntitle-leftclick
end
else
begin
FSortedColIndex := ACol;
FSortOrder := False;
SortGrid(StringGrid1,ACol,False,Checkbox1.Checked,ASortProc);//Desc on columntitle-rightclick
end;
end;

//Create a unsorted content
procedure TForm1.Button1Click(Sender: TObject);
var I : Integer;
begin
StringGrid1.RowCount := 10001;
StringGrid1.ColCount := 7;
for i := 1 to 6 do
StringGrid1.Cells[I,0] := Randomstring(5,['0'..'9','A'..'Z','a'..'z']);
for i := 1 to 10000 do
begin
StringGrid1.Cells[1,I] := IntToStr(I);
StringGrid1.Cells[2,I] := IntToStr(10001-I);
StringGrid1.Cells[3,I] := Randomstring(10,['A'..'Z']);
StringGrid1.Cells[4,I] := Randomstring(10,['0'..'9','A'..'Z','a'..'z']);
StringGrid1.Cells[5,I] := Randomstring(10,[#0..#255]);
StringGrid1.Cells[6,I] := '1000';
end;
end;

//Draw a triangle
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
const CMargin = 5;
begin
If (ARow = 0) and (ACol = FSortedColIndex) then  //FSortedColIndex->the col, which is sorted
case FSortOrder of
true : begin  //Ascending
StringGrid1.Canvas.MoveTo(Rect.Right-CMargin,Rect.Top+CMargin);
StringGrid1.Canvas.LineTo(Rect.Right-7-CMargin,Rect.Top+CMargin);
StringGrid1.Canvas.LineTo(Rect.Right-4-CMargin,Rect.Top+7+CMargin);
StringGrid1.Canvas.Pen.Color := clBtnHighLight;
StringGrid1.Canvas.LineTo(Rect.Right-CMargin,Rect.Top+CMargin);
end;
false : begin  //Descending
StringGrid1.Canvas.Pen.Color := clBtnHighLight;
StringGrid1.Canvas.MoveTo(Rect.Right-4-CMargin,Rect.Top+CMargin);
StringGrid1.Canvas.LineTo(Rect.Right-CMargin,Rect.Top+7+CMargin);
StringGrid1.Canvas.LineTo(Rect.Right-7-CMargin,Rect.Top+7+CMargin);
StringGrid1.Canvas.LineTo(Rect.Right-4-CMargin,Rect.Top+CMargin);
end;
end;
end;

initialization
Randomize;
end.

meikl ;-)
0

Accepted Solution

RUSTAM earned 50 total points
ID: 6316129
Every column and row in TStringGris are TStringList. Thjat's why you can use this sample:

StringGrid1.Columns[0].Sorted := True;
0

LVL 27

Expert Comment

ID: 6316147
this would cause that the rows becomes mixed,
because only the column is sorted but not the row

sample effect

unsorted
2 4
1 5
7 6
4 8

1 4
2 5
4 6
7 8

sorted by my sample(s)
1 5
2 4
4 8
7 6

meikl ;-)
0

LVL 27

Expert Comment

ID: 6316173
just to say RUSTOM its not a good fair style to answer a q,

specially that (i guess) your answer isn't the solution, which is needed, except the grid does have only one column

meikl ;-)
0

LVL 27

Expert Comment

ID: 6316174
RUSTOM->RUSTAM

sorry, for the typo :-)
0

Author Comment

ID: 6317064
The way I did it was similar to that suggested by Meikl, but because the grid was a fixed 4 columns wide and only needed to sort A-Z on column 0 it didn't have to be as flexible. (Just a few 'quick & dirty' lines of inflexible code.)
It seemed to be so crude and an unnecessary complication so I was looking for an elegant one liner that must surely exist, because as Rustam points out the StringGrid code is probably only an array of stringLists.
I was hoping that instead of doing something odd like removing the sort, Borland just forgot to include the syntax in the help system. ie, it just needed someone in the know to reveal the syntax of how to access it and still maintain the integrity of the rows.
I agree Meikl, that locking an answer with previous comments un-assessed is unusual, perhaps Rustam is new to EE.
I looks like I'll have to keep my existing messy code so I'll accept the answer and post points to meikl as well.
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, thâ€¦
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGridâ€¦
This video Micro Tutorial shows how to password-protect PDF files with free software. Many software products can do this, such as Adobe Acrobat (but not Adobe Reader), Nuance PaperPort, and Nuance Power PDF, but they are not free products. This videâ€¦
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
###### Suggested Courses
Course of the Month8 days, 18 hours left to enroll