レコードのフィルタリング(FireDAC)
データセットの操作(FireDAC) への移動
すべての FireDAC データセットに、ローカルでレコードをフィルタリングする方法が用意されています。フィルタの適用後、FireDAC ではレコードを必要としません。その代わりに、ローカル データセット キャッシュ内のレコードがフィルタリング対象になります。内部的には、FireDAC はフィルタリングしたレコードのリストを作成して保守します。そのため、レコードの量が多ければフィルタのアクティブ化に時間がかかる場合がありますが、その後のレコードのナビゲーションはフィルタリングなしの場合と同じような速さで行われます。
標準のフィルタリング
FireDAC データセットには、標準の方法でレコードをフィルタリングするためのオプションがいくつか用意されています:
- Filter プロパティを使用すると、条件式を文字列として指定することができます。Filter の値を指定した後で Filtered プロパティを True に設定すると、フィルタがアクティブ化されます。例:
FDQuery1.Filter := 'OrderID in (10150, 10151, 10152)';
FDQuery1.Filtered := True;
- OnFilterRecord イベント ハンドラを使用すると、フィルタリングを Delphi コードで実装することができます。OnFilterRecord ハンドラを指定した後で Filtered プロパティを True に設定すると、フィルタがアクティブ化されます。例:
FDQuery1.OnFilterRecord := Form1FilterRecord;
FDQuery1.Filtered := True;
procedure TForm1.Form1FilterRecord(DataSet: TDataSet; var Accept: Boolean);
var
iOrderID: Integer;
begin
iOrderID := DataSet.FieldByName('OrderID').AsInteger;
Accept := (iOrderID = 10150) or (iOrderID = 10151) or (iOrderID = 10152);
end;
値の範囲によるフィルタリング
データセットがフィールド リストを使ってソートされている場合には、アプリケーションではフィールド値の範囲によってフィルタリングを行います。データセットの内部インデックス構造が使われるため、レコードを制限するにはこれが最も効果的な方法です。
以下のメソッドでフィルタリングを制御します:
- SetRangeStart -- データセットを、範囲の最小値を設定してこれまでの値を消去できる状態にします。
- EditRangeStart -- データセットを、これまでの値を残したまま範囲の最小値を設定できる状態にします。
- SetRangeEnd -- データセットを、範囲の最大値を設定してこれまでの値を消去できる状態にします。
- EditRangeEnd -- データセットを、これまでの値を残したまま範囲の最大値を設定できる状態にします。
- ApplyRange -- 最小値と最大値を指定した後で範囲のフィルタリングをアクティブ化します。
- SetRange -- SetRangeStart、SetRangeEnd、ApplyRange を 1 つのメソッドにまとめたものです。
- CancelRange -- 範囲のフィルタリングを取り消します。
以下のプロパティでフィルタリングを制御します:
- IsRanged -- 現在の範囲フィルタリング モードを取得することができます。
- KeyExclusive -- 最小値および最大値をフィルタ対象の範囲に含めるかどうかを取得または設定します。
- KeyFieldCount -- 範囲フィルタリングで使用するインデックス フィールド数を取得または設定します。
例:
FDQuery1.IndexFieldNames := 'ORDERID;ORDERDATE';
FDQuery1.SetRangeStart;
FDQuery1.KeyExclusive := False;
FDQuery1.KeyFieldCount := 1;
FDQuery1.FieldByName('OrderID').AsInteger := 10150;
FDQuery1.SetRangeEnd;
FDQuery1.KeyExclusive := False;
FDQuery1.KeyFieldCount := 1;
FDQuery1.FieldByName('OrderID').AsInteger := 10152;
FDQuery1.ApplyRange;
レコード状態によるフィルタリング
FilterChanges プロパティを使用すると、変更状態に応じてレコードをフィルタリングすることができます。この種類のフィルタリングを使用できるのは、"キャッシュされた更新" モードの場合だけです。たとえば、修正および削除されたレコードだけを表示するには、次のようにします:
FDQuery1.FilterChanges := [rtModified, rtDeleted];
ApplyUpdates 呼び出しの処理が失敗したレコードをフィルタリングするには、FilterChanges プロパティを使用して、その値を rtHasErrors に設定します。
その他のオプション
表示するレコードを制限する方法には、他にも次のようなものがあります:
- マスタ/詳細データセット関係を使用する。
- ローカル データセット インデックスを使用してソートとフィルタリングを組み合わせる。
fkCalculated または fkLookup の種類のフィールドのフィルタリングをサポートしていません。その代りに、アプリケーションでは fkInternalCalc および fkAggregate のフィールドをフィルタリングに使用します。
TFDTable とフィルタリング
ライブ データ ウィンドウ モードの TFDTable では、次の場合にサーバー側のフィルタリング(WHERE)が使われます。
- Filter プロパティ。Filter プロパティの内容はそのまま DB に送信されることに注意してください。FireDAC エスケープ シーケンス を使用して、DBMS やローカルの式エンジンと互換性のある式を作成することができます。
- マスタ/詳細関係の詳細 TFDTable。
- TFDTable に範囲が適用されている場合。
ライブ データ ウィンドウ モードの TFDTable では、次の場合にクライアント側のフィルタリングが使われます:
- OnFilterRecord イベント。
- FilterChanges プロパティ。