2013-07-07 13 views
5

Ich habe ein TDBGrid. Es funktioniert, aber die Spalten sind sehr groß.Adjust Spaltenbreite DBGrid

Wie kann ich eine "auto-fix column width" einstellen?

+4

Die Breite jeder Spalte wird standardmäßig auf die angegebene Größe des entsprechenden Felds angepasst. Wenn dies nicht mit der Realität übereinstimmt, sollten Sie Ihr Datenbankdesign überdenken. –

+0

@Uwe, das ist wahr für die "DisplayWidth" -Zahl des Feldes von '0' Zeichen, die 6px breit sind, jedes mit Tahoma Schriftgröße 8 (bei Standardskalierung). Wenn Sie eine 100 von 'W'-Zeichen anzeigen (die jeweils 10px breit ist), wäre die Standardspaltenbreite 400 Pixel schmaler als tatsächlich benötigt (wenn die' DisplayWidth' 100 wäre). Es könnte also auch einen gegenteiligen Grund geben, die Breiten automatisch zu skalieren. – TLama

Antwort

10

Die erforderliche Spaltenbreite hängt von den Einstellungen der Grids-Zeichenfläche und der maximalen Länge des Anzeigetextes jedes Felds ab.

procedure FitGrid(Grid: TDBGrid); 
const 
    C_Add=3; 
var 
    ds: TDataSet; 
    bm: TBookmark; 
    i: Integer; 
    w: Integer; 
    a: Array of Integer; 
begin 
    ds := Grid.DataSource.DataSet; 
    if Assigned(ds) then 
    begin 
    ds.DisableControls; 
    bm := ds.GetBookmark; 
    try 
     ds.First; 
     SetLength(a, Grid.Columns.Count); 
     while not ds.Eof do 
     begin 
     for I := 0 to Grid.Columns.Count - 1 do 
     begin 
      if Assigned(Grid.Columns[i].Field) then 
      begin 
      w := Grid.Canvas.TextWidth(ds.FieldByName(Grid.Columns[i].Field.FieldName).DisplayText); 
      if a[i] < w then 
       a[i] := w ; 
      end; 
     end; 
     ds.Next; 
     end; 
     for I := 0 to Grid.Columns.Count - 1 do 
     Grid.Columns[i].Width := a[i] + C_Add; 
     ds.GotoBookmark(bm); 
    finally 
     ds.FreeBookmark(bm); 
     ds.EnableControls; 
    end; 
    end; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    FitGrid(DBgrid1) 
end; 
+5

ZeroMemory wird nicht benötigt. SetLength initialisiert alle neuen Mitglieder mit Null. –

+0

Gute Lösung. Nur eine kleine Auswahl: Im inneren 'if a [i] lurker

+0

Das kann bei einem großen Datensatz sehr lange dauern, und wenn Sie einen streunenden Datensatz mit einem sehr langen Inhalt haben, wird dieser Fehler behoben. Was übrigens die Gründe sind, warum das 'TDBGrid' überhaupt nicht über diese Funktionalität verfügt und Windows Explorer unter Umständen auch nicht 'richtig' skaliert. –

3

Minor Modifikation von Bummi Antwort, um sicherzustellen, dass Titel Row (Zeile 0)

procedure FitGrid(Grid: TDBGrid); 
const 
    C_Add=3; 
var 
    ds: TDataSet; 
    bm: TBookmark; 
    i: Integer; 
    w: Integer; 
    a: Array of Integer; 
begin 
    ds := Grid.DataSource.DataSet; 
    if Assigned(ds) then 
    begin 
    ds.DisableControls; 
    bm := ds.GetBookmark; 
    try 
     ds.First; 
     SetLength(a, Grid.Columns.Count); 
     while not ds.Eof do 
     begin 
     for I := 0 to Grid.Columns.Count - 1 do 
     begin 
      if Assigned(Grid.Columns[i].Field) then 
      begin 
      w := Grid.Canvas.TextWidth(ds.FieldByName(Grid.Columns[i].Field.FieldName.).DisplayText); 
      if a[i] < w then 
       a[i] := w ; 
      end; 
     end; 
     ds.Next; 
     end; 
     //if fieldwidth is smaller than Row 0 (field names) fix 
     for I := 0 to Grid.Columns.Count - 1 do 
     begin 
     w := Grid.Canvas.TextWidth(Grid.Columns[i].Field.FieldName); 
     if a[i] < w then 
      a[i] := w ; 
     end; 

     for I := 0 to Grid.Columns.Count - 1 do 
     Grid.Columns[i].Width := a[i] + C_Add; 
     ds.GotoBookmark(bm); 
    finally 
     ds.FreeBookmark(bm); 
     ds.EnableControls; 
    end; 
    end; 
end; 
+0

Hallo, ich bin ziemlich neu in Delphi und ich möchte dich bitten zu erklären, wie das im Detail funktioniert. Was sind Variablen wie ich, w und ein Gut für ect. Ich werde wirklich dankbar sein. – user2886091

2

Minor Modifikation von Bummi Antwort nicht abgeschnitten wird, um sicherzustellen, dass Titel Row (Zeile 0) nicht abgeschnitten, und überschüssiger Raum wird auf jeder Spalte zugeordnet wird

procedure FitGrid(Grid: TDBGrid); 
const 
    C_Add = 3; 
var 
    ds: TDataSet; 
    bm: TBookmark; 
    i: Integer; 
    w: Integer; 
    a: array of Integer; 
begin 
    ds := Grid.DataSource.DataSet; 

    if not Assigned(ds) then 
    exit; 

    if Grid.Columns.Count = 0 then 
    exit; 

    ds.DisableControls; 
    bm := ds.GetBookmark; 
    try 
    ds.First; 
    SetLength(a, Grid.Columns.Count); 
    for i := 0 to Grid.Columns.Count - 1 do 
     if Assigned(Grid.Columns[i].Field) then 
     a[i] := Grid.Canvas.TextWidth(Grid.Columns[i].FieldName); 

    while not ds.Eof do 
    begin 

     for i := 0 to Grid.Columns.Count - 1 do 
     begin 
     if not Assigned(Grid.Columns[i].Field) then 
      continue; 

     w := Grid.Canvas.TextWidth(ds.FieldByName(Grid.Columns[i].Field.FieldName).DisplayText); 

     if a[i] < w then 
      a[i] := w; 
     end; 
     ds.Next; 
    end; 

    w := 0; 
    for i := 0 to Grid.Columns.Count - 1 do 
    begin 
     Grid.Columns[i].Width := a[i] + C_Add; 
     inc(w, a[i] + C_Add); 
    end; 

    w := (Grid.ClientWidth - w - 20) div (Grid.Columns.Count); 

    if w > 0 then 
     for i := 0 to Grid.Columns.Count - 1 do 
     Grid.Columns[i].Width := Grid.Columns[i].Width + w; 


    ds.GotoBookmark(bm); 
    finally 
    ds.FreeBookmark(bm); 
    ds.EnableControls; 
    end; 
end; 
0

Minor Modifikation von Bummi des, TheSteven den und Jens Antworten, um sicherzustellen, dass Titel Row (Zeile 0) nicht abgeschnitten, und die überschüssige Raum wird allo in jeder Spalte angegeben werden, und Sichtbarkeit der Spalten berücksichtigen.

procedure FitGrid(const Grid: TDBGrid; const CoverWhiteSpace: Boolean = True); 
const 
    C_Add=3; 
var 
    DS: TDataSet; 
    BM: TBookmark; 
    I, W, VisibleColumnsCount: Integer; 
    A: array of Integer; 
    VisibleColumns: array of TColumn; 
begin 
    DS := Grid.DataSource.DataSet; 
    if Assigned(DS) then 
    begin 
    VisibleColumnsCount := 0; 
    SetLength(VisibleColumns, Grid.Columns.Count); 
    for I := 0 to Grid.Columns.Count - 1 do 
     if Assigned(Grid.Columns[I].Field) and (Grid.Columns[I].Visible) then 
     begin 
     VisibleColumns[VisibleColumnsCount] := Grid.Columns[I]; 
     Inc(VisibleColumnsCount); 
     end; 
    SetLength(VisibleColumns, VisibleColumnsCount); 

    DS.DisableControls; 
    BM := DS.GetBookmark; 
    try 
     DS.First; 
     SetLength(A, VisibleColumnsCount); 
     while not DS.Eof do 
     begin 
     for I := 0 to VisibleColumnsCount - 1 do 
     begin 
      W := Grid.Canvas.TextWidth(DS.FieldByName(VisibleColumns[I].Field.FieldName).DisplayText); 
      if A[I] < W then 
       A[I] := W; 
     end; 
     DS.Next; 
     end; 
     //if fieldwidth is smaller than Row 0 (field names) fix 
     for I := 0 to VisibleColumnsCount - 1 do 
     begin 
     W := Grid.Canvas.TextWidth(VisibleColumns[I].Field.FieldName); 
     if A[I] < W then 
      A[I] := W; 
     end; 

     W := 0; 
     if CoverWhiteSpace then 
     begin 
     for I := 0 to VisibleColumnsCount - 1 do 
      Inc(W, A[I] + C_Add); 
     W := (Grid.ClientWidth - W - 20) div VisibleColumnsCount; 
     if W < 0 then 
      W := 0; 
     end; 

     for I := 0 to VisibleColumnsCount - 1 do 
     VisibleColumns[I].Width := A[I] + C_Add + W; 
     DS.GotoBookmark(BM); 
    finally 
     DS.FreeBookmark(BM); 
     DS.EnableControls; 
    end; 
    end; 
end;