Link to home
Start Free TrialLog in
Avatar of bartekz
bartekz

asked on

Sorting in TCustomDBGrid

I have to sort rows in TCustomDBGrid. By clicking a column it have to sort by this column (like in Win Explorer). Have You got any useful tips?

Greetz
Bartek
Avatar of vladika
vladika

If you use TTable ...
In the OnTitleClick handler try to set Table.IndexFieldName property equal Column.FieldName

If you use TQuery ...
In the OnTitleClick handler try to recreate TQuery.SQL property
by adding proper 'ORDER BY' statement in it


Vladika has a good point there. Zif.
Avatar of bartekz

ASKER

Well, I didn't say I'm writing a component derived from TDBGrid.
In OnTitleClick I can read field values, then I need to sort it and I have to redraw grid (probably remapping fields in DefineFieldMap method). It has to work like this:
- after first clicking on title -> sorting ascending,
- after second clicking on title -> sorting descending,
It has to sort by cliked field/column (like in Win Explorer)

You should use SQL:
SELECT * FROM <table_name> ORDER BY <field_name> ASCENDING/DESCENDING.

If you click first time you sort ascending, seccond change it to descending. You could also use two indexes here, bt SQL is easier and doesn't require indexes.

If you want the titles of the DB grid to look like buttons so you can actually get the feeling of pressing them,  then use something like RXDBGrid (freeware at http://rx.demo.ru/).
ASKER CERTIFIED SOLUTION
Avatar of venks
venks

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I think this equivalent to my short comment
"In the OnTitleClick handler try to set Table.IndexFieldName property equal Column.FieldName"

And this will not work, for example, for client-server databases
(Table1.Exclusive := True - It's strong demand for such task
and user may havn't rights for such operation as creating index)

And how about Query?

Avatar of bartekz

ASKER

Thanx for all answers. But in my component I don't have access to Table or Query (so I can't use Table.IndexFieldName), I only have Datase property. I generated TQuery object and executed query which should sort it, but data shown in Grid is still not sorted! I tried to refresh it, but... doesn't work. I really think I have to remap field in DefineFieldMap method and redraw Grid after it.
The query doesn't sort it phisically!!!
To sort the table phisically use DbiSortTable.



BDE API Examples (DbiSortTable)

Sorts an opened or closed table, either into itself or into a destination table. There are options to remove
duplicates, to enable case-insensitive sorts and special sort functions, and to control the number of
records sorted.


Example 1: Sort a table on a single field.

Options are: Case Insensitive, Case Sensitive, Descending, and Ascending.
This example uses the following input:
SortTable(Table1, Table1.FieldByName('SortField'), False, sortDESCEND, L);
NOTE: L is defined as a longint and specifies the amount of records to sort. Use TTable.RecordCount
to sort the entire table.
The function is defined as follows:

procedure SortTable(Table: TTable; Field: TField; CaseInsensitive: boolean;
                Order: SORTOrder; var SortNumber: longint);
var
  Props: CURProps;
  FieldNumber: word;
  hDb: hDBIDb;

begin
  if Table.Active = False then
    raise EDatabaseError.Create('Table must be opened');
  Check(DbiGetCursorProps(Table.Handle, Props));
  if Props.bIndexed = True then
    raise EDatabaseError.Create('No index can be active when sorting the table');
  FieldNumber := Field.Index + 1;
  Check(DbiGetObjFromObj(hDBIObj(Table.Handle), objDATABASE, hDBIObj(hDb)));
  Table.Close;
  try
    Check(DbiSortTable(hDb, PChar(Table.TableName), Props.szTableType,
             nil, nil, nil, nil, 1, @FieldNumber, @CaseInsensitive, @Order, nil,
             False, nil, SortNumber));
  finally
    Table.Open;
  end;
end;


(http://www.inprise.com/devsupport/bde/bdeapiex/)