Feldbreiten des DBGrid an Textbreite anpassen
-
- Beiträge: 37
- Registriert: Do 6. Mär 2008, 12:48
- OS, Lazarus, FPC: WinXP/Mint13KDE (Lazarus 1.0.8 FPC 2.6.2)
- CPU-Target: 64 Bit
- Wohnort: Halle (Saale)
Feldbreiten des DBGrid an Textbreite anpassen
Hallo, liebe Forumteilnehmer!
Ich möchte in meinem DBGrid mittels einer Prozedur die Spaltenbreiten an den längsten Text jeder Spalte anpassen. Habe schon jede Menge in Google gesucht, bin aber leider bisher nicht fündig geworden. Mein Ansatz ist, durch mein Grid (ist immer nur ein kleines mit einer überschaubaren Anzahl Spalten (5) u. Zeilen (9..20)) spaltenweise durch alle Zeilen zu gehen und die maximale Textbreite respektive -weite zu ermitteln und mit dieser die Spaltenbreite neu zu setzen. Folgende Frage: Wie ermittle ich die Breite des Textes (TextWidth(...)?)? Ist diese in Punkten zu lesen? Setze ich die neue Breite mit DBGrid.Columns.Items[Col].Width := ...? Oder muss ich da etwas umrechen?
Wäre für jeden Hinweis dankbar!
Gruß
Aldi
Ich möchte in meinem DBGrid mittels einer Prozedur die Spaltenbreiten an den längsten Text jeder Spalte anpassen. Habe schon jede Menge in Google gesucht, bin aber leider bisher nicht fündig geworden. Mein Ansatz ist, durch mein Grid (ist immer nur ein kleines mit einer überschaubaren Anzahl Spalten (5) u. Zeilen (9..20)) spaltenweise durch alle Zeilen zu gehen und die maximale Textbreite respektive -weite zu ermitteln und mit dieser die Spaltenbreite neu zu setzen. Folgende Frage: Wie ermittle ich die Breite des Textes (TextWidth(...)?)? Ist diese in Punkten zu lesen? Setze ich die neue Breite mit DBGrid.Columns.Items[Col].Width := ...? Oder muss ich da etwas umrechen?
Wäre für jeden Hinweis dankbar!
Gruß
Aldi
-
- Beiträge: 37
- Registriert: Do 6. Mär 2008, 12:48
- OS, Lazarus, FPC: WinXP/Mint13KDE (Lazarus 1.0.8 FPC 2.6.2)
- CPU-Target: 64 Bit
- Wohnort: Halle (Saale)
Hallo und vielen Dank für die schnellen Antworten!
Mein Problem ist momentan noch, dass ich einfach nicht weiss, wie ich an den Text einer durch Spalte, Zeile definierten Zelle heran komme. Das für mich Wichtige: Canvas.TextExtend(DBGrid.DataSource.DataSet.undwaskommtjetzt?) Oder gibt es noch einen einfacheren Weg? (Sorry für die für viele von euch sicher doofe Frage, aber es ist schon eine Zeit her, dass mich mich zuletzt damit beschäftigt habe und man vergißt wirklich verdammt schnell verdammt viel.)
Gruß
Aldi
Mein Problem ist momentan noch, dass ich einfach nicht weiss, wie ich an den Text einer durch Spalte, Zeile definierten Zelle heran komme. Das für mich Wichtige: Canvas.TextExtend(DBGrid.DataSource.DataSet.undwaskommtjetzt?) Oder gibt es noch einen einfacheren Weg? (Sorry für die für viele von euch sicher doofe Frage, aber es ist schon eine Zeit her, dass mich mich zuletzt damit beschäftigt habe und man vergißt wirklich verdammt schnell verdammt viel.)
Gruß
Aldi
-
- Lazarusforum e. V.
- Beiträge: 2809
- Registriert: Sa 9. Sep 2006, 18:05
- OS, Lazarus, FPC: Linux (L trunk FPC trunk)
- CPU-Target: 64Bit
- Wohnort: Dresden
- Kontaktdaten:
DBGrid.Datasource.DataSet.RecNo(Integer) >> setzt aktiven Datensatz (also letztlich die Zeile)
...DataSet.FieldByName('Feldname').AsString >> gibt den String-Wert der mit Feldnamen angegebenen Spalte der oben gesetzten Zeile zurück, also eine konkrette Zelle.
Mit Dataset.First und Next kannst du in ner Schleife auch alle Datensätze durchgehen, bspw:
...DataSet.FieldByName('Feldname').AsString >> gibt den String-Wert der mit Feldnamen angegebenen Spalte der oben gesetzten Zeile zurück, also eine konkrette Zelle.
Mit Dataset.First und Next kannst du in ner Schleife auch alle Datensätze durchgehen, bspw:
Code: Alles auswählen
var: MaxBreite: integer;
DataSet.First;
MaxBreite := 0;
while not Dataset.EOF do
begin
if Canvas.TextExtend(DataSet.FieldByName('Spalte1').AsString > MaxBreite; then
MaxBreite := Canvas.TextExtend(DataSet.FieldByName('Spalte1').AsString;
DataSet.Next;
end;
//Und dann Zuweisung an entsprechende Spalte:
DBGrid.Columns.Items[Spalte1].Width := MaxBreite;
Johannes
Also ich versteh zwar nicht viel von DB unter Lazarus, aber ich würde das
OnPrepareCanvas Ereignis nehmen.
Das sollte eigentlich immer auf dem aktuellen Datensatz stehen und mit DataCol kann man das Feld abholen und gleich Column.Width setzen.
Es heisst übrigens TextExtenT, aber TextWidth würde reichen.
Ich stelle mir das so vor, das müsste das Problem eigentlich lösen ohne viel Geeiere (nicht getestet)
OnPrepareCanvas Ereignis nehmen.
Das sollte eigentlich immer auf dem aktuellen Datensatz stehen und mit DataCol kann man das Feld abholen und gleich Column.Width setzen.
Es heisst übrigens TextExtenT, aber TextWidth würde reichen.
Ich stelle mir das so vor, das müsste das Problem eigentlich lösen ohne viel Geeiere (nicht getestet)
Code: Alles auswählen
procedure TForm1.DBGrid1PrepareCanvas(sender: TObject; DataCol: Integer;
Column: TColumn; AState: TGridDrawState);
var Wid:Integer;
begin
Wid:=Canvas.TextWidth(TDBGrid(Sender).DataSource.DataSet.Fields[DataCol].AsString);
if Column.Width<Wid then Column.Width:=Wid;
end;
-
- Beiträge: 6079
- Registriert: Do 21. Sep 2006, 07:51
- OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
- CPU-Target: AVR,ARM,x86(-64)
- Wohnort: Dessau
- Kontaktdaten:
Warnung recNo dürfe nicht bei allen TDataSet abkömmlingen Funktionieren. In SQL Tabellen hat man schlichtweg in 90% der Fälle keine Recordnumber. geht ja auch nicht weil die Abfrage ja stark variieren kann.
Am effizientesten wäre das in Grid zu machen du könntest dir einen Nachfahren vom DBGrid ableiten und das über den Buffer des DataSets machen. Das wäre viel schneller als tatsächlich die datensätze durchzugehn. problem ist dabei das beim scrollen die Spaltenbreite springen dürfte.
Am effizientesten wäre das in Grid zu machen du könntest dir einen Nachfahren vom DBGrid ableiten und das über den Buffer des DataSets machen. Das wäre viel schneller als tatsächlich die datensätze durchzugehn. problem ist dabei das beim scrollen die Spaltenbreite springen dürfte.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/
- af0815
- Lazarusforum e. V.
- Beiträge: 6766
- 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:
Ich meine, der schnellste Ansatz ist (mit einer Unschärfe):
Unmittelbar nach der Abfrage aus der Datenbank, so wie von Monta gebracht, durch die Datenmenge gehen, nur dort den längsten String speichern.
Dann erst mittels TextExtend die Länge bestimmen und die Spalte des Grids setzen.
Dann erst die Datenmenge an das Grid hängen.
Warum: Wird bei der kleinen Anwendung nicht so spürbar sein, sind aber viele Datensätze und Spalten vorhanden, so kosten das ausrechen der Breite mehr. Bei der Stringlänge kann es nur vorkommen, das das Feld nicht zu 100% genau definiert wird, weil bei einigen Zeichen (i etc.) Platz eingespart wird. Ich verwende zur Errechnung der Feldbreite einen breiten Buchstaben als Muster.
Unmittelbar nach der Abfrage aus der Datenbank, so wie von Monta gebracht, durch die Datenmenge gehen, nur dort den längsten String speichern.
Dann erst mittels TextExtend die Länge bestimmen und die Spalte des Grids setzen.
Dann erst die Datenmenge an das Grid hängen.
Warum: Wird bei der kleinen Anwendung nicht so spürbar sein, sind aber viele Datensätze und Spalten vorhanden, so kosten das ausrechen der Breite mehr. Bei der Stringlänge kann es nur vorkommen, das das Feld nicht zu 100% genau definiert wird, weil bei einigen Zeichen (i etc.) Platz eingespart wird. Ich verwende zur Errechnung der Feldbreite einen breiten Buchstaben als Muster.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).