TClIEntDataSet 中計算字段有兩種: Calculated(計算字段)、InternalCalc(內部計算字段).
兩者區別是: Calculated 在每次需要時都要重新計算; InternalCalc 只需要計算一次.
Calculated 需要計算的時間, InternalCalc 需要存取的時間; 當然後者快.
計算字段不會被保存到文件.
下面的例子先定義了兩個整數字段: sum1、sum2;
又定義了兩個計算字段: SUM(求和)、MUL(求積), 分別指定了 Calculated、InternalCalc.
計算是在 TClientDataSet 的 OnCalcFIElds 事件中完成的, 每當需要計算結果時事件會被自動激活.
除了 OnCalcFIElds 事件中的代碼外, 其他都可以在設計時完成; 這裡是動態完成的.
//准備: 窗體放置 ClIEntDataSet1、DataSource1、DBGrid1(關聯一下)、Button1
//程序運行後, 可用 Tab 和 ↑ ↓ → ← 鍵配合著輸入測試數據.
{ 建立數據集, 包括計算字段 }
procedure TForm1.Button1Click(Sender: TObject);
begin
with TIntegerFIEld.Create(Self) do
begin
FieldName := 'num1'; { FIEldKind 的默認值是 fkData }
DataSet := ClIEntDataSet1;
end;
with TIntegerFIEld.Create(Self) do
begin
FIEldName := 'num2';
DataSet := ClIEntDataSet1;
end;
with TIntegerFIEld.Create(Self) do
begin
FIEldName := 'SUM';
FIEldKind := fkCalculated; { 指定為計算字段 }
DataSet := ClIEntDataSet1;
end;
with TIntegerFIEld.Create(Self) do
begin
FIEldName := 'MUL';
FIEldKind := fkInternalCalc; { 指定為內部計算字段 }
DataSet := ClIEntDataSet1;
end;
ClIEntDataSet1.CreateDataSet;
Button1.Enabled := False;
end;
{ OnCalcFIElds 事件 }
procedure TForm1.ClientDataSet1CalcFIElds(DataSet: TDataSet);
begin
{ 獲取計算字段的值 }
DataSet['SUM'] := DataSet['num1'] + DataSet['num2'];
{ 獲取內部計算字段的值; 一般要先判斷一下以避免重復運算 }
if DataSet.State = dsInternalCalc then
DataSet['MUL'] := DataSet['num1'] * DataSet['num2'];
end;
在上面程序的基礎上再添加一個 Timer1, 為詳細測試 Calculated 和 InternalCalc 的區別, 代碼修改如下:
var
Calc, InternalCalc: Integer;
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
with TIntegerFIEld.Create(Self) do
begin
FIEldName := 'num1';
DataSet := ClIEntDataSet1;
end;
with TIntegerFIEld.Create(Self) do
begin
FIEldName := 'num2';
DataSet := ClIEntDataSet1;
end;
with TIntegerFIEld.Create(Self) do
begin
FIEldName := 'SUM';
FIEldKind := fkCalculated;
DataSet := ClIEntDataSet1;
end;
with TIntegerFIEld.Create(Self) do
begin
FIEldName := 'MUL';
FIEldKind := fkInternalCalc; { 指定為內部計算字段 }
DataSet := ClIEntDataSet1;
end;
ClIEntDataSet1.CreateDataSet;
{ 添加測試數據 }
ClIEntDataSet1.DisableControls;
for i := 0 to 999 do ClIEntDataSet1.AppendRecord([i, i]);
ClIEntDataSet1.EnableControls;
Button1.Enabled := False;
end;
procedure TForm1.ClientDataSet1CalcFIElds(DataSet: TDataSet);
begin
Inc(Calc);
DataSet['SUM'] := DataSet['num1'] + DataSet['num2'];
if DataSet.State = dsInternalCalc then
begin
Inc(InternalCalc);
DataSet['MUL'] := DataSet['num1'] * DataSet['num2'];
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Text := Format('Calc: %d; InternalCalc: %d', [Calc, InternalCalc]);
end;
測試圖: