Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Click Column to Sort TwwDBGrid Data

Posted on 2004-08-25
6
Medium Priority
?
2,198 Views
Last Modified: 2011-09-20
This question is specific to Infopower 's TwwDBGrid. In infopower grid, there is no direct property that enable clicking on header column to sort data. We have to set TitleButton to True and write 2 of its event handler. Set Title 's imagelist etc....

If I want to make a component to do this, which is a best solution between:-
      1. Inherited from it and add new features to the new component.
      2. Make sorting component and link to TwwDBGrid.

I want also a feature like clicking on title column but using hidden data to sort. Multiple column sort using SHIFT key.
0
Comment
Question by:soapsiam
6 Comments
 
LVL 17

Accepted Solution

by:
Wim ten Brink earned 100 total points
ID: 11890264
If it's a DBGrid, then the sort order depends on the index you've selected or the way you've sorted the records in your database. Am not familiar with the TwwDBGrid but I think they do have an event for it. (Probably called OnTitleClick) Depending on the functionality you want, you might either start your new component on the TCustomDBGrid or the TwwDBGrid but it will be a reasonable amount of work. There might be other grid components out there that might be easier to use.
0
 

Assisted Solution

by:BaTy_GiRl
BaTy_GiRl earned 200 total points
ID: 11892444
>There might be other grid components out there that might be easier to use.

Im agree with alex, for example you can use a TStringGrid an paste the followining code  (this source code is for
sort a column when you click someone header, it orders integers, real values, strings, you can configure descending or ascending if u want)

on Mouse Up Event


procedure TForm1.StringGrid1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  c:integer;
  w:integer;
begin
  with stringgrid1 do
  if y<=rowheights[0] then
  begin
    c:=0;
    w:=colwidths[0];
    while (c<colcount) and (w<=x) do
    begin
      inc(c);
      w:=w+colwidths[c]+gridlinewidth;
    end;
    sortgrid(StringGrid1,c,1);  //the grid name, the grid the column to sort, the datatype 1-integer
 end;
end;

procedure Tform1.Sortgrid(Grid : TStringGrid; sortcol,datatype:integer);
var
   i : integer;
   tempgrid:tstringGrid;
   list:array of integer;
begin
  screen.cursor:=crhourglass;
  tempgrid:=TStringgrid.create(self);
  with tempgrid do
  begin
    rowcount:=grid.rowcount;
    colcount:=grid.colcount;
    fixedrows:=grid.fixedrows;
  end;
  with Grid do
  begin
    setlength(list,rowcount-fixedrows);
    for i:= fixedrows to rowcount-1 do
    begin
      list[i-fixedrows]:=i;
      tempgrid.rows[i].assign(grid.rows[i]);
    end;
    quicksort(Grid, list,0,rowcount-fixedrows-1,sortcol,datatype, True);  //last is for ascendig or descending
    for i:=0 to rowcount-fixedrows-1 do
    begin
      rows[i+fixedrows].assign(tempgrid.rows[list[i]])
    end;
    row:=fixedrows;
  end;
  tempgrid.free;
  setlength(list,0);
  screen.cursor:=crdefault;
end;

procedure TForm1.Quicksort(Grid:TStringGrid; var List:array of integer;
    min, max,sortcol,datatype: Integer; Ascending:boolean);
{List is a list of rownumbers in the grid being sorted}
var
    med_value : integer;
    hi, lo, i : Integer;

    function compare(val1,val2:string):integer;
    var
      int1,int2:integer;
      float1,float2:extended;
      errcode:integer;
    begin
      case datatype of
        0: result:=ANSIComparetext(val1,val2);  //if are characters
        1: begin
             int1:=strtointdef(val1,0);         //if are integers
             int2:=strtointdef(val2,0);
             if (int1>int2) then result:=1
             else if int1<int2 then result:=-1
             else result:=0;
           end;

        2: begin                                     //if are floats
             val(val1,float1,errcode);
             if errcode<>0 then float1:=0;
             val(val2,float2,errcode);
             if errcode<>0 then float2:=0;
             if float1>float2 then result:=1
             else if float1<float2 then result:=-1
             else result:=0;
           end;
         else result:=0;
      end;
   end; {compare}

begin
    {If the list has <= 1 element, it's sorted}
    if (min >= max) then Exit;
    {Pick a dividing item randomly}
    i := min + Trunc(Random(max - min + 1));
    med_value := List[i];
    List[i] := List[min]; { Swap it to the front so we can find it easily}
    {Move the items smaller than this into the left
     half of the list. Move the others into the right}
    lo := min;
    hi := max;
    while (True) do
    begin
        // Look down from hi for a value < med_value (for ascending)
        while
           (ascending and (compare(Grid.cells[sortcol,List[hi]]
                             ,grid.cells[sortcol,med_value])>=0))
           or ((not ascending) and (compare(Grid.cells[sortcol,List[hi]]
                             ,grid.cells[sortcol,med_value])<=0))
        do
        begin
            dec(hi);
            if (hi <= lo) then Break;
        end;
        if (hi <= lo) then
        begin {We're done separating the items}
          List[lo] := med_value;
          Break;
        end;

        // Swap the lo and hi values.
        List[lo] := List[hi];
        inc(lo); {Look up from lo for a value >= med_value}

        while
          (ascending and (Compare(grid.cells[sortcol,List[lo]],
                 grid.cells[sortcol,med_value])<0))
          or ((not ascending) and (Compare(grid.cells[sortcol,List[lo]],
                 grid.cells[sortcol,med_value])>0))
        do
        begin
            inc(lo);
            if (lo >= hi) then break;
        end;
        if (lo >= hi) then
        begin  {We're done separating the items}
          lo := hi;
          List[hi] := med_value;
          break;
        end;
        List[hi] := List[lo];
    end;
    {Sort the two sublists}
    Quicksort(Grid,List, min, lo - 1,sortcol,datatype, ascending);
    Quicksort(Grid,List, lo + 1, max,sortcol,datatype, ascending);
end;


Just paste this code on a form and put a TString Grid, fill values of course and you´ll see how the rows sorts
Greetings =)
   B@ty
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 11894067
B@aty, the TwwDBGrid is a data-aware component and could be linked to millions of records. You're not going to read it all in just to do simple sorts. This seems a bit more complicated in my opinion. Sorting shouldn't be a problem either since basically this means just selecting a different index. If ADO is used then you can even specify to the ADO query or table to sort it on whatever column by setting the "Sort" property. (Which is why I love ADO so much.) And yes, you can sort on multiple columns easily this way.
The only problem here is responding to a click on the title... I just don't know how to capture that.
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 6

Assisted Solution

by:bpana
bpana earned 200 total points
ID: 11907616
I didn't work with TwwDBGrid, but it should be the same as any DataGrid. It should have an OnTitleClick event.

Here's a simple example to implement the sort in response to the title click.
http://delphi.about.com/library/weekly/aa042203a.htm
0
 
LVL 1

Author Comment

by:soapsiam
ID: 11911067
I can write event to sort when user click on title button but I have to set many things.
   Set Title image list
  Write code for OnTitleButtonClick
  Write cod for OnCalcTitleAttributes

I have to do this for every form that have a grid. I want to write component that speed up the solution.

//procedure TfrmLineGrantList.wwDBGrid2TitleButtonClick(Sender : TObject; AFieldName:String);
procedure OnTitleButtonClick(Sender : TObject; AFieldName:String);
var SortText : String;
    DataSet : TCustomADODataSet;
begin
      if not (Sender is TwwDBGrid) then exit;
      if not (Sender as TwwDBGrid).DataSource.DataSet.Active then exit;
      DataSet := ((Sender as TwwDBGrid).DataSource.DataSet) as TCustomADODataSet);
      SortText :=DataSet.Sort;
      if Pos(AFieldName + ' ASC',SortText)>0 then
             SortText := AFieldName + ' DESC'
      else
             SortText := AFieldName + ' ASC';
      DataSet.Sort
end;

TfrmLineGrantList.wwDBGrid2TitleButtonClick := OnTitleButtonClick;

Above is one of procedure current used for simple sorting (single column).
0
 
LVL 6

Assisted Solution

by:bpana
bpana earned 200 total points
ID: 11911706
then, I would choose
1. Inherited from it and add new features to the new component.
0

Featured Post

Industry Leaders: 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

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
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 Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
With just a little bit of  SQL and VBA, many doors open to cool things like synchronize a list box to display data relevant to other information on a form.  If you have never written code or looked at an SQL statement before, no problem! ...  give i…
Suggested Courses

581 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