DBGRID Automatische breite

Für Fragen von Einsteigern und Programmieranfängern...
Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 7039
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: DBGRID Automatische breite

Beitrag von af0815 »

Andy Nightingale hat geschrieben: Mo 22. Dez 2025, 15:07 das Video von Niesi hat schon absolut geholfen. Es wird ein C/S Anwendung mit bis zu 100 oder mehr Clients die alle auf eine Firebird Datenbank auf einem Server zugreifen.
Ok, aber pass gut auf, der Teufel steckt im Detail :-)

Wie lange wird ein Datensatz (oder auch Tabelle) durch eine offene Transaktion blockiert. Was passiert, wenn 2 denselben Datensatz posten, mit unterschiedliche Daten (Normal - the last wins). Nur stimmen dann die Daten ?

Kann ein Client die Transaktion blockieren ? Mein liebstes Beispiel der Manager der gerade beginnt was zu ändern und dabei sieht das ein Meeting hat - Klappe zu und zum Meeting - und dann geht in der DB gerade nichts (hängt vom System ab und wie man locking macht).

Je mehr Benutzer umso mehr kann einem auf die Füße fallen im multi Client Betrieb.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Andy Nightingale
Beiträge: 309
Registriert: Mo 13. Jan 2025, 12:11

Re: DBGRID Automatische breite

Beitrag von Andy Nightingale »

af0815 hat geschrieben: Mo 22. Dez 2025, 16:28
Andy Nightingale hat geschrieben: Mo 22. Dez 2025, 15:07
Je mehr Benutzer umso mehr kann einem auf die Füße fallen im multi Client Betrieb.
Danke dir für die Tipps :D

charlytango
Beiträge: 1214
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: DBGRID Automatische breite

Beitrag von charlytango »

Bei Datenbankfrontends ist es besonders herausfordernd weil man viele Bälle gleichzeitig in der Luft hat.

Man muss den Datenbankserver halbwegs im Griff haben (wenns klemmt damm muss man da mehr Zeit investieren)
Dann noch die richtigen DLLs benutzen, die passenden Zugriffskomponenten (SQLDB od ZEOS)
Danach brauchts im Multiuser Betrieb noch die richtige Locking Strategie wie @af0815 ausgeführt hat. Das ist auch zeitkritisch. Sperrt man eine Tabelle oder einen einzelnen (bzw mehrere) Datensatz. Löst man diese Probleme in der Datenbank und was passiert bei Deadlock? Oder versucht man sich an logischem Locking, das zb bestimmte Bereiche komplett lockt (zb alles was mit dem Kunden 4711 zu tun hat) und was passiert wenn der Benutzer mitten im Änderungsmodus den berühmten Laptop zusammenklappt und drei Wochen auf Urlaub fährt.

Datenbanken sind auch persönliche Vorlieben -- ich zb würde nie Firebird verwenden. Meine DBs sind SQLite, MariaDB/MySQL und MSSQL wenns sein muss.
Andy Nightingale hat geschrieben: Mo 22. Dez 2025, 10:20 Das was du sagst verstehe ich so das du das meiste programmierst anstatt es irgendwo einstellst..-richtig?
Das macht Sinn. Aber man muß es können.
Am Anfang versucht man sicher die passenden Komponenten "zusammenzuklicken" und damit einzustellen.
Wenn was dann aber zb darum geht Formulare oder Klassen mit Vererbung anzugehen sind manchmal grafische Elemente ein Problem, da lässt sich Code leichter verwerben.

In größeren Applikationen ist es dann oft ein Problem Zeitpunkte zu bestimmmen an denen etwas passieren soll.
Wenn man das alles Lazarus überlässt, ist man recht oft in einer quasi undefinierten Situation, wo man auf Objekte zugreifen möchte von denen man nicht sicher weiß dass sie schon existieren.

wp_xyz
Beiträge: 5328
Registriert: Fr 8. Apr 2011, 09:01

Re: DBGRID Automatische breite

Beitrag von wp_xyz »

Um zur ursprünglichen Frage zurückzukommen: Ich bin mit Hilfe des Debuggers in die Tiefen des DBGrid eingetaucht und habe versucht das Verhalten der offenbar nicht immer wirksamen Option dgAutoSizeColumns zu verstehen.

Also: wenn die Option dgAutoSizeColumns in DBGrid.Options aktiviert wird, wird zunächst das Bit gsAutoSized in der internen GridStatus-Variablen gelöscht. Das signalisiert, dass bei der nächsten Gelegenheit die Spaltenbreiten neu berechnet werden sollen. Und das geschieht gleich am Ende des Setters der DBGrid Options über mehrere Zwischenstationen in InternalAutoSizeColumn, wo über alle Spalten hinweg die im Grid gepufferten Records nach den längsten Zellen durchsucht werden. Das geschieht aber nur, wenn eben dieses gsAutoSized-Flag gelöscht ist und die internal Variable FDefaultColWidths auf true steht; diese wird gelöscht, wenn die Spaltenbreiten mit der Maus verändert werden. Durch Letzteres wird die Wirkungsweise der dgAutoSizeColumns-Option sehr eingeschränkt - sobald der User einmal an den Spaltenbreioten gespielt hat, ist die Option tot... Man könnte das beheben, wenn man in der Prozedur UpdateGridColumnSizes das UpdateAutoSizeColumns aus dem "if FDefaultColWidths"-Block herausnimmt:

Code: Alles auswählen

procedure TCustomDBGrid.UpdateGridColumnSizes;
var
  i: Integer;
begin
  if FDefaultColWidths then begin
    if dgIndicator in Options then
      ColWidths[0]:=Scale96ToFont(12);
  end;    // <--- eingefügt
    if NeedAutoSizeColumns then
      UpdateAutoSizeColumns;
//  end;   // <--- auskommentiert
end;
Mit dieser Änderung kann man die Spaltenbreiten ändern und nach Hinundherschalten von gdAutoSizeColumns in den DBGrid.Options das AutoSize wieder aktivieren. Das Hinundherschalten ist nötig, damit gsAutoSized in GridStatus gelöscht wird. Etwas umständlich... Ich bin nicht sicher, ob es sich lohnt, dies in die DBGrid-Quellcode zu committen, denn es geht noch weiter:

Eine weitere Schwierigkeit ist, dass die richtige Spaltenbreite nur für die im Grid geladenen Records berechnet wird. Das ist sinnvoll, weil sonst bei großen Tabellen alle Records der Datenbank vom Server geladen werden müssten (womit man sich keine Freunde macht..). Aber das bedeutet auch, dass, wenn der User scrollt und somit neue Records ins Grid nachgeladen werden, möglicherweise die Spaltenbreite nicht mehr stimmt. Auch das ist gut, denn sonst würden die Spaltenbreiten beim Scrollen wild hinundherspringen. Für die Spaltenbreiten-Anpassung in diesen Fall ist die Methode DBGrid.AutoSizeColumns bzw. .AutoAdjustColumns vorgesehen.

Insgesamt bin ich der Meinung, dass man dgAutoSizeColumns nur als Einstellung für die Initialisierung verstehen darf, damit bei der erstmaligen Anzeige des Grids die zu den geladenen Records optimalen Spaltenbreiten vorliegen. Alle folgenden Anpassungen (v.a. nach Scrollen) muss man durch explizite Aufrufe von AutoSizeColumns/AutoAdjustColumns mit Hilfe eines Buttons o.ä. selbst vornehmen.

Antworten