?
Solved

Grid/List, Sorting, Component

Posted on 2003-03-09
11
Medium Priority
?
1,054 Views
Last Modified: 2012-05-04
anyone know a component that
is a "grid" where i can sort on
a click on the "header"
and sort both ways?

it has to be a free component
and it must be "includable" in the
main exe, so there is only the exe
to use.
0
Comment
Question by:tspse
[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
11 Comments
 
LVL 3

Expert Comment

by:BTecho
ID: 8099895
Hello.

There are some choices

http://freespace.virgin.net/giles.lindsay/GJL-Software/ExDBGrid.html

http://www.scalabium.com/faq/smdbgrid.htm ->also checkout FAQ


http://jvcl.sourceforge.net/main.htm ->includes the RXLib DBGrid

Or you can do this yourself using the DBGrid's OnTitleClick event, you can easy sort using SQL with a TQuery. If you use a TTable you can set the IndexName , but note: you must add 2 indexes, one for descending and one for ascending sort , for each field you want to sort both ways.
0
 
LVL 27

Accepted Solution

by:
kretzschmar earned 1000 total points
ID: 8100658
you can do it with the standard-stringgrid

an older sample

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]);
        SL.AddObject(AGrid.Cells[ColIndex,I],ARow);
      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;

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.Pen.Color := clbtnShadow;
             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.Pen.Color := clbtnShadow;
             StringGrid1.Canvas.LineTo(Rect.Right-4-CMargin,Rect.Top+CMargin);
           end;
  end;
end;

initialization
  Randomize;
end.


meikl ;-)
0
 
LVL 1

Expert Comment

by:soapsiam
ID: 8100826
You can use vgLibrary (vgDBGrid), please see following code (my case):-

// Title button onClick event
procedure TfrmMain.DBGrid1TitleBtnClick(Sender: TObject; ACol: Integer;
  Field: TField);
var
    SortString : string;
begin
    SortString := MainDM.ADOSp1.Sort;
    if ShiftDown and (SortString <> '') then
    begin
        if Pos(Field.FieldName, SortString)>0 then
        begin
            if Pos(Field.FieldName+' DESC',SortString) > 0 then
                SortString := StringReplace(SortString, Field.FieldName+' DESC',Field.FieldName+' ASC',[rfIgnoreCase])
            else
                SortString := StringReplace(SortString, Field.FieldName+' ASC',Field.FieldName+' DESC',[rfIgnoreCase]);
        end
        else
            SortString := SortString +', '+Field.FieldName+' ASC';
        MainDM.ADOSp1.Sort := SortString;
        exit;
    end;

    if SortString <> '' then
    begin
        if Pos(Field.FieldName+' ASC',SortString) > 0 then
            SortString := Field.FieldName+' DESC'
        else if Pos(Field.FieldName+' DESC',SortString) > 0 then
            SortString := Field.FieldName+' ASC'
        else
            SortString := Field.FieldName+' ASC';
    end
    else
        SortString := Field.FieldName+' ASC';
    MainDM.ADOSp1.Sort := SortString;
end;

// Drawing title button event
procedure TfrmMain.DBGrid1GetBtnParams(Sender: TObject; Field: TField;
  AFont: TFont; var Background: TColor; var SortMarker: TSortMarker;
  IsDown: Boolean);
var str : string;
begin
    str := MainDM.ADOSp1.Sort;
    if AnsiPos(Field.FieldName+' ASC', str) > 0 then
        SortMarker := smUp
    else if AnsiPos(Field.FieldName+' DESC', str) > 0 then
        SortMarker := smDown
    else
        SortMarker := smNone;
end;

As you can see, you only write code for only 2 events. There are images that already defined in the components.
please come to see it at http://www.vglib.com/link-5.html
0
Independent Software Vendors: 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!

 

Author Comment

by:tspse
ID: 8101888
Ok,

SMDB-Grid: looked ok, but i dit not figure out
how to sort the list after its been filled (didnt have much time, nor did it say in page)

GJL: requires delphi updated to "service pack 2" or what
it is called.

Vg-Lib: costs what i saw.

still not satisfied yet.
0
 
LVL 3

Expert Comment

by:BTecho
ID: 8105081
Hi, tspse

I abviously want to sort a DBGrid not a StringGrid. What Database do you use? and what kind of DataSet do you use to access the Database?


For the SMDBGrid.

You can use the OnTitleClick event to catch the Title click.

1. How I can add the sorted column?

SMDBGrid.DataSource.DataSet.DisableControls;

{add a new sorted column in list - ascending order}
with SMDBGrid.SortColumns.Add do
begin
    FieldName := 'yourFieldName';
    SortType := stAscending
end;

{add a new sorted column in list - descending order}
with SMDBGrid.SortColumns.Add do
begin
    FieldName := 'yourFieldName';
    SortType := stDescending;
end;

SMDBGrid.DataSource.DataSet.EnableControls;

--------------------------------------------------------------------------------

2. How I can clear the all sorted columns?

SMDBGrid.DataSource.DataSet.DisableControls;

{clear the all sorted columns}
SMDBGrid.SortColumns.Clear;

SMDBGrid.DataSource.DataSet.EnableControls;

--------------------------------------------------------------------------------

3. How I can change a standard TSMDBGrid glyphs (sorted arrows, indicator symbols etc)?

You can run the Image Editor application (or any other resource workshop), open the SMDBGrid.RES file and change the any glyphs.



Also did you try ExDBGrid?

Description says:
Automatic Column Sorting (Fields that have indexes will be sortable by clicking the Column Titles), QueryByForm and SortByForm implementation (For Paradox and dBASE any column names specified in the SortByForm procedure must already be indexed. For SQL-based tables, the specified columns need not be indexed.)


Also the JVCL DBGrid noted that is had the feature you wanted. So if needed why not apply the Delphi Patch?

0
 

Author Comment

by:tspse
ID: 8107122
im not using any db because the data comes from a ini-file provided by a third-party site
0
 

Author Comment

by:tspse
ID: 8160035
BTecho: when i use your code to sort the
SMDBGrid, my program just crashes..

---------------------------
Debugger Exception Notification
---------------------------
Project htht.exe raised exception class EAccessViolation with message 'Access violation at address 004ACB8F in module 'htht.exe'. Read of address 00000030'. Process stopped. Use Step or Run to continue.
---------------------------
OK   Help  
---------------------------
0
 

Expert Comment

by:CleanupPing
ID: 9316870
tspse:
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1 
EXPERTS:
Post your closing recommendations!  No comment means you don't care.
0
 

Author Comment

by:tspse
ID: 9318659
Hmm, i had totally forgotten about EE :D
The program went down in the drain about the same time
my computer went the same way :D

So basicly i didnt use any code, sort of.
But i still got help, with probably code
that would done the right thing only if i continued,
so i dont dont what to do now, advise would be good on this matter then
(not the code-stuff)

People shouldnt feel that they help out and then not getting any points.
0
 
LVL 5

Expert Comment

by:snehanshu
ID: 10090511
Hi!
No comment has been added lately and this question is therefore classified abandoned.

If asker wishes to close the question, then refer to
http://www.experts-exchange.com/help/closing.jsp

Otherwise, I will leave a recommendation in the Cleanup topic area that this question is:

Answered by: kretzschmar

Please leave any comments here within the next seven days. It is assumed that any participant not responding to this request is no longer interested in its final disposition.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

...Snehanshu
EE Cleanup Volunteer

P.S.
  tspse, looks like you didn't try meikl's suggestion at all.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

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…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA: https://www.percona.com/resources/we…
Suggested Courses

770 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