Das DBGrid ist eine Vielen bekannte Standardkomponente in Delphi. Ohne weitere Drittkomponenten ist das DBGrid die einzige Gridkomponente zur Darstellung von Informationen aus Datenbanken. Obwohl das DBGrid seine Grundfunktion erfüllt, gibt es Features, die ein Nutzer bei der tabellarischen Darstellung von Daten erwartet. Während verschiedene Gridkomponenten von Drittentwicklern viele dieser Funktionen von Haus aus bieten, müssen Entwickler bei dem DBGrid diese selbst programmieren.
In dem folgenden Abschnitt wird in einem kurzen Beispiel gezeigt, wie man Spalteninhalte in einem DBGrid per Mausklick auf das Titelfeld der jeweiligen Spalte auf- und absteigend sortieren kann. Je nach Anforderungen können Lösungen für dieses Problem natürlich verschiedenartig aussehen und erreicht werden, das folgende stellt lediglich eine Möglichkeit dar. Das folgende Beispiel ist mit Delphi XE5 geschrieben worden und nutzt die FireDAC-Komponenten.
Folgende Komponenten wurden hier auf dem Formular platziert:
- TDBGrid
- TDBNavigator
- TFDConnection
- TDatasource
- TFDQuery
- TFDGUIxWaitCursor und TFDPhysMySQLDriverLink
TFDGUIxWaitCursor und TFDPhysMySQLDriverLink sind hier für FireDAC notwendig, da eine MySQL-Datenbank genutzt wird und können für alles Weitere ignoriert werden.
In der TFDConnection-Komponente wird die Verbindung zum Server eingerichtet. Das TDBGrid und der TDBNavigator werden mit der TDatasource und diese mit der TFDQuery verknüpft, die wiederum mit der TFDConnection verbunden ist.
Die TFDQuery enthält ein sehr schlichtes Statement:
SELECT * FROM Artikel |
Um eine Spalte mit einem Mausklick auf seinen Titel zu sortieren, wird das OnTitleClick-Event des DBGrids genutzt. Der Code, der bei dem Event ausgeführt wird, kann nun so aussehen
procedure TForm1.DBGrid1TitleClick(Column: TColumn); var OldOrderString: String; NewOrderString: String; i: integer; TmpRecNo: integer; begin //Speichern der aktuell ausgewählten Zeile //Nach dem Reaktivieren der Query wird sonst immer die erste Zeile markiert TmpRecNo := FDQuery1.RecNo; //Prüfung, ob bereits eine Sortierung vorhanden ist If pos('ORDER BY', Uppercase(FDQuery1.SQL.Text)) <> 0 then begin NewOrderString := 'ORDER BY ' + Column.FieldName; //Ersetze eine bereits vorhandene Sortierung durch die neue Spalte 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]); //Prüfe, ob dieselbe Spalte noch einmal angeklickt wurde //Falls ja, wechsel zwischen auf- und absteigend 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; //Springe zur markierten Zeile zurück FDQuery1.RecNo := TmpRecNo; //Die Spalte, nach der sortiert wird, fett machen und alle anderen wieder normal darstellen 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; |
Mit diesen Zeilen wird der Inhalt der Spalte, dessen Titel angeklickt wurde entweder aufsteigend oder, falls dies bereits der Fall sein sollte, absteigend sortiert. Des Weiteren wird der Titel der Spalte, nach der sortiert wird, fett markiert.