DBGrid Reihenfolge der Spalten sichern
-
- Beiträge: 478
- Registriert: Fr 13. Sep 2013, 12:07
- OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
- CPU-Target: 64Bit
- Wohnort: Rügen
DBGrid Reihenfolge der Spalten sichern
Hallo,
ich möchte ein DBGrid konfektionieren d.h. die Reihenfolge der Spalten ermitteln und dann abspeichern - wie greife ich auf die Spalten indexe zu ?
Ändert sich der Index beim umsortiern oder gibt es eine Feste Zuordnung Inex zu Spaltenname ?
Gruß Frank
ich möchte ein DBGrid konfektionieren d.h. die Reihenfolge der Spalten ermitteln und dann abspeichern - wie greife ich auf die Spalten indexe zu ?
Ändert sich der Index beim umsortiern oder gibt es eine Feste Zuordnung Inex zu Spaltenname ?
Gruß Frank
Re: DBGrid Reihenfolge der Spalten sichern
Ist ein bischen tricky, da sich bei der Zuweisung eines Indexes, die restlichen Columns automatisch anpassen. Daher der Umweg mittels einer Liste (schnell mal zusammengeschustert):
Code: Alles auswählen
TForm1 = class(TForm)
...
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure FormCreate(Sender: TObject);
procedure SQLQuery1AfterOpen(DataSet: TDataSet);
private
ProjectIniFile: String;
procedure LoadIni;
procedure SaveIni;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ProjectIniFile := Application.Location + PathDelim + 'project.ini';
...
end;
procedure TForm1.SQLQuery1AfterOpen(DataSet: TDataSet);
begin
...
LoadIni;
end;
procedure TForm1.LoadIni;
var
Ini: TIniFile;
List: TList;
i, i2: Integer;
AFieldName: String;
begin
if not SQLQuery1.Active then Exit;
List := TList.Create;
Ini := TIniFile.Create(ProjectIniFile);
try
for i := 0 to DBGrid1.Columns.Count - 1 do
List.Add(DBGrid1.Columns.Items[i]);
for i := 0 to DBGrid1.Columns.Count - 1 do
begin
AFieldName := Ini.ReadString('Grid', 'Column' + IntToStr(i), DBGrid1.Columns.Items[i].FieldName);
for i2 := 0 to List.Count - 1 do
if AFieldName = TColumn(List[i2]).FieldName then
begin
TColumn(List[i2]).Index := i;
Break;
end;
end;
except
on e: Exception do
ShowMessage('TForm1.LoadIni: ' + e.Message);
end;
Ini.Free;
List.Free;
end;
procedure TForm1.SaveIni;
var
Ini: TIniFile;
i: Integer;
begin
if not SQLQuery1.Active then Exit;
Ini := TIniFile.Create(ProjectIniFile);
try
for i := 0 to DBGrid1.Columns.Count - 1 do
Ini.WriteString('Grid', 'Column' + IntToStr(i), DBGrid1.Columns.Items[i].FieldName);
except
on e: Exception do
ShowMessage('TForm1.SaveIni: ' + e.Message);
end;
Ini.Free;
end;
procedure TForm1.FormClose(Sender: TObject;
var CloseAction: TCloseAction);
begin
SaveIni;
...
end;
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
-
- Beiträge: 478
- Registriert: Fr 13. Sep 2013, 12:07
- OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
- CPU-Target: 64Bit
- Wohnort: Rügen
Re: DBGrid Reihenfolge der Spalten sichern
Hallo Michl,
Danke!
du sagst es - es ist mir zu tricky.
Ich möchte die einzelnen Eigenschaften verstehen - gibt da auch keine vernünftige Hilfe
Wie greife ich auf die Spalten indexe zu ?
Ändert sich der Index beim umsortiern oder gibt es eine Feste Zuordnung Inex zu Spaltenname ?
Was ist die Eigenschaft Tag?
Was ist SortColumn?
Was ist TSortorder?
Zur Laufzeit kann man die Reihenfolge ja beliebig Ändern d.h. es gehen die Zuordnungen zu den Feldnamen nicht verloren
Gruß Frank
Danke!
du sagst es - es ist mir zu tricky.
Ich möchte die einzelnen Eigenschaften verstehen - gibt da auch keine vernünftige Hilfe
Wie greife ich auf die Spalten indexe zu ?
Ändert sich der Index beim umsortiern oder gibt es eine Feste Zuordnung Inex zu Spaltenname ?
Was ist die Eigenschaft Tag?
Was ist SortColumn?
Was ist TSortorder?
Zur Laufzeit kann man die Reihenfolge ja beliebig Ändern d.h. es gehen die Zuordnungen zu den Feldnamen nicht verloren
Gruß Frank
Re: DBGrid Reihenfolge der Spalten sichern
Ich verstehe nicht... Der Spalten"index" ist wie der Index in einem Array, das erste Array-Element hat den Index 0, das zweite den Index 1 usw. Welches Feld der Spalte zugeordnet ist, ist eine andere Sache - das erhältst du über die Eigenschaft FieldName der Spalte, also DBGrid.Columns[0].FieldName ist der Name des Feldes, das in der 1.Spalte dargestellt ist.
Wenn du die Spalten umsortierst, bleibt der Index der 1. Spalte immer 0 - sonst wär's ja nicht die 1.Spalte!, nur steht dann dort ein anderes Feld.
Falls dies dir nicht weiterhilft, versuche die Frage klarer zu formulieren.
[EDIT]
Michl hat recht: es gibt noch eine zweite Art von Index. Nachdem TColumn ein Element einer Collection ist, hat es auch die Eigenschaft Index, also der Index, mit dem sie ursprünglich erzeugt wurde. Allerdings wird dieser Index verändert, wenn sich die Reihenfolge durch Umsortieren ändert. Baue in Michl Projekt des folgenden Beitrags einen Button ein, der auf folgenden Code im OnClick reagiert, und du siehst, dass die Spalten-Eigenschaft Index beim Verändern der Spaltenreihenfolge mit der Maus mit dem Array-Index identisch bleibt. Zur Identification einer Spalte ist Index also nicht geeignet, sondern nur FieldName.
Wenn du die Spalten umsortierst, bleibt der Index der 1. Spalte immer 0 - sonst wär's ja nicht die 1.Spalte!, nur steht dann dort ein anderes Feld.
Falls dies dir nicht weiterhilft, versuche die Frage klarer zu formulieren.
[EDIT]
Michl hat recht: es gibt noch eine zweite Art von Index. Nachdem TColumn ein Element einer Collection ist, hat es auch die Eigenschaft Index, also der Index, mit dem sie ursprünglich erzeugt wurde. Allerdings wird dieser Index verändert, wenn sich die Reihenfolge durch Umsortieren ändert. Baue in Michl Projekt des folgenden Beitrags einen Button ein, der auf folgenden Code im OnClick reagiert, und du siehst, dass die Spalten-Eigenschaft Index beim Verändern der Spaltenreihenfolge mit der Maus mit dem Array-Index identisch bleibt. Zur Identification einer Spalte ist Index also nicht geeignet, sondern nur FieldName.
Code: Alles auswählen
procedure TForm1.Button2Click(Sender: TObject);
var
L: TStrings;
F: TForm;
LB: TListbox;
i: Integer;
col: TColumn;
begin
F := TForm.Create(nil);
try
F.Position := poMainFormCenter;
LB := TListbox.Create(F);
LB.Parent := F;
LB.Align := alClient;
L := TStringList.Create;
try
for i:=0 to DBGrid1.Columns.Count-1 do begin
col := DBGrid1.Columns[i];
L.Add('%d - Index: %d, FieldName: %s', [i, col.Index, col.FieldName]);
end;
LB.Items.Assign(L);
finally
L.Free;
end;
F.ShowModal;
finally
F.Free;
end;
end;
Zuletzt geändert von wp_xyz am So 23. Jul 2017, 17:01, insgesamt 1-mal geändert.
Re: DBGrid Reihenfolge der Spalten sichern
Mittels DBGrid1.Columns.Items[...].IndexDL3AD hat geschrieben:Wie greife ich auf die Spalten indexe zu ?
JaDL3AD hat geschrieben:Ändert sich der Index beim umsortiern
Nein, daher oben der Umweg über TList.DL3AD hat geschrieben:gibt es eine Feste Zuordnung Inex zu Spaltenname ?
http://www.delphipraxis.net/71648-ist-tag.htmlDL3AD hat geschrieben:Was ist die Eigenschaft Tag?
Das sind beides Eigenschaften vom CustomGrid, die für Nachfahren vom CustomGrid verwendet werden, nicht jedoch vom DBGrid. Diese kannst du dort ignorieren.DL3AD hat geschrieben:Was ist SortColumn? Was ist TSortorder?
Ich hänge mal ein kleines Bsp. an mit 32bit SQLite für Windows an (wenn du ein anderes OS oder 64bit verwendest, müsstest du die SQLite-Bibliothek austauschen), mit einem Button, der das Grid von vorn nach hinten sortiert. Vielleicht hilft es ja zum besseren Verständnis?
- Dateianhänge
-
SQLDB-SQLite-Einfach.zip
- (325.74 KiB) 104-mal heruntergeladen
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
-
- Beiträge: 478
- Registriert: Fr 13. Sep 2013, 12:07
- OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
- CPU-Target: 64Bit
- Wohnort: Rügen
Re: DBGrid Reihenfolge der Spalten sichern
... d.h. mit DBGrid1.Columns.Items[...].Index wird die Reihenfolge 0...n von links nach rechts gekennzeichnet.
Wenn ich z.B. eine Spalte Datum habe und verschiebe diese so erhält sie je nach position einen anderen Index.
An jede Spalte sind ja verschiedene Eigenschaften geknüpft welche alle erhalten bleiben bist auf den Index wenn ich verschiebe.
Gibt es außer dem Feldnamen einen Marker mit dem ich arbeiten könnte um die Spalte zu identifizieren ?
Wenn ich z.B. eine Spalte Datum habe und verschiebe diese so erhält sie je nach position einen anderen Index.
An jede Spalte sind ja verschiedene Eigenschaften geknüpft welche alle erhalten bleiben bist auf den Index wenn ich verschiebe.
Gibt es außer dem Feldnamen einen Marker mit dem ich arbeiten könnte um die Spalte zu identifizieren ?
Re: DBGrid Reihenfolge der Spalten sichern
Der Fieldname ist eindeutig. D.h. wenn das Query aktiv ist und das entsprechende Field liefert, kann das Column eindeutig zugeordnet werden. Daher würde ich immer dieses verwenden. Ansonsten könnte man die Columns auch nach Column.Tag, Column.Title.Caption bzw Column.Displayname unterscheiden, wenn diese unverwechselbar zugewiesen wurden.
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
Re: DBGrid Reihenfolge der Spalten sichern
Eigentlich nicht. Es sei denn, du verwendest die Allzweck-Eigenschaft "Tag" dafür (übersetzt etwa wie "Aufkleber"). Diese Eigenschaft wird für sonst nichts verwendet und steht zur freien (einmaligen) Verfügung. Du könntest nach dem Öffnen der Datenbank, wenn die ursprüngliche Reihenfolge der Spalten feststeht, die Columns des Grid durchlaufen und DBGrid.Columns.Tag den Laufindex i zuweisen.DL3AD hat geschrieben:Gibt es außer dem Feldnamen einen Marker mit dem ich arbeiten könnte um die Spalte zu identifizieren ?
Aber, eigentlich würde ich das nicht machen. Vielleicht brauchst du Tag später für noch etwas anderes? Und FieldName ist von der Datenbank her garantiert eindeutig. Z.B. könntest du so nach der Spalte mit einem bestimmten Feld suchen:
Code: Alles auswählen
function FindColumnOfField(AGrid: TDBGrid; AFieldName: String): TColumn;
var
i: Integer;
begin
for i:=0 to AGrid.Columns.Count-1 do
if AGrid.Columns[i].FieldName = AFieldName then begin
Result := AGrid.Columns[i];
exit;
end;
Result := nil;
end;
-
- Beiträge: 478
- Registriert: Fr 13. Sep 2013, 12:07
- OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
- CPU-Target: 64Bit
- Wohnort: Rügen
Re: DBGrid Reihenfolge der Spalten sichern
... Danke - das mit FindColumnOfField ist ein sehr guter Ansatz - da werde ich darauf aufbauen.
Gruß Frank
Gruß Frank
-
- Beiträge: 478
- Registriert: Fr 13. Sep 2013, 12:07
- OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
- CPU-Target: 64Bit
- Wohnort: Rügen
Re: DBGrid Reihenfolge der Spalten sichern
Hallo,
es funktioniert soweit alle prima - Spaltenbreite, Titel, Feldnamen und Sichtbakeit der Spalten sichern sowie die Reihenfolge sicher geht auch (über Testbutton)
Ein kleines Problem habe ich noch - wenn ich die Reihenfolge der Spalten durch verschieben ändere dann habe ich mit OnColumnMoved ein Event erzeugt und
wollte dann die neue Reihenfolge speichern.
Nun habe ich festgestellt dass das Event kommt befor die neue Reihenfolge der Spalten "fertig" ist - das sieht man schön wenn eine SchowMessage macht.
Es wird nachdem man die Maustaste losgelassen hat die Message ausgegeben und der Rote Marker zwischen den Spalten wird noch angezeigt.
Erst wenn die Message bestätigt wird sortiert sich die Spalte um.
Gibt es da ein anderes Event welchen man verwenden kann wenn das Umsortieren komplett fertig ist ?
Gruß Frank
es funktioniert soweit alle prima - Spaltenbreite, Titel, Feldnamen und Sichtbakeit der Spalten sichern sowie die Reihenfolge sicher geht auch (über Testbutton)
Ein kleines Problem habe ich noch - wenn ich die Reihenfolge der Spalten durch verschieben ändere dann habe ich mit OnColumnMoved ein Event erzeugt und
wollte dann die neue Reihenfolge speichern.
Nun habe ich festgestellt dass das Event kommt befor die neue Reihenfolge der Spalten "fertig" ist - das sieht man schön wenn eine SchowMessage macht.
Es wird nachdem man die Maustaste losgelassen hat die Message ausgegeben und der Rote Marker zwischen den Spalten wird noch angezeigt.
Erst wenn die Message bestätigt wird sortiert sich die Spalte um.
Gibt es da ein anderes Event welchen man verwenden kann wenn das Umsortieren komplett fertig ist ?
Gruß Frank
Re: DBGrid Reihenfolge der Spalten sichern
Hast du mal probiert eine Methode mit Application.QueueAsyncall im OnColumnMoved aufzurufen und in dieser Methode zu speichern?
Wenn das Grid auf einem Formular (und nicht z.B. auf einem Frame) liegt, warum speicherst du nicht im OnClose vom Formular?
Wenn das Grid auf einem Formular (und nicht z.B. auf einem Frame) liegt, warum speicherst du nicht im OnClose vom Formular?
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
-
- Beiträge: 478
- Registriert: Fr 13. Sep 2013, 12:07
- OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
- CPU-Target: 64Bit
- Wohnort: Rügen
Re: DBGrid Reihenfolge der Spalten sichern
Wie macht man das ?Michl hat geschrieben:Hast du mal probiert eine Methode mit Application.QueueAsyncall im OnColumnMoved aufzurufen und in dieser Methode zu speichern?
Wird auch gemacht - aber wen ich Spalten verschoben habe dann will ich vieleicht noch welche ein und ausblenden - dann muss ich vorher nochMichl hat geschrieben:Wenn das Grid auf einem Formular (und nicht z.B. auf einem Frame) liegt, warum speicherst du nicht im OnClose vom Formular?
meine CheckListBox mit der neuen Reihenfolge befüllen - und dafür benötige ich das Event OnColumnMoved
Re: DBGrid Reihenfolge der Spalten sichern
Aber das machst du doch nicht gleichzeitig. Ich würde die Checklistbox erst zu Beginn der Routine, die den Dialog zum An/Abwählen von Spalten erzeugt, füllen. Oder ist diese Checklistbox permanent sichtbar?DL3AD hat geschrieben:aber wen ich Spalten verschoben habe dann will ich vieleicht noch welche ein und ausblenden - dann muss ich vorher noch
meine CheckListBox mit der neuen Reihenfolge befüllen - und dafür benötige ich das Event OnColumnMoved
-
- Beiträge: 478
- Registriert: Fr 13. Sep 2013, 12:07
- OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
- CPU-Target: 64Bit
- Wohnort: Rügen
Re: DBGrid Reihenfolge der Spalten sichern
... ist in einem DBGrid Configurations Form - da wird alles zum Tabellendesign eingestellt und somit gleichzeitig sichtbar.
EDIT:
Problem gelößt:
Habe einen TTimer in der OnColumnMoved gesetzt (1ms) und in der Timer procedure den rest erledigt - nun is wie muss
Gruß Frank
EDIT:
Problem gelößt:
Habe einen TTimer in der OnColumnMoved gesetzt (1ms) und in der Timer procedure den rest erledigt - nun is wie muss

Gruß Frank
-
- Beiträge: 463
- Registriert: Do 8. Jun 2017, 18:21
- OS, Lazarus, FPC: Windows 10 64bit, Lazarus 3.6, FPC 3.2.2
- CPU-Target: 64Bit
- Wohnort: Wien
Re: DBGrid Reihenfolge der Spalten sichern
Diese Vorgangsweise ist eine "quick and dirty" Notlösung, wenn es gar nicht anders geht, und beinhaltet m.E. immer das Risiko von instabilem Programmverhalten.
Du kannst nie 100% sicher sein, ob die Zeit, die du dem Timer lässt, auch wirklich ausreicht. Wenn ein anderer Task mit hoher Priorität dein Programm kurzzeitig blockiert, passiert nicht mehr das, was du wilst. Mag sein, dass die Wahrscheinlichkeit gering ist, aber man sollte immer eine bessere Lösung suchen.
Du kannst nie 100% sicher sein, ob die Zeit, die du dem Timer lässt, auch wirklich ausreicht. Wenn ein anderer Task mit hoher Priorität dein Programm kurzzeitig blockiert, passiert nicht mehr das, was du wilst. Mag sein, dass die Wahrscheinlichkeit gering ist, aber man sollte immer eine bessere Lösung suchen.