Solved

StringGrid sorting

Posted on 2000-03-30
9
633 Views
Last Modified: 2010-04-04
Does anyone knows some easy way to sort StringGrid Rows on a given Column's content?

Jo.
0
Comment
Question by:Fatman121898
[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
  • Learn & ask questions
  • 4
  • 4
9 Comments
 
LVL 9

Expert Comment

by:ITugay
ID: 2668809
You may put all string from given columns to sorted TStringList and then back to StringGrids.

Cheers,
Igor.

PS: do not forget TStringList.Sorted:=true;
0
 
LVL 9

Expert Comment

by:ITugay
ID: 2668820
The sample

var L : TStringList;
begin
   L := TStringList.Create;
   L.Sorted:=true;
   L.Assign(StringGrid1.Cols[2]);
   StringGrid1.Cols[2].Assign(L);
   L.Free;
end;

---------
Igor
0
 
LVL 1

Author Comment

by:Fatman121898
ID: 2668834
Hi Igor,

it's nice to hear you again.
What I'm trying is to sort whole stringgrid, not items in its rows separately.
That means to swap rows in such way that the values in key column are sorted in accendant (descendant) order.

Jo.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:Fatman121898
ID: 2668840
Hi Igor,

it's nice to hear you again.
What I'm trying is to sort whole stringgrid, not items in its rows separately.
That means to swap rows in such way that the values in key column are sorted in accendant (descendant) order.

Jo.
0
 
LVL 2

Expert Comment

by:florisb
ID: 2668853
Hi,

bit more complex I think: you can copy the column you want to sort on to the first column. Then put all rows in a stringgrid. Sort it, remove the first column and then place it back (got idea from website).

have it working in programm, I also took those up-down arrows from Outlook and place them 'on' the grid when it's sorted.


getsort does the sorting, setImage switches between the images and in the mousedown event a leftclick in the header is detected. OmgekeerdResult is dutch for reversed-result.

some vars that I set on create:
//init globals
  omgekeerdResult := false;
  sortedOnColumn := 0; //invisible in UMS, so safe to set first
  globalWaitDblClick := false;
  globalCol := 0;
  globalRow := 0;
//init form
  imUp.visible := false;
  imDown.visible := false;
  imUp.parent := grdResult;
  imDown.parent := grdResult;
//vul grid a.d.h.v. sql
  grdResult.FixedRows := 1;
  grdResult.TopRow := 2;

with some copy-pasting you must be able to use my post, I expect...:-)

Floris.





procedure TResultaten.GetSort(var GenStrGrid : TStringGrid; ThatCol : Integer;omgekeerdResult : boolean);
{ Description : sort stringlist, by copying to stringlist
                (column that has to be sorted is move to beginning line, sort
                is done automatically and column is placed back)
  Pre         : rowcount has to be set correctly!
  Post        : genstrgrid sorted on Column:ThatCol
  Input       : -
  Returns     : -
  Creator     : Floris
  Date        : 5-2}
const
 TheSeparator = '@'; // Define the Separator
var
 CountItem, I, J, K, ThePosition : Integer;
 MyList : TStringList;
 MyString, TempString : String;
begin
  CountItem := GenStrGrid.RowCount; // Give the number of rows in the StringGrid
  MyList := TStringList.Create;//Create the List
  MyList.Sorted := False;
  try
    begin
    for I := 1 to (CountItem - 1) do
      begin
      MyList.Add(GenStrGrid.Rows[I].Strings[ThatCol] + TheSeparator + GenStrGrid.Rows[I].Text);
      end;
    Mylist.Sort;//Sort the List
    for K := 1 to Mylist.Count do
      begin
      MyString := MyList.Strings[(K - 1)];//Take the String of the line (K – 1)
      ThePosition := Pos(TheSeparator, MyString);//Find the position of the Separator in the String
      TempString := '';
      //element waarop gesorteerd is kan nu verwijderd worden van eerste positie
      TempString := Copy(MyString, (ThePosition + 1), Length(MyString));
      MyList.Strings[(K - 1)] := '';
      MyList.Strings[(K - 1)] := TempString;
      end;
   if not omgekeerdResult then
     begin
     for J := 1 to (CountItem - 1) do
       GenStrGrid.Rows[J].Text := MyList.Strings[(J - 1)];//Refill the StringGrid
     end
   else
     begin
     for J := 1 to (CountItem - 1) do
       GenStrGrid.Rows[J].Text := MyList.Strings[((CountItem-2)-(J - 1))];//Refill the StringGrid
     end;
   setImage(thatCol,omgekeerdResult); //plaats Outlookalike bitmap in columnheader.
  end;
 finally
  MyList.Free;//Free the List
 end;
end;

procedure TResultaten.setImage(thatCol: integer;down: boolean);
const
  distance = 20;
var
  MyLeft,y,z : integer;
begin
  y := grdResult.LeftCol;
  //loop column with till end thatCol
  myLeft := 0;
  for z := 0 to thatCol do
    myLeft := myLeft +grdResult.ColWidths[z];
  if not(down) then
    begin
    imUp.Left := (y+myLeft) - distance;
    imUp.Top := 1;
    imDown.visible := false;
    imUp.visible := true;
    end
  else
    begin
    imDown.Left := (y+myLeft) - distance;
    imDown.Top := 1;
    imUp.visible := false;
    imDown.visible := true;
    end
end;




procedure TResultaten.grdResultMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
{ Description : right and leftmouse handling, sort if column click.
  Pre         :
  Post        :
  Input       : -
  Returns     : -
  Creator     : Floris
  Date        : 3-2, update 4-2}

begin
if not (globalWaitDblClick) then //dubbel click was -> overslaan
  begin
  grdResult.MouseToCell(x,y,globalCol,globalRow);
  //right mouseclick
    if Button = mbright then
      begin
      if activeResultSet = false then //no activerestul, no pop-up at all.
        grdResult.popupMenu := nil
      else
        begin
  //      grdResult.MouseToCell(x,y,Col,Row); //HALELUJA! (wist niet dat deze functie bestond)
          if globalRow = -1 then
            exit
          else if globalRow = 0 then
            grdResult.popupMenu := popupTop //show popup for upper columns
          else
            begin
            grdResult.row := globalrow; //show normal popup and set current row here
            grdResult.popupMenu := popupGrid;
            end;
        end;
      end
  //left mouseclick
    else if (not (activeResultSet = false)) and (ssLeft in Shift) then
      begin
  //    grdResult.MouseToCell(x,y,Col,Row); //get row
      if globalRow = -1 then
        exit
      else if globalrow = 0 then
        begin
        screen.cursor := crHourGlass;
        //bepaal of er up of down gesort wordt.
        if (globalcol = sortedOnColumn) then
          begin
          if not omgekeerdResult then //switch after third clicks on same column
            omgekeerdResult := true
          else
            omgekeerdResult := false;
          end
        else
          omgekeerdResult := false;
        GetSort(grdResult,globalcol, omgekeerdResult);
        sortedOnColumn := globalcol;
        screen.cursor := crDefault;
        end;
      end;
  end
else
  globalWaitDblClick := false;
//grdResult.refresh; //how to refresh that move column line?
//grdResult.repaint;
end;
0
 
LVL 9

Expert Comment

by:ITugay
ID: 2668863
Hi Jo,
Hi floris (it's a comment!;)

Yes I'm wrong. Of course you need to sort whole stringgrid;) Just a moment, I have simply idea. TStringList can store not only strings but some associated data too. You may put as data number of original position in ROW. After sorting, it's possible to know where is new position. Just a moment, I will check it........


Igor.
0
 
LVL 1

Author Comment

by:Fatman121898
ID: 2668877
Hi Floris,

This is not what I meant 'easy' ;-).
Anyway, I'll test it for a while, and be back soon.

Jo.
0
 
LVL 9

Accepted Solution

by:
ITugay earned 50 total points
ID: 2668915
Hi all again,
Not so easy but It work:

SG - your TStringGrid.
-------------
procedure TForm1.SpeedButton1Click(Sender: TObject);
var L : TStringList;
    G : TStringGrid;
    I : integer;
begin
   G := TStringGrid.Create(nil);
   G.RowCount:=SG.RowCount;
   G.ColCount:=SG.ColCount;

   L := TStringList.Create;
   L.Sorted:=true;
   for I:=0 to SG.RowCount-1 do
   begin
      L.AddObject(SG.Cells[2,I],pointer(I));
      G.Rows[I].Assign(SG.Rows[I]);
   end;
   for I:=0 to L.Count-1 do
     SG.Rows[I].Assign(G.Rows[integer(L.Objects[I])]);

   L.Free;
   G.Free;
end;
-------------

Cheers,
Igor.
0
 
LVL 1

Author Comment

by:Fatman121898
ID: 2669185
Igor, that is what I needed.
You got the points.
Floris, thank you too.

Jo.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
There's a multitude of different network monitoring solutions out there, and you're probably wondering what makes NetCrunch so special. It's completely agentless, but does let you create an agent, if you desire. It offers powerful scalability …
Monitoring a network: why having a policy is the best policy? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the enormous benefits of having a policy-based approach when monitoring medium and large networks. Software utilized in this v…
Suggested Courses
Course of the Month5 days, 8 hours left to enroll

626 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question