Solved

StringGrid sorting

Posted on 2000-03-30
9
606 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
Use Case: Protecting a Hybrid Cloud Infrastructure

Microsoft Azure is rapidly becoming the norm in dynamic IT environments. This document describes the challenges that organizations face when protecting data in a hybrid cloud IT environment and presents a use case to demonstrate how Acronis Backup protects all data.

 
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

Problems using Powershell and Active Directory?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Strange code, can use it, but i cant figure out what it does. 3 60
Convert Jpg /PNG To GIF 5 135
Delphi: how to send PJL commands to printer 3 99
Multiple image collision 13 75
A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Windows 10 is mostly good. However the one thing that annoys me is how many clicks you have to do to dial a VPN connection. You have to go to settings from the start menu, (2 clicks), Network and Internet (1 click), Click VPN (another click) then fi…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

773 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