2011-11-17 43 views
1

我有一个过程来自动调整网格中的列的大小以适应该列中的最大字符串。但是,如果网格中有超过2000条记录,则需要一些时间。有关加快速度的任何提示?加快步骤来调整网格列的大小

//lstSKU = grid 
procedure TfrmExcel.ResizeCol(const ACol: Integer); 
var 
    M: Integer; 
    X: Integer; 
    S: String; 
    R: TRect; 
begin 
    M:= 20; 
    lstSKU.Canvas.Font.Assign(lstSKU.Font); 
    for X:= 1 to lstSKU.RowCount - 1 do begin 
    S:= lstSKU.Cells[ACol, X]; 
    R:= Rect(0, 0, 20, 20); 
    DrawText(lstSKU.Canvas.Handle, PChar(S), Length(S), R, 
     DT_LEFT or DT_VCENTER or DT_CALCRECT); 
    if R.Right > M then 
     M:= R.Right; 
    end; 
    M:= M + 15; 
    lstSKU.ColWidths[ACol]:= M; 
end; 

回答

2

这是一个标准的TStringGrid/TDrawGrid?

您可以迭代使用Canvas.TextWidth(S)来代替测量每个单元格的内容宽度,保存最大值,添加任何填充,然后设置Grid.ColWidths[Col] := M;。如果需要,这将触发单个重绘。 (基本上,你在做什么,而不必重复绘图操作2001次)。

procedure TfrmExcel.ResizeCol(const ACol: Integer); 
var 
    M, T: Integer; 
    X: Integer; 
    S: String; 
begin 
    M := 20; 

    for X := 1 to lstSKU.RowCount - 1 do 
    begin 
    S:= lstSKU.Cells[ACol, X]; 
    T := lstSKU.Canvas.TextWidth(S); 
    if T > M then 
     M := T; 
    end; 

    M := M + 15; 
    lstSKU.ColWidths[ACol] := M; 
end; 

如果你想设置单元格的宽度和高度,以适应较大的字体或东西,使用TextExtent代替TextWidth; TextExtent返回TSize,您可以从中读取WidthHeight

+0

它没有绘制单元格的尺寸 - DrawText过程中的“DT_CALCRECT”意味着它不绘制在画布上 - 它只计算矩形的宽度。但是你是对的,TextWidth应该会更好,虽然我很确定它已经使用相同的方法来获得相同的结果。值得一试,如果有帮助,我会告诉你。 –

+0

Doh!错过了'DT_CALCRECT'。不过,我认为'TextWidth'仍然会更快,因为你不需要所有其他标志。 –

+0

是的,这削减了一半的时间 - 除了我不得不修改它 - TFont(至少在Delphi7中)没有TextWidth函数,但画布。 –

1

虽然已经回答,但我发布了最终代码,您可以使用任何字符串网格(TStringGrid)。它在2.3秒内调整了3000个记录,其中有27个列,而不是之前的6.4个平均值。

//AGrid = Grid containing column to be resized 
//ACol = Column index of grid to be resized 
//AMin = Minimum column width 
procedure ResizeCol(AGrid: TStringGrid; const ACol, AMin: Integer); 
var 
    M, T: Integer; //M=Maximum Width; T=Current Text 
    X: Integer; //X=Loop Counter 
begin 
    M:= AMin; //Begin with minimum width 
    AGrid.Canvas.Font.Assign(AGrid.Font); 
    for X:= 1 to AGrid.RowCount - 1 do begin 
    T:= AGrid.Canvas.TextWidth(AGrid.Cells[ACol, X]); 
    if T > M then M:= T; 
    end; 
    AGrid.ColWidths[ACol]:= M + AMin; 
end;