Nils Eilers, 05.05.2017
Here's the English translation:
DBGrid Sorting by Column Click in Delphi
The DBGrid is a well-known standard component in Delphi. Without additional third-party components, the DBGrid is the only grid component for displaying information from databases. Although the DBGrid fulfills its basic function, there are features that a user expects for the tabular presentation of data. While various grid components from third-party developers offer many of these functions out of the box, developers have to program these features themselves with the DBGrid.
In the following section, a short example demonstrates how to sort column content in a DBGrid ascending and descending by clicking on the column header. Depending on the requirements, solutions for this problem can of course vary; the following is just one possibility. This example is written with Delphi XE5 and uses FireDAC components.
Components placed on the form:
TDBGrid
TDBNavigator
TFDConnection
TDatasource
TFDQuery
TFDGUIxWaitCursor and TFDPhysMySQLDriverLink
TFDGUIxWaitCursor and TFDPhysMySQLDriverLink are necessary for FireDAC, as a MySQL database is used, but can be ignored for everything else.
In the TFDConnection component, the connection to the server is configured. The TDBGrid and the TDBNavigator are connected to the TDatasource, which is linked to the TFDQuery, which in turn is connected to the TFDConnection.
The TFDQuery contains a very simple statement:
SELECT *
FROM Artikel
Sorting Columns by Clicking on Headers
To sort a column by clicking on its header, the OnTitleClick event of the DBGrid is used. The code executed during the event could look like this:
procedure TForm1.DBGrid1TitleClick(Column: TColumn);
var
OldOrderString: String;
NewOrderString: String;
i: integer;
TmpRecNo: integer;
begin
// Save the currently selected row
// After reactivating the query, the first row is otherwise always marked
TmpRecNo := FDQuery1.RecNo;
// Check if sorting already exists
If pos('ORDER BY', Uppercase(FDQuery1.SQL.Text)) <> 0 then
begin
NewOrderString := 'ORDER BY ' + Column.FieldName;
// Replace an existing sorting with the new column
For i:= 0 to DBgrid1.Columns.Count - 1 do
begin
OldOrderString := 'ORDER BY ' + DBGrid1.Columns[i].FieldName;
FDQuery1.SQL.Text := StringReplace(FDQuery1.SQL.Text, OldOrderString, NewOrderString, [rfReplaceAll, rfIgnoreCase]);
// Check if the same column was clicked again
// If yes, switch between ascending and descending
If OldOrderString = NewOrderString then
begin
FDQuery1.SQL.Text := FDQuery1.SQL.Text;
If pos(Uppercase(NewOrderString + ' ASC'), Uppercase(FDQuery1.SQL.Text)) <> 0 then
FDQuery1.SQL.Text := StringReplace(FDQuery1.SQL.Text, NewOrderString + ' ASC', NewOrderString + ' DESC', [rfReplaceAll, rfIgnoreCase])
else
FDQuery1.SQL.Text := StringReplace(FDQuery1.SQL.Text, NewOrderString + ' DESC', NewOrderString + ' ASC', [rfReplaceAll, rfIgnoreCase]);
end;
end;
end
Else
FDQuery1.SQL.Append(' ORDER BY ' + Column.FieldName + ' ASC');
FDQuery1.Active := true;
// Return to the marked row
FDQuery1.RecNo := TmpRecNo;
// Make the column being sorted bold and all others normal again
For i := 0 to DBGrid1.Columns.Count - 1 do
begin
If DBGrid1.Columns[i].Title.Font.Style = [fsBold] then
DBGrid1.Columns[i].Title.Font.Style := [];
end;
If DBGrid1.Columns[Column.Index].Title.Font.Style <> [fsBold] then
DBGrid1.Columns[Column.Index].Title.Font.Style := [fsBold];
end;
Explanation
With these lines, the content of the column whose header was clicked is sorted either ascending or, if it was already sorted that way, descending. Additionally, the title of the column being sorted is displayed in bold.
Summary of Features
Sorting columns by clicking on their titles.
Switching between ascending and descending order when clicking repeatedly.
Displaying the sorted column's header in bold.
Maintaining the selected row after sorting.
Works with Delphi XE5 and FireDAC components.
This approach can be further expanded or customized as needed.