2011-11-17 44 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;