「 TClientDataSet 就可以做到的功能,但它的效能有這麼差嗎?」
抱著這樣的疑問,我開啟了這位仁兄的專案,他是這麼寫的:
LSum := 0; while ClientDataSet1.Eof do begin LSum := LSum + ClientDataSet1.Fields[n].AsInteger; ClientDataSet1.Next; end; while ClientDataSet2.Eof do begin LSum := LSum + ClientDataSet2.Fields[n].AsInteger; ClientDataSet2.Next; end; Result := LSum;
這樣跟輪詢的方式好像差不多,為什麼不用更好的方法:
TClientDataSet 裡的 Aggregate Field 合計欄位功能
在 Field Editor 便可以輕鬆完成定義這個欄位,如果要 2 個 TClientDataSet 欄位要加總時也只需要這樣寫:
LSum := Cds1AggregateField.Value + Cds2AggregateField.Value
動態產生的話,也不難,最終應該會以這樣的成果出現:
LSum := ClientDataSet1.SumFieldFloat(FieldName) + ClientDataSet2.SumFieldFloat(FieldName);
以範例資料庫 employee.cds 裡的資料進行試算,結果如下,
修改前:1.0812692 sec
修改後:0.0010634 sec
驚人的速度提升!
至於為什麼 Aggregate 機制效能可以這麼高?
追到 DSIntf.pas 時
function GetAggregateValue( hAgg : hDSAggregate; pValue : Pointer; var bBlank : LongBool ): DBResult; stdcall;
看來這是藏在 Midas.dll 裡面,無解了。
........好吧,那這樣的程式碼要怎麼實現呢?
以下的程式碼,搭配 helper class 就可以解決這個問題啦!
function TClientDataSetHelper.SumFieldFloat(A_計算式: string): Extended; var Agg: TAggregate; begin Agg := Self.Aggregates.Add; Agg.Expression := Format('SUM(%s)', [A_計算式]); Agg.Active := True; Result := StrToFloat(Agg.Value); Self.Aggregates.Delete(Agg.Index); end;
您好 請問 function TClientDataSetHelper.SumFieldFloat(A_計算式: string): Extended; 整個程式架構要怎麼設計,是要新增一個unit 還是寫在form裡面 ,clientdataset 要怎麼呼叫他?? 謝謝
回覆刪除您好,TClientDataSetHelper 通常會設計成一個獨立的 Unit。這樣可以方便在不同的 Form 或其他 Unit 中重複使用。
刪除程式架構:
新增 Unit: 在您的 Delphi 專案中新增一個 Unit (例如:ClientDataSetHelper.pas)。
撰寫 Helper Class: 將 TClientDataSetHelper 的類別定義和 SumFieldFloat 方法寫在這個 Unit 中。
使用 Unit: 在需要使用 SumFieldFloat 的 Form 或 Unit 的 uses 子句中加入 ClientDataSetHelper。
呼叫方法: 透過 ClientDataSet 的實例來呼叫 SumFieldFloat 方法。
呼叫範例 (在 Form 中):
==
uses
..., ClientDataSetHelper;
procedure TForm1.SomeProcedure;
var
LSum: Extended;
begin
LSum := ClientDataSet1.SumFieldFloat('YourFieldName');
// ... 其他程式碼
end;