DBGrid Reihenfolge der Spalten sichern

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.

DBGrid Reihenfolge der Spalten sichern

Beitragvon DL3AD » 23. Jul 2017, 11:26 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
DL3AD
 
Beiträge: 355
Registriert: 13. Sep 2013, 11:07
Wohnort: Rügen
OS, Lazarus, FPC: Win7 (L 1.8.0 FPC 3.0.4) und Debian Stretch (L 1.8.0 FPC 3.0.4) | 
CPU-Target: 32Bit/64Bit
Nach oben

Beitragvon Michl » 23. Jul 2017, 14:17 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; 
Michl
 
Beiträge: 2221
Registriert: 19. Jun 2012, 11:54
OS, Lazarus, FPC: Win7 Laz 1.7 Trunk FPC 3.1.1 Trunk | 
CPU-Target: 32Bit/64bit
Nach oben

Beitragvon DL3AD » 23. Jul 2017, 14:54 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
DL3AD
 
Beiträge: 355
Registriert: 13. Sep 2013, 11:07
Wohnort: Rügen
OS, Lazarus, FPC: Win7 (L 1.8.0 FPC 3.0.4) und Debian Stretch (L 1.8.0 FPC 3.0.4) | 
CPU-Target: 32Bit/64Bit
Nach oben

Beitragvon wp_xyz » 23. Jul 2017, 15:09 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.
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 23. Jul 2017, 16:01, insgesamt 1-mal geändert.
wp_xyz
 
Beiträge: 2393
Registriert: 8. Apr 2011, 08:01

Beitragvon Michl » 23. Jul 2017, 15:25 Re: DBGrid Reihenfolge der Spalten sichern

DL3AD hat geschrieben:Wie greife ich auf die Spalten indexe zu ?
Mittels DBGrid1.Columns.Items[...].Index

DL3AD hat geschrieben:Ändert sich der Index beim umsortiern
Ja

DL3AD hat geschrieben:gibt es eine Feste Zuordnung Inex zu Spaltenname ?
Nein, daher oben der Umweg über TList.

DL3AD hat geschrieben:Was ist die Eigenschaft Tag?
http://www.delphipraxis.net/71648-ist-tag.html

DL3AD hat geschrieben:Was ist SortColumn? Was ist TSortorder?
Das sind beides Eigenschaften vom CustomGrid, die für Nachfahren vom CustomGrid verwendet werden, nicht jedoch vom DBGrid. Diese kannst du dort ignorieren.

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?
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Code: Alles auswählen
type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 
Michl
 
Beiträge: 2221
Registriert: 19. Jun 2012, 11:54
OS, Lazarus, FPC: Win7 Laz 1.7 Trunk FPC 3.1.1 Trunk | 
CPU-Target: 32Bit/64bit
Nach oben

Beitragvon DL3AD » 23. Jul 2017, 15:54 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 ?
DL3AD
 
Beiträge: 355
Registriert: 13. Sep 2013, 11:07
Wohnort: Rügen
OS, Lazarus, FPC: Win7 (L 1.8.0 FPC 3.0.4) und Debian Stretch (L 1.8.0 FPC 3.0.4) | 
CPU-Target: 32Bit/64Bit
Nach oben

Beitragvon Michl » 23. Jul 2017, 16:10 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; 
Michl
 
Beiträge: 2221
Registriert: 19. Jun 2012, 11:54
OS, Lazarus, FPC: Win7 Laz 1.7 Trunk FPC 3.1.1 Trunk | 
CPU-Target: 32Bit/64bit
Nach oben

Beitragvon wp_xyz » 23. Jul 2017, 16:10 Re: DBGrid Reihenfolge der Spalten sichern

DL3AD hat geschrieben:Gibt es außer dem Feldnamen einen Marker mit dem ich arbeiten könnte um die Spalte zu identifizieren ?

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[i].Tag den Laufindex i zuweisen.

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;
wp_xyz
 
Beiträge: 2393
Registriert: 8. Apr 2011, 08:01

Beitragvon DL3AD » 23. Jul 2017, 17:10 Re: DBGrid Reihenfolge der Spalten sichern

... Danke - das mit FindColumnOfField ist ein sehr guter Ansatz - da werde ich darauf aufbauen.

Gruß Frank
DL3AD
 
Beiträge: 355
Registriert: 13. Sep 2013, 11:07
Wohnort: Rügen
OS, Lazarus, FPC: Win7 (L 1.8.0 FPC 3.0.4) und Debian Stretch (L 1.8.0 FPC 3.0.4) | 
CPU-Target: 32Bit/64Bit
Nach oben

Beitragvon DL3AD » 25. Jul 2017, 16:44 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
DL3AD
 
Beiträge: 355
Registriert: 13. Sep 2013, 11:07
Wohnort: Rügen
OS, Lazarus, FPC: Win7 (L 1.8.0 FPC 3.0.4) und Debian Stretch (L 1.8.0 FPC 3.0.4) | 
CPU-Target: 32Bit/64Bit
Nach oben

Beitragvon Michl » 25. Jul 2017, 19:56 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?
Code: Alles auswählen
type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 
Michl
 
Beiträge: 2221
Registriert: 19. Jun 2012, 11:54
OS, Lazarus, FPC: Win7 Laz 1.7 Trunk FPC 3.1.1 Trunk | 
CPU-Target: 32Bit/64bit
Nach oben

Beitragvon DL3AD » 26. Jul 2017, 06:22 Re: DBGrid Reihenfolge der Spalten sichern

Michl hat geschrieben:Hast du mal probiert eine Methode mit Application.QueueAsyncall im OnColumnMoved aufzurufen und in dieser Methode zu speichern?

Wie macht man das ?

Michl hat geschrieben:Wenn das Grid auf einem Formular (und nicht z.B. auf einem Frame) liegt, warum speicherst du nicht im OnClose vom Formular?

Wird auch gemacht - 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
DL3AD
 
Beiträge: 355
Registriert: 13. Sep 2013, 11:07
Wohnort: Rügen
OS, Lazarus, FPC: Win7 (L 1.8.0 FPC 3.0.4) und Debian Stretch (L 1.8.0 FPC 3.0.4) | 
CPU-Target: 32Bit/64Bit
Nach oben

Beitragvon wp_xyz » 26. Jul 2017, 07:54 Re: DBGrid Reihenfolge der Spalten sichern

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

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?
wp_xyz
 
Beiträge: 2393
Registriert: 8. Apr 2011, 08:01

Beitragvon DL3AD » 26. Jul 2017, 08:27 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 :mrgreen:

Gruß Frank
DL3AD
 
Beiträge: 355
Registriert: 13. Sep 2013, 11:07
Wohnort: Rügen
OS, Lazarus, FPC: Win7 (L 1.8.0 FPC 3.0.4) und Debian Stretch (L 1.8.0 FPC 3.0.4) | 
CPU-Target: 32Bit/64Bit
Nach oben

Beitragvon braunbär » 26. Jul 2017, 12:08 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.
braunbär
 
Beiträge: 164
Registriert: 8. Jun 2017, 17:21

» Weitere Beiträge siehe nächste Seite »
Nächste

Zurück zu Datenbanken



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

porpoises-institution
accuracy-worried