Ecriture d'expressions (FireDAC)

De RAD Studio
Aller à : navigation, rechercher

Remonter à Utilisation des ensembles de données (FireDAC)


FireDAC fournit un moteur d'expressions client puissant, utilisé pour le filtrage, l'indexation et les champs calculés.

Informations générales

FireDAC supporte une syntaxe d'expression compatible avec :

  • les composants d'accès aux données BDE
  • TClientDataSet
  • Oracle 8 (pas 100 % compatible)
  • les fonctions d'échappement ODBC

Pour ajouter des fonctions d'expression de type Oracle, ODBC et régulières, vous devez inclure l'unité FireDAC.Stan.ExprFuncs dans la clause uses d'une application. Sinon, vous obtenez une erreur, comme "Impossible de trouver la colonne nommée [NVL]". Voici la liste des fonctions enregistrées :

Notez que le moteur d'expression supporte les séquences d'échappement FireDAC. Par ailleurs, les champs des ensembles de données peuvent être référencés dans une expression, en tant qu'identificateurs. Par exemple :

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

Ou

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

Si vous devez créer votre propre fonction et l'enregistrer avec FireDAC, voir l'unité FireDAC.Stan.ExprFuncs.pas pour plus de détails.

Utilisation d'une expression à des fins de personnalisation

Une application peut utiliser l'évaluateur d'expression de FireDAC pour effectuer des calculs de formule de texte. Les deux options de base sont les suivantes :

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;
  • Utilisez l'API pour étendre l'évaluateur par source de données personnalisée. Par exemple :
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;

Exemples