式の作成(FireDAC)

提供: RAD Studio
移動先: 案内検索

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


FireDAC には強力なクライアント式エンジンが用意されていて、フィルタリングやインデックス付けや計算フィールドに使用することができます。

概要

FireDAC でサポートしている式の構文は、以下と互換性があります。

  • BDE データ アクセス コンポーネント
  • TClientDataset
  • Oracle 8(完全な互換ではありません)
  • ODBC エスケープ関数

Oracle や ODBC に似た関数や正規表現関数を追加するには、アプリケーションの uses 句に FireDAC.Stan.ExprFuncs ユニットを追加する必要があります。 追加しなければ、"Column with name [NVL] is not found"([NVL] という名前の列が見つかりません)のようなエラーが発生する可能性があります。 以下は、登録済みの関数の一覧です。

式エンジンは、FireDAC エスケープシーケンスをサポートしています。 また、データセット フィールドは、式の中で識別子と同じように参照できます。 例:

FDQuery1.Filter := 'upper(name) like ''bill%''';
FDQuery1.Filtered := True;

または:

FDQuery1.Filter := '(upper(rtrim(name)) like ''bill%'') or (upper(rtrim(name)) like ''john%'')';
FDQuery1.Filtered := True;

独自の関数を作成して FireDAC に登録する方法の詳細は、FireDAC.Stan.ExprFuncs.pas ユニットを参照してください。

独自の目的に式を使用する

アプリケーションで FireDAC 式評価モジュールを使用して、テキスト式の計算を行うことができます。 基本の方法は以下の 2 つです。

var
  oEval: IFDStanExpressionEvaluator;
...
oEval := FDMemTable1.CreateExpresison('(sal + comm) * tax / 100');
Label1.Caption := oEval.Evaluate;
...
FDMemTable1.Next;
oEval.DataSource.Position := FDMemTable1.GetRow;
Label1.Caption := oEval.Evaluate;
...
oEval := nil;
FDMemTable1.Close;
  • API を使ってカスタム データ ソースで評価モジュールを拡張する方法。 例:
uses
  FireDAC.Stan.Intf, FireDAC.Stan.Factory, FireDAC.Stan.Expr, FireDAC.Stan.ExprFuncs;

type
  TMyVariable = class (TInterfacedObject, IFDStanExpressionDataSource)
  private
    FName: String;
    FpValue: PDouble;
  protected
    function GetVarIndex(const AName: String): Integer;
    function GetVarType(AIndex: Integer): TFDDataType;
    function GetVarScope(AIndex: Integer): TFDExpressionScopeKind;
    function GetVarData(AIndex: Integer): Variant;
    ...........
  public
    constructor Create(AName: String; var AValue: Double);
  end;

{ TMyVariable }

constructor TMyVariable.Create(AName: String; var AValue: Double);
begin
  inherited Create;
  FName := AName;
  FpValue := @AValue;
end;

function TMyVariable.GetVarIndex(const AName: String): Integer;
begin
  if CompareText(AName, FName) = 0 then
    Result := 0
  else
    Result := -1;
end;

function TMyVariable.GetVarType(AIndex: Integer): TFDDataType;
begin
  if AIndex = 0 then
    Result := dtDouble
  else
    Result := dtUnknown;
end;

function TMyVariable.GetVarScope(AIndex: Integer): TFDExpressionScopeKind;
begin
  if AIndex = 0 then
    Result := ckConst
  else
    Result := ckUnknown;
end;

function TMyVariable.GetVarData(AIndex: Integer): Variant;
begin
  if AIndex = 0 then
    Result := FpValue^
  else
    Result := Null;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  d: Double;
  oDS: IFDStanExpressionDataSource;
  oParser: IFDStanExpressionParser;
  oEval: IFDStanExpressionEvaluator;
begin
  oDS := TMyVariable.Create('x', d);

  FDCreateInterface(IFDStanExpressionParser, oParser);
  oEval := oParser.Prepare(oDS, '(2*x)+cos(sin(90)+10)', [], [poDefaultExpr], '');

  d := 1.2;
  ShowMessage(oEval.Evaluate);

  d := 3.4;
  ShowMessage(oEval.Evaluate);
end;

サンプル