Solved

Click Column to Sort TwwDBGrid Data

Posted on 2004-08-25
6
2,040 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 50 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 100 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
ScreenConnect 6.0 Free Trial

Want empowering updates? You're in the right place! Discover new features in ScreenConnect 6.0, based on partner feedback, to keep you business operating smoothly and optimally (the way it should be). Explore all of the extras and enhancements for yourself!

 
LVL 6

Assisted Solution

by:bpana
bpana earned 100 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 100 total points
ID: 11911706
then, I would choose
1. Inherited from it and add new features to the new component.
0

Featured Post

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
add combobox item based on numbers 9 141
Delphi - replicating a form 8 74
Dynamically Created Query 3 55
Tvertscrollbox like a whatsapp layout delete messages 1 16
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
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…
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
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 …

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