Solved

StringGrid sorting

Posted on 2000-03-30
9
595 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
  • 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
 
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

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…
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…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

760 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now