計算フィールドと集計フィールド(FireDAC)

提供: Appmethod Topics
移動先: 案内検索

データセットの操作(FireDAC) への移動


FireDAC には、いくつかの種類の計算フィールドが用意されています。

概要

計算フィールドは、データベースに対する値の取得や格納が行われない仮想フィールドです。そうではなく、クライアント側で計算されます。FireDAC では、以下に示す全種類の TField.FieldKind の計算フィールドをサポートしています。

  • fkCalculated -- 単純な計算フィールド。この値は、TDataSet.OnCalcFields イベント ハンドラで計算されます。
  • fkInternalCalc -- 拡張計算フィールド。値は、通常のフィールドに代入することができ、データセット レコード キャッシュに格納されます。TDataSet.OnCalcFields イベント ハンドラで計算されるか、TField.DefaultExpression に指定された式を使って計算されます。
  • fkLookup -- ルックアップ フィールド。値は自動的に計算され、ルックアップ データセット内のキー値に対するそのデータセットの値が返されます。
  • fkAggregate -- 集計計算フィールド。値は TAggregateField.Expression に指定された式(集計関数 COUNT、SUM、MIN、MAX、AVG を含みます)を使って計算されます。

フィルタリングやソートや検索の操作に使用できるのは、fkInternalCalcfkAggregate のフィールドだけです。また、これらのフィールドは、他のデータセット フィールドと一緒に永続ストリームや永続ファイルに格納されます。計算フィールドの値は、自動モードでデータベースにポストすることができません。

ライブ データ ウィンドウ モードの 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 に指定された式を使って自動的に計算することができます。その際に、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.AggregatesActiveTrue に設定されている場合に集計フィールドが計算されます(この値はデフォルトでは 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);

関連項目