I have a TDBGrid. It works, but the columns shown are very large.
How can I set an "auto-fix column width"?
I have a TDBGrid. It works, but the columns shown are very large.
How can I set an "auto-fix column width"?
The needed Columnwidth is depended of the settings of the Grids canvas and the mamimum length of the displaytext of each field.
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;
if a[i] < w then
I'd set a[i] := w;
then set Grid.Columns[i].Width := a[i] + C_Add
in the last for
loop. –
Petrel TDBGrid
does not have this kind of functionality in the first place, and Windows Explorer does not resize 'properly' under some circumstances either. –
Ommiad ds.GotoBookmark(bm);
two lines up (just in front of the for-loop). Otherwise the program crashes in some situations. –
Twine Minor modification of bummi's answer to insure that Title Row (Row 0) is not truncated, and excess space will be allocated on each column
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;
Minor modification of bummi's answer to insure that Title Row (Row 0) is not truncated
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;
ds.GotoBookmark(bm);
two lines up (just in front of the for-loop). Otherwise the program crashes in some situations. –
Twine Minor modification of bummi's, TheSteven's and Jens' answers to insure that Title Row (Row 0) is not truncated, and excess space will be allocated on each column, and take visibility of columns into account.
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;
I found 'Columns' in the properties of my TDBGrid and new window is opened. In that window I add new FieldNames - you can choose columnNames only from the result of your SQL string of your TADOQuery and then when you click to the exact column you can find 'Width' in the properties of selected column so change it whatever you like. It works for me.
I'm afraid the last adaptation of the code is no correct.
I would rather write something like :
const
C_Add=20;
//.....
Sup := 0;
if CoverWhiteSpace then
sup :=C_Add;
for I := 0 to VisibleColumnsCount - 1 do
VisibleColumns[I].Width := A[I] + sup;
DS.GotoBookmark(BM);
© 2022 - 2024 — McMap. All rights reserved.
DisplayWidth
count of0
chars, which is 6px wide each with Tahoma size 8 font (at default scaling). If you were displaying, let's say a 100 ofW
chars (which is 10px wide each), the default column width would be 400px narrower than is actually needed (when theDisplayWidth
would be 100). So there might be also an opposite reason to autosize the widths. – Pyrrho