計算フィールドと集計フィールド(FireDAC)
データセットの操作(FireDAC) への移動
FireDAC には、いくつかの種類の計算フィールドが用意されています。
概要
計算フィールドは、データベースに対する値の取得や格納が行われない仮想フィールドです。代わりに、クライアント側で計算されます。FireDAC では、すべての TField.FieldKind 型の計算フィールドをサポートしています。
- fkCalculated -- 単純な計算フィールド。この値は、TDataSet.OnCalcFields イベント ハンドラにて計算されます。
- fkInternalCalc -- 詳細計算フィールド。この値は、通常のフィールドに代入することができ、データセット レコード キャッシュに格納されます。TDataSet.OnCalcFields イベント ハンドラで計算されるか、TField.DefaultExpression で指定された式を使用します。
- fkLookup -- ルックアップ フィールド。値は自動的に計算され、ルックアップ データセット内のキー値に対する、このデータセットの値が返されます。
- fkAggregate -- 集計計算フィールド。値は、TAggregateField.Expression に指定された式(集計関数 COUNT、SUM、MIN、MAX、AVG を含みます)を使って計算されます。
フィルタリングやソートや検索の操作に使用できるのは、fkInternalCalc および fkAggregate のフィールドのみです。これらのフィールドは、他のデータセット フィールドと一緒に永続ストリームや永続ファイルに格納されます。計算フィールドの値は、自動モードでデータベースにポストすることができません。
ライブ データ ウィンドウ モードの TFDTable は、集計フィールドをサポートしていないことに注意してください。
標準計算フィールド
fkCalculated および fkInternalCalc の計算フィールドの値は、TDataSet.OnCalcFields イベント ハンドラで割り当てることができます。計算フィールドは、以下のようにして定義することができます。
- 設計時にデータセットの[フィールド エディタ...]メニュー項目を使って。
- 実行時にコードを使って。たとえば、大文字の名前を含む計算フィールドを作成するには、次のようにします:
procedure TForm1.Form1CalcFields(ADataSet: TDataSet);
begin
ADataSet.FieldByName('UName').AsString := UpperCase(ADataSet.FieldByName('Name').AsString);
end;
var
oField: TField;
i: Integer;
...
FDQuery1.FieldDefs.Updated := False;
FDQuery1.FieldDefs.Update;
for i := 0 to ADQuery1.FieldDefs.Count - 1 do
FDQuery1.FieldDefs[i].CreateField(Self);
oField := TStringField.Create(FDQuery1);
oField.Size := 50;
oField.FieldName := 'UName';
oField.FieldKind := fkInternalCalc; // or fkCalculated
oField.DataSet := FDQuery1;
FDQuery1.OnCalcFields := Form1CalcFields;
FDQuery1.Open;
式計算フィールド
fiInternalCalc フィールドは、TField.DefaultExpression で指定された式を使って自動的に計算することがdけいます。TDataSet.OnCalcFields イベント ハンドラや明示的な値の代入の必要はありません。データセットがアクティブなときに、式を変更することはできません。例:
var
oField: TField;
i: Integer;
...
FDQuery1.FieldDefs.Updated := False;
FDQuery1.FieldDefs.Update;
for i := 0 to FDQuery1.FieldDefs.Count - 1 do
FDQuery1.FieldDefs[i].CreateField(Self);
oField := TStringField.Create(FDQuery1);
oField.Size := 50;
oField.FieldName := 'UName';
oField.FieldKind := fkInternalCalc;
oField.DefaultExpression := 'UPPER(Name)';
oField.DataSet := FDQuery1;
FDQuery1.Open;
集計フィールド
fkAggregate 集計フィールドの管理は、式計算フィールドの管理と似ています。FireDAC では、TFDDataSet.AggregatesActive が True に設定されている場合に、集計フィールドが計算されます(この値はデフォルトでは、False に設定されています)。データセットがアクティブなときに、集計式を変更することはできません。 たとえば、集計フィールドを作成するには、次のようにします:
var
oField: TAggregateField;
i: Integer;
...
FDQuery1.FieldDefs.Updated := False;
FDQuery1.FieldDefs.Update;
for i := 0 to FDQuery1.FieldDefs.Count - 1 do
FDQuery1.FieldDefs[i].CreateField(Self);
oField := TAggregateField.Create(FDQuery1);
oField.FieldName := 'Total';
oField.Expression := 'SUM((ItemPrice + ItemTaxes) * ItemCount)';
oField.DataSet := FDQuery1;
FDQuery1.AggregatesActive := True;
FDQuery1.Open;
集計フィールドには、グループを定義することができます。すると、全レコードではなく、同じインデックス フィールド値を持つレコードだけの値が計算されます。グループを定義する手順は以下のとおりです:
- グループ化に使用するインデックスの名前を TAggregateField.IndexName に設定します。デフォルトでは、現在のインデックスが使用されます。
- グループ化に使用するインデックス付きフィールドの数を TAggregateField.GroupingLevel に設定します。この値は、デフォルトでは 0(フィールドがなくグループ化を行わない)に設定されています。
データセットが dsInsert 状態であれば、集計フィールドは必ず Null を返すことに注意してください。
集計値
FireDAC アプリケーションでは、TFDDataSet.Aggregates コレクションを使って集計値を定義することもできます。集計値は集計フィールドよりも軽量で、データセットがアクティブな場合も含む任意の時点で定義することができます。以下に例を示します。例:
with FDQuery1.Aggregates.Add do begin
Name := 'Total';
Expression := 'SUM((ItemPrice + ItemTaxes) * ItemCount)';
Active := True;
end;
FDQuery1.AggregatesActive := True;
...
Label1.Caption := VarToStr(FDQuery1.Aggregates[0].Value);