Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
bom dia pessoal sou aprendiz em Delphi porem to fazendo um sistema de boleto
mais esta dando o seguinte erro DecimalSeparator
o código ai em baixo .alguém sabe como resolver
grata
/applications/core/interface/imageproxy/imageproxy.php?img=http://www.uploaddeimagens.com.br/images/000/216/662/original/erro!!.jpg?1395934920&key=f055684c7f68c0b51a9614c7defc9348b4b2eaa410cf23c9a67126d4330b8250" alt="erro!!.jpg?1395934920" />
{$I QRDEFS.INC}
unit QRExpr;
{$R-}
{$T-}
{$B-}
interface
uses
Windows, Sysutils, Classes, DB, Forms, DBTables, QR5Const;
type
TQRLibraryItemClass = class of TObject;
TQRLibraryEntry = class
private
FDescription : string;
FData : string;
FItem : TQRLibraryItemClass;
FName : string;
FVendor : string;
public
property Data : string read FData write FData;
property Description : string read FDescription write FDescription;
property Name : string read FName write FName;
property Vendor : string read FVendor write FVendor;
property Item : TQRLibraryItemClass read FItem write FItem;
end;
TQRLibrary = class
protected
Entries : TStrings;
function GetEntry(Index : integer) : TQRLibraryEntry; virtual;
public
constructor Create;
destructor Destroy; override;
procedure Add(aItem : TQRLibraryItemClass; AName, ADescription, AVendor, AData : string);
property EntryList : TStrings read Entries write Entries;
property Entry[Index : integer] : TQRLibraryEntry read GetEntry;
end;
TQREvElementFunction = class;
TQREvElement = class;
TQREvEnvironment = class;
TQREvaluator = class;
TQREvOperator = (opLess, opLessOrEqual, opGreater, opGreaterOrEqual, opEqual,
opUnequal, opPlus, opMinus, opOr, opMul, opDiv, opAnd);
TQREvResultType = (resInt, resDouble, resString, resBool, resError);
TQREvResult = record
case Kind : TQREvResultType of
resInt : (intResult : longint);
resDouble : (dblResult : double);
resString : (strResult : string[255]);
resBool : (booResult : boolean);
end;
TQREvResultClass = class
public
EvResult : TQREvResult;
end;
TQRFiFo = class
private
FAggreg : boolean;
FiFo : TList;
FNextItem : integer;
public
constructor Create;
destructor Destroy; override;
procedure Put(Value : TObject);
procedure Start;
function Get : TObject;
function GetAndFree : TObject;
property Aggreg : boolean read FAggreg write FAggreg;
end;
TQREvElement = class
private
FIsAggreg : boolean;
public
constructor Create; virtual;
function Value(FiFo : TQRFiFo) : TQREvResult; virtual;
procedure Reset; virtual;
property IsAggreg : boolean read FIsAggreg write FIsAggreg;
end;
TQREvElementFunction = class(TQREvElement)
private
protected
ArgList : TList;
function ArgumentOK(Value : TQREvElement) : boolean;
function Argument(Index : integer) : TQREvResult;
procedure FreeArguments;
procedure GetArguments(FiFo : TQRFiFo);
procedure Aggregate; virtual;
function Calculate : TQREvResult; virtual;
public
constructor Create; override;
destructor Destroy; override;
function Value(FiFo : TQRFiFo) : TQREvResult; override;
end;
TQREvElementFunctionClass = class of TQREvElementFunction;
{$warnings off}
TQREvElementWrapper = class(TQREvElement)
private
FEmbeddedFunction : TQREvElement;
public
constructor Create(AEmbeddedFunction : TQREvElement);
function Value(FiFo : TQRFiFo) : TQREvResult; override;
property EmbeddedFunction : TQREvElement read FEmbeddedFunction;
end;
TQREvEmbeddedFunction = class(TQREvElement)
private
Evaluator : TQREvaluator;
FExpression : string;
FInEvaluate : boolean;
public
constructor Create(Expression : string);
destructor Destroy; override;
function Value(FiFo : TQRFiFo) : TQREvResult; override;
procedure Reset; override;
function Peek(Index : integer) : TQREvElement;
function Expression : string;
end;
{$warnings on}
TQREvElementArgumentEnd = class(TQREvElement);
TQREvElementDataField = class(TQREvElement)
private
FDataSet : TDataSet;
FFieldNo : integer;
FField : TField;
public
constructor CreateField(aField : TField); virtual;
function Value(FiFo : TQRFiFo) : TQREvResult; override;
end;
{$warnings off}
TQREvElementError = class(TQREvElement)
private
FErrorMessage : string;
public
constructor Create(ErrorMessage : string);
function Value(FiFo : TQRFiFo) : TQREvResult; override;
end;
{$warnings on}
{ TQREvaluator }
TQREvaluator = class (TObject)
private
OwnDataSets : TList;
FDataSets : TList;
FiFo : TQRFiFo;
FPrepared : boolean;
FEnvironment : TQREvEnvironment;
function EvalEnvironment(strVariable : string) : TQREvResult;
function EvalFunctionExpr(const strFunc : string) : TQREvResult;
function EvalSimpleExpr(const strSimplExpr : string) : TQREvResult;
function EvalTerm(const strTermExpr : string) : TQREvResult;
function EvalFactor(strFactorExpr : string) : TQREvResult;
function EvalString(const strString : string) : TQREvResult;
function EvalConstant(const strConstant : string) : TQREvResult;
function GetAggregate : boolean;
function Evaluate(const strExpr : string) : TQREvResult;
procedure FindDelimiter(strArg : string; var Pos : integer);
procedure SetAggregate(Value : boolean);
procedure TrimString(var strString : string);
protected
function EvalFunction(strFunc : string; const strArg : string) : TQREvResult; virtual;
function EvalVariable(strVariable : string) : TQREvResult; virtual;
function GetIsAggreg : boolean;
function GetDatasets : TList;
procedure SetDatasets(Value : TList);
public
constructor Create;
destructor Destroy; override;
function Calculate(const StrExpr : string) : TQREvResult;
function Value : TQREvResult;
function AsString : string;
function AsInteger : integer;
function AsFloat : extended;
function AsBoolean : boolean;
function AsVariant : Variant;
procedure Prepare(const StrExpr : string);
procedure Reset;
procedure UnPrepare;
procedure DoAggregate;
property Environment : TQREvEnvironment read FEnvironment write FEnvironment;
property IsAggreg : boolean read GetIsAggreg;
property Aggregate : boolean read GetAggregate write SetAggregate;
property DataSets : TList read GetDatasets write SetDataSets;
property Prepared : boolean read FPrepared write FPrepared;
end;
{ TQREvEnvironment }
TQREvEnvironment = class(TStringList)
private
PrepareCount : integer;
OwnDataSets : TList;
FDatasets : TList;
protected
procedure DefineProperties(Filer : TFiler); override;
procedure ReadProperties(Reader : TReader);
procedure WriteProperties(Writer : TWriter);
function GetDatasets : TList;
procedure SetDatasets(Value : TList);
public
constructor Create;
destructor Destroy; override;
procedure AddFunction(AName, AExpression : string);
procedure Clear; override;
procedure DeleteFunction(AName : string);
procedure Update;
procedure Prepare;
procedure UpdateConstant(Name : string; Value : TQREvResult);
procedure SetConstant(Constant : TQREvElement; Value : TQREvResult);
procedure SetStringConstant(Constant : TQREvElement; Value : string);
procedure SetIntegerConstant(Constant : TQREvElement; Value : integer);
procedure SetFloatConstant(Constant : TQREvElement; Value : double);
procedure SetBooleanConstant(Constant : TQREvElement; Value : boolean);
procedure Unprepare;
function Prepared : boolean;
function Value(Name : string) : TQREvResult;
function Element(Name : string) : TQREvElement;
function GetConstant(Name : string) : TQREvElement;
property Datasets : TList read GetDatasets write SetDatasets;
end;
{ TQRFunctionLibrary }
TQRFunctionLibrary = class(TQRLibrary)
public
function GetFunction(Name : string) : TQREvElement;
end;
procedure UpdateConstant(AConstant : TQREvElement; Value : TQREvResult);
procedure RegisterQRFunction(FunctionClass : TQRLibraryItemClass; Name, Description, Vendor, Arguments : string);
function QREvResultToString(const AValue : TQREvResult) : string;
function QREvResultToInt(const AValue : TQREvResult) : integer;
function QREvResultToFloat(const AValue : TQREvResult) : extended;
function QREvResultToVariant(const AValue : TQREvResult) : Variant;
function QRGlobalEnvironment : TQREvEnvironment;
var
QRFunctionLibrary : TQRFunctionLibrary;
implementation
//uses CustomFunc;
var
ArgSeparator : Char;
FGlobalEnvironment : TQREvEnvironment;
UnpreparingGlobalEnvironment : boolean; { should be moved to interface section }
function QREvResultToString(const AValue : TQREvResult) : string; resString : Result := AValue.StrResult;
resInt : Result := IntToStr(AValue.IntResult);
resDouble : Result := FloatToStr(AValue.DblResult);
resBool : if AValue.booResult then
Result := SqrTrue
else
Result := SqrFalse;
else
Raise Exception.Create(Format(SqrExpError, [AValue.strResult]));
end;
end;
function QREvResultToInt(const AValue : TQREvResult) : integer; resInt : Result := AValue.IntResult;
resDouble : Result := Round(AValue.DblResult);
else
Raise Exception.Create(Format(SqrNotValue, [SqrExpNumeric]));
end;
end;
function QREvResultToFloat(const AValue : TQREvResult) : extended; resInt : Result := AValue.IntResult;
resDouble : Result := AValue.DblResult;
else
Raise Exception.Create(Format(SqrNotValue, [SqrExpNumeric]));
end;
end;
function QREvResultToBoolean(const AValue : TQREvResult) : boolean; resBool : Result := AValue.BooResult;
resString : if AnsiUppercase(AValue.StrResult) = 'TRUE' then // Do not translate
Result := true
else
if AnsiUppercase(AValue.StrResult) = 'FALSE' then // Do not translate
Result := false
else
Raise Exception.Create(Format(SqrNotValue, [SqrExpBoolean]));
else
Raise Exception.Create(Format(SqrNotValue, [SqrExpBoolean]));
end;
end;
function QREvResultToVariant(const AValue : TQREvResult) : Variant; resString : Result := AValue.StrResult;
resInt : Result := AValue.IntResult;
resDouble : Result := AValue.dblResult;
resBool : Result := AValue.BooResult;
else
Raise Exception.Create(Format(SqrExpError, [AValue.StrResult]));
end;
end;
function QRGlobalEnvironment : TQREvEnvironment; Result := FGlobalEnvironment;
end;
{ TQRLibrary }
constructor TQRLibrary.Create;
begin
inherited Create;
Entries := TStringList.Create;
end;
destructor TQRLibrary.Destroy; Entries.Objects[I].Free;
Entries.Free;
inherited Destroy;
end;
procedure TQRLibrary.Add(aItem : TQRLibraryItemClass; AName, ADescription, AVendor, AData : string); aLibraryEntry := TQRLibraryEntry.Create;
with aLibraryEntry do
begin
Name := AName;
Description := ADescription;
Vendor := AVendor;
Data := AData;
Item := aItem;
end;
Entries.AddObject(aName,aLibraryEntry);
end;
function TQRLibrary.GetEntry(Index : integer) : TQRLibraryEntry; result := nil;
end;
{ TQRFunctionLibrary }
function TQRFunctionLibrary.GetFunction(Name : string) : TQREvElement;
var
I : integer;
AObject : TQREvElementFunctionClass;
aLibraryEntry : TQRLibraryEntry; I := Entries.IndexOf(Name);
if I >= 0 then
begin
aLibraryEntry := TQRLibraryEntry(Entry[I]);
aObject := TQREvElementFunctionClass(aLibraryEntry.Item);
result := aObject.Create;
end else
result := TQREvElementError.Create(Format(SqrExpUnknownFunction, [Name]));
end;
{ TQREvaluator }
constructor TQRFiFo.Create;
begin
FiFo := TList.Create;
FAggreg := false;
FNextItem := 0;
end;
destructor TQRFiFo.Destroy; TObject(FiFo[I]).Free;
FiFo.Free;
inherited Destroy;
end;
procedure TQRFiFo.Start; FNextItem := 0;
end;
procedure TQRFiFo.Put(Value : TObject); FiFo.Add(Value);
end;
function TQRFiFo.GetAndFree : TObject; result := FiFo[0];
FiFo.Delete(0);
end else
result := nil;
end;
function TQRFiFo.Get : TObject; result := FiFo[FNextItem];
inc(FNextItem);
end else
result := nil;
end;
{ TQREvElement }
constructor TQREvElement.Create;
begin
inherited Create;
FIsAggreg := false;
end;
function TQREvElement.Value(FiFo : TQRFiFo) : TQREvResult;end;
procedure TQREvElement.Reset;{ TQREvElementOperator }
type
TQREvElementOperator = class(TQREvElement)
private
FOpCode : TQREvOperator;
procedure ConverTQREvResults(var Res1 : TQREvResult; var Res2 : TQREvResult);
public
constructor CreateOperator(OpCode : TQREvOperator);
function Value(FiFo : TQRFiFo) : TQREvResult; override;
end;
function ErrorCreate(Value : string) : TQREvResult; Result.Kind := resError;
Result.strResult := Value;
end;
constructor TQREvElementOperator.CreateOperator(OpCode : TQREvOperator); inherited Create;
FOpCode := OpCode;
end;
procedure TQREvElementOperator.ConverTQREvResults(var Res1 : TQREvResult; var Res2 : TQREvResult); Res1.Kind := resDouble;
Res1.dblResult := Res1.intResult;
end else
if ((Res1.Kind = resDouble) and (Res2.Kind = resInt)) then
begin
Res2.Kind := resDouble;
Res2.dblResult := Res2.intResult;
end else
begin
Res1.StrResult := QREvResultToString(Res1);
Res1.Kind := resString;
Res2.StrResult := QREvResultToString(Res2);
Res2.Kind := resString;
end;
end
end;
function TQREvElementOperator.Value(FiFo : TQRFiFo) : TQREvResult; Res1 := TQREvElement(FiFo.Get).Value(FiFo);
Res2 := TQREvElement(FiFo.Get).Value(FiFo);
ConverTQREvResults(Res1, Res2);
Result.Kind := Res1.Kind;
if Res2.Kind = resError then
Result.Kind := res2.Kind;
if result.Kind <> resError then
case FOpCode of
opPlus: case result.Kind of
resInt: result.intResult := Res1.intResult + Res2.intResult;
resDouble: result.dblResult := Res1.dblResult + Res2.dblResult;
resString: result.strResult := Res1.strResult + Res2.strResult;
resBool: result := ErrorCreate(Format(SqrExpCannotOperator, [SqrExpAdd, SqrExpBoolean]));
end;
opMinus: case result.Kind of
resInt: result.intResult := Res1.intResult - Res2.intResult;
resDouble: result.dblResult := Res1.dblResult - Res2.dblResult;
resString: result := ErrorCreate(Format(SqrExpCannotOperator, [SqrExpSubtract, SqrExpString]));
resBool: result := ErrorCreate(Format(SqrExpCannotOperator, [SqrExpSubtract, SqrExpBoolean]));
end;
opMul: case result.Kind of
resInt: result.intResult := Res1.intResult * Res2.intResult;
resDouble: result.dblResult := Res1.dblResult * Res2.dblResult;
resString: result := ErrorCreate(Format(SqrExpCannotOperator, [SqrExpMultiply, SqrExpString]));
resBool: result := ErrorCreate(Format(SqrExpCannotOperator, [SqrExpMultiply, SqrExpBoolean]));
end;
opDiv: case result.Kind of
resInt: if Res2.intResult <> 0 then
begin
result.dblResult := Res1.intResult / Res2.intResult;
result.Kind := resDouble;
end else
result := ErrorCreate(SqrExpDivideByZero);
resDouble: if Res2.dblResult <> 0 then
result.dblResult := Res1.dblResult / Res2.dblResult
else
result := ErrorCreate(SqrExpDivideByZero);
resString: result := ErrorCreate(Format(SqrExpCannotOperator, [SqrExpDivide, SqrExpString]));
resBool: result := ErrorCreate(Format(SqrExpCannotOperator, [SqrExpDivide, SqrExpBoolean]));
end;
opGreater: begin
result.Kind := resBool;
case Res1.Kind of
resInt: result.booResult := Res1.intResult > Res2.intResult;
resDouble: result.booResult := Res1.dblResult > Res2.dblResult;
resString: result.booResult := Res1.strResult > Res2.strResult;
resBool: result := ErrorCreate(Format(SqrExpOperatorNotCompatible, ['>', SqrExpBoolean]));
end;
end;
opGreaterOrEqual: begin
result.Kind := resBool;
case Res1.Kind of
resInt: result.booResult := Res1.intResult >= Res2.intResult;
resDouble: result.booResult := Res1.dblResult >= Res2.dblResult;
resString: result.booResult := Res1.strResult >= Res2.strResult;
resBool: result := ErrorCreate(Format(SqrExpOperatorNotCompatible, ['>=', SqrExpBoolean]));
end;
end;
opLess: begin
result.Kind := resBool;
case Res1.Kind of
resInt: result.booResult := Res1.intResult < Res2.intResult;
resDouble: result.booResult := Res1.dblResult < Res2.dblResult;
resString: result.booResult := Res1.strResult < Res2.strResult;
resBool: result := ErrorCreate(Format(SqrExpOperatorNotCompatible, ['<', SqrExpBoolean]));
end;
end;
opLessOrEqual: begin
result.Kind := resBool;
case Res1.Kind of
resInt: result.booResult := Res1.intResult <= Res2.intResult;
resDouble: result.booResult := Res1.dblResult <= Res2.dblResult;
resString: result.booResult := Res1.strResult <= Res2.strResult;
resBool: result := ErrorCreate(Format(SqrExpOperatorNotCompatible, ['<=', SqrExpBoolean]));
end;
end;
opEqual: begin
result.Kind := resBool;
case Res1.Kind of
resInt: result.booResult := Res1.intResult = Res2.intResult;
resDouble: result.booResult := Res1.dblResult = Res2.dblResult;
resString: result.booResult := Res1.strResult = Res2.strResult;
resBool: result.booResult := Res1.booResult = Res2.booResult;
end;
end;
opUnequal: begin
result.Kind := resBool;
case Res1.Kind of
resInt: result.booResult := Res1.intResult <> Res2.intResult;
resDouble: result.booResult := Res1.dblResult <> Res2.dblResult;
resString: result.booResult := Res1.strResult <> Res2.strResult;
resBool: result.booResult := Res1.booResult <> Res2.booResult;
end;
end;
opOr: begin
result.Kind := Res1.Kind;
case Res1.Kind of
resInt: result.intResult := Res1.intResult or Res2.intResult;
resDouble: result := ErrorCreate(Format(SqrExpOperatorNotCompatible, ['OR', SqrExpNumeric]));
resString: Result := ErrorCreate(Format(SqrExpOperatorNotCompatible, ['OR', SqrExpString]));
resBool: result.booResult := Res1.booResult or Res2.booResult;
end;
end;
opAnd: begin
result.Kind := Res1.Kind;
case Res1.Kind of
resInt: result.intResult := Res1.intResult and Res2.intResult;
resDouble: result := ErrorCreate(Format(SqrExpOperatorNotCompatible, ['AND', SqrExpNumeric]));
resString: Result := ErrorCreate(Format(SqrExpOperatorNotCompatible, ['AND', SqrExpString]));
resBool: result.booResult := Res1.booResult and Res2.booResult;
end;
end;
end else
if Res1.Kind = resError then
Result := Res1
else
Result := Res2;
end;
{ TQREvElementConstant }
type
TQREvElementConstant = class(TQREvElement)
private
FValue : TQREvResult;
public
constructor CreateConstant(Value : TQREvResult);
function Value(FiFo : TQRFiFo) : TQREvResult; override;
end;
constructor TQREvElementConstant.CreateConstant(Value : TQREvresult); inherited Create;
FValue := Value;
end;
function TQREvElementConstant.Value(FiFo : TQRFiFo): TQREvResult; Result := FValue;
end;
{ TQREvElementString }
type
TQREvElementString = class(TQREvElement)
private
FValue : string;
public
constructor CreateString(Value : string);
function Value(FiFo : TQRFiFo) : TQREvResult; override;
end;
constructor TQREvElementString.CreateString(Value : string); inherited Create;
FValue := Value;
end;
function TQREvElementString.Value(FiFo : TQRFiFo) : TQREvResult; result.Kind := resString;
result.StrResult := FValue;
end;
{ TQREvElementFunction }
constructor TQREvElementFunction.Create;
begin
inherited Create;
ArgList := TList.Create;
end;
destructor TQREvElementFunction.Destroy; ArgList.Free;
inherited Destroy;
end;
procedure TQREvElementFunction.GetArguments(FiFo : TQRFiFo); aArgument : TQREvElement;
AResult : TQREvResultClass; aArgument := TQREvElement(FiFo.Get);
if not (aArgument is TQREvElementArgumentEnd) then
begin
aResult := TQREvResultClass.Create;
aResult.EvResult := aArgument.Value(FiFo);
ArgList.Add(aResult);
end;
until aArgument is TQREvElementArgumentEnd;
end;
procedure TQREvElementFunction.FreeArguments; TQREvElement(ArgList.Items[I]).Free;
ArgList.Clear;
end;
function TQREvElementFunction.Argument(Index : integer): TQREvResult; Result := TQREvResultClass(ArgList[Index]).EvResult;
end;
function TQREvElementFunction.Value(FiFo : TQRFiFo) : TQREvResult; GetArguments(FiFo);
if FiFo.Aggreg then
Aggregate;
Result := Calculate;
FreeArguments;
end;
function TQREvElementFunction.ArgumentOK(Value : TQREvElement) : boolean; Result := not (Value is TQREvElementArgumentEnd) and not (Value is TQREvElementError);
end;
procedure TQREvElementFunction.Aggregate;end;
function TQREvElementFunction.Calculate : TQREvResult; Result.Kind := resError;
end;
{ TQREvElementDataField }
constructor TQREvElementDataField.CreateField(aField : TField);
begin
inherited Create;
FDataSet := aField.DataSet;
FFieldNo := aField.Index;
FField := aField;
end;
function TQREvElementDataField.Value(FiFo : TQRFiFo) : TQREvResult; FField := FDataSet.Fields[FFieldNo];
if FField is TStringField then
begin
result.Kind := resString;
result.strResult := TStringField(FField).Value;
end
else if (FField is TIntegerField) or
(FField is TSmallIntField) or
(FField is TLargeIntField) or
(FField is TWordField) then
begin
result.Kind := resInt;
result.intResult := FField.AsInteger;
end
// numeric fields
else if (FField is TBCDField) or
(FField is TFMTBCDField) then
begin
result.Kind := resDouble;
result.dblResult := TNumericField(FField).AsFloat;
end
else if (FField is TFloatField) or
(FField is TCurrencyField) or
(FField.DataType = ftFMTbcd) then
begin
result.Kind := resDouble;
result.dblResult := TFloatField(FField).AsFloat;
end
else if FField is TBooleanField then
begin
result.Kind := resBool;
result.BooResult := TBooleanField(FField).Value;
end
else if (FField is TDateField) or (FField.DataType = ftTimestamp) then
begin
result.Kind := resString;
result.strResult := TDateField(FField).AsString;
end
else if FField is TDateTimeField then
begin
result.Kind := resString;
result.strResult := TDateField(FField).AsString;
end
else
result := ErrorCreate(Format(SqrExpUnknownFieldType, [FField.FieldName]));
end;
constructor TQREvElementError.Create(ErrorMessage : string); FErrorMessage := ErrorMessage;
end;
function TQREvElementError.Value(FiFo : TQRFiFo) : TQREvResult; Result.Kind := resError;
Result.strResult := FErrorMessage;
end;
function Flip(aString : string; a, b : char) : string; ParLevel : integer;
isString : boolean;
I : integer;
aChar : string; ParLevel := 0;
isString := False;
I := 1;
while I <= Length(aString) do
begin
aChar := aString[I];
if aChar = '''' then
isString := not IsString
else
if not isString then
begin
if aChar = '(' then
inc(ParLevel)
else
if aChar = ')' then
dec(parLevel)
else
if ParLevel = 0 then
if aChar = a then
aString[I] := b
else
if aChar = b then
aString[I] := a;
end;
inc(i);
end;
result := aString;
end;
{ TQREvaluator }
constructor TQREvaluator.Create;
begin
Prepared := false;
Environment := nil;
FDatasets := nil;
OwnDatasets := nil;
end;
destructor TQREvaluator.Destroy; if Prepared then Unprepare;
if (FDatasets <> nil) and (FDataSets = OwnDatasets) then
FDatasets.Free;
inherited Destroy;
end;
procedure TQREvaluator.SetDatasets(Value : TList); FDatasets.Free;
FDatasets := Value;
end;
function TQREvaluator.GetDatasets : TList; FDatasets := TList.Create;
OwnDatasets := FDatasets;
end;
Result := FDatasets;
end;
procedure TQREvaluator.TrimString(var strString : string); intStart := 1;
intEnd := Length(strString);
while (strString[intStart] = ' ') and (intStart < intEnd) do
inc(intStart);
while (strString[intEnd] = ' ') and (intEnd > intStart) do
dec(intEnd);
strString := Copy(strString, intStart, intEnd - intStart + 1);
end;
procedure TQREvaluator.FindDelimiter(strArg : string; var Pos : integer); n : integer;
FoundDelim : boolean;
booString : boolean;
intParenteses : integer; FoundDelim := false;
BooString := false;
intParenteses := 0;
N := 1;
while (N<length(strArg)) and not FoundDelim do
begin
case StrArg[N] of
'(' : if not booString then inc(intParenteses);
')' : if not booString then dec(intParenteses);
'''' : booString := not booString;
end;
if (intParenteses=0) and not booString then
if strArg[N]=ArgSeparator then
begin
FoundDelim := true;
break;
end;
inc(N);
end;
if FoundDelim then
Pos := N
else
Pos := 0;
end;
end;
function TQREvaluator.EvalEnvironment(strVariable : string) : TQREvResult; AElement := FEnvironment.Element(strVariable);
if AElement is TQREvElementError then
begin
AElement.Free;
AElement := FGlobalEnvironment.Element(strVariable);
end
end else
AElement := FGlobalEnvironment.Element(strVariable);
FiFo.Put(AElement);
end;
function TQREvaluator.EvalVariable(strVariable : string) : TQREvResult; SeparatorPos : integer;
DSName : string;
FieldName : string;
aDataSet : TDataSet;
aField : TField;
I : integer; SeparatorPos := AnsiPos('.', strVariable);
DSName := AnsiUpperCase(copy(StrVariable, 1, SeparatorPos - 1));
FieldName := AnsiUpperCase(copy(strVariable, SeparatorPos + 1, length(StrVariable) - SeparatorPos));
aField := nil;
aDataSet := nil;
if length(DSName) > 0 then
begin
for I := 0 to FDataSets.Count - 1 do
if AnsiUpperCase(TDataSet(FDataSets[I]).Name) = DSName then
begin
aDataSet := TDataSet(FDataSets[I]);
break;
end;
if aDataSet<>nil then
aField := aDataSet.FindField(FieldName);
end else
begin
for I := 0 to FDataSets.Count - 1 do
with TDataSet(FDataSets[I]) do
begin
aField := FindField(FieldName);
if aField <> nil then break;
end;
end;
if aField <> nil then
FiFo.Put(TQREvElementDataField.CreateField(aField))
else
EvalEnvironment(strVariable);
end else
EvalEnvironment(strVariable);
end;
function TQREvaluator.EvalString(const strString : string) : TQREvResult; result.Kind := resString;
result.strResult := strString;
FiFo.Put(TQREvElementString.CreateString(Result.StrResult));
end;
function TQREvaluator.EvalFunction(strFunc : string; const strArg : string) : TQREvResult; DelimPos : integer;
aString : string;
Res : TQREvResult;
aFunc : TQREvElement; StrFunc := AnsiUpperCase(StrFunc);
aFunc := QRFunctionLibrary.GetFunction(strFunc);
if AFunc is TQREvElementError then
begin
if StrArg = '' then
begin
AFunc.Free;
EvalVariable(StrFunc)
end else
FiFo.Put(AFunc);
end else
begin
FiFo.Put(AFunc);
if not (aFunc is TQREvElementError) then
begin
aString := strArg;
repeat
FindDelimiter(aString, DelimPos);
if DelimPos > 0 then
Res := Evaluate(copy(aString, 1, DelimPos - 1))
else
if length(aString) > 0 then Res := Evaluate(aString);
Delete(aString, 1, DelimPos);
until DelimPos = 0;
end;
FiFo.Put(TQREvElementArgumentEnd.Create);
end;
end;
function TQREvaluator.EvalConstant(const strConstant : string) : TQREvResult; N : integer;
aString : string; N := 1;
aString := strConstant;
while (N <= Length(aString)) and (aString[N] in ['0'..'9']) do
inc(N);
result.Kind := resInt;
while ((N <= Length(aString)) and (aString[N] in ['0'..'9', '.', 'e', 'E', '+', '-'])) do
begin
inc(N);
result.Kind := resDouble;
end;
if N - 1 <> Length(aString) then
result := ErrorCreate(Format(SqrExpIllegalCharInNumeric, [aString]))
else
begin
if result.Kind = resInt then
begin
try
result.intResult := StrToInt(aString)
except
result.Kind := resDouble;
end;
end;
if result.Kind = resDouble then
begin
if DecimalSeparator <> '.' then
begin
while pos('.', aString) > 0 do
aString[pos('.', aString)] := DecimalSeparator;
end;
try
result.dblResult := StrToFloat(aString);
except
result := ErrorCreate(Format(SqrExpIllegalCharInNumeric, [aString]))
end;
end;
end;
if result.Kind = resError then
FiFo.Put(TQREvElementError.Create(Result.strResult))
else
FiFo.Put(TQREvElementConstant.CreateConstant(Result));
end;
function TQREvaluator.EvalFunctionExpr(const strFunc : string) : TQREvResult; argRes : TQREvResult;
po : integer; po := AnsiPos('(', StrFunc);
if po > 0 then
begin
if strFunc[length(StrFunc)] = ')' then
begin
result := EvalFunction(copy(StrFunc, 1, po - 1), copy(StrFunc, po + 1, length(strFunc) - po - 1));
end else
begin
// Result := ErrorCreate(Format(SqrExpMissing, [')']));
// argRes.Kind := resError;
result := EvalFunction('', '');
end;
end else
begin
argRes.Kind := resError;
result := EvalFunction(StrFunc, '');
end;
end;
function TQREvaluator.EvalFactor(strFactorExpr : string) : TQREvResult; aString : string[255];
aResult : TQREvResult; TrimString(strFactorExpr);
aString := strFactorExpr;
if (AnsiLowerCase(Copy(strFactorExpr, 1, 3)) = 'not') then
begin
aResult := EvalSimpleExpr(Copy(strFactorExpr, 4, Length(strFactorExpr)));
if aResult.Kind = resBool then
begin
Result.booResult := not aResult.booResult;
Result.Kind := aResult.Kind;
end else
Result := ErrorCreate(SqrInvalidNot);
end else
case aString[1] of
'(' : if strFactorExpr[Length(strFactorExpr)] = ')' then
result := Evaluate(Copy(strFactorExpr, 2, Length(strFactorExpr) - 2))
else
begin
result := ErrorCreate(Format(SqrExpMissing, [')']));
FiFo.Put(TQREvElementError.Create(Result.strResult));
end;
'-' : result := EvalSimpleExpr('0-' + Copy(strFactorExpr, 2, Length(strFactorExpr)));
'+' : result := EvalFactor(Copy(strFactorExpr, 2, Length(strFactorExpr)));
'0'..'9' : result := EvalConstant(strFactorExpr);
'''' : if aString[Length(strFactorExpr)] = '''' then
result := EvalString(Copy(strFactorExpr, 2, Length(strFactorExpr) - 2))
else
begin
Result := ErrorCreate(Format(SqrExpMissing, [')']));
FiFo.Put(TQREvElementError.Create(Result.strResult));
end; Result := ErrorCreate(Format(SqrExpMissing, [']']));
FiFo.Put(TQREvElementError.Create(Result.strResult));
end;
'A'..'Z', 'a'..'z' : result := EvalFunctionExpr(strFactorExpr);
else
begin
result := ErrorCreate(Format(SqrExpError, [aString]));
FiFo.Put(TQREvElementError.Create(Result.strResult));
end;
end;
end;
function TQREvaluator.EvalSimpleExpr(const strSimplExpr : string) : TQREvResult; Op : TQREvOperator;
intStart,
intLen : integer;
Res1,
Res2 : TQREvResult;
n : integer;
intParenteses : integer;
booFound : boolean;
booString : boolean;
booBracket : boolean; n := 1;
Op := TQREvOperator(nil);
intParenteses := 0;
booFound := false;
booString := false;
booBracket := false;
intLen := 1;
while (n < Length(strSimplExpr)) and (not booFound) do
begin
booFound := true;
case strSimplExpr[N] of
'(' : if not (booString or booBracket) then inc(intParenteses);
')' : if not (booString or booBracket) then dec(intParenteses);
'[' : if not (booString or booBracket) then booBracket := true;
']' : if (not booString) and booBracket then booBracket := false;
'''': if (not booBracket) then booString := not booString;
end;
if (intParenteses = 0) and (not (booString or booBracket)) and (N > 1) then
case strSimplExpr[N] of
'+' : Op := opPlus;
'-' : Op := opMinus;
' ' : if (AnsiLowercase(copy(strSimplExpr, N + 1, 3)) = 'or ') then
begin
Op := opOr;
intLen := 2;
inc(N);
end else
booFound := false;
else
booFound := false;
end else
booFound := false;
inc(N);
end;
if booFound then
intStart := N - 1
else
intStart := -1;
if intStart > 0 then
begin
FiFo.Put(TQREvElementOperator.CreateOperator(Op));
Res1 := EvalTerm(Copy(strSimplExpr, 1, intStart - 1));
if Op = opMinus then
Res2 := EvalSimpleExpr(Flip(Copy(strSimplExpr, intStart + intLen, Length(strSimplExpr)), '+', '-'))
else
Res2 :=EvalSimpleExpr(Copy(strSimplExpr, intStart + intLen, Length(strSimplExpr)))
end else
result := EvalTerm(strSimplExpr);
end;
function TQREvaluator.EvalTerm(const strTermExpr : string) : TQREvResult; Op : TQREvOperator;
intStart,
intLen : integer;
Res1,
Res2 : TQREvResult;
N : integer;
booString : boolean;
booFound : boolean;
booBracket : boolean;
intParenteses : integer; n := 1;
Op := TQREvOperator(nil);
intParenteses := 0;
booFound := false;
booString := false;
booBracket := false;
intLen := 1;
while (N < Length(strTermExpr)) and (not booFound) do
begin
booFound := true;
case strTermExpr[N] of
'(' : if not (booString or booBracket) then inc(intParenteses);
')' : if not (booString or booBracket) then dec(intParenteses);
'[' : if not (booString or booBracket) then booBracket := true;
']' : if (not booString) and booBracket then booBracket := false;
'''': if (not booBracket) then booString := not booString;
end;
if (intParenteses = 0) and (not (booString or booBracket)) and (N > 1) then
begin
case strTermExpr[N] of
'*' : Op := opMul;
'/' : Op := opDiv;
' ' : if (AnsiLowercase(copy(strTermExpr, n + 1, 4)) = 'and ') then
begin
Op := opAnd;
IntLen := 3;
inc(N);
end else
booFound := false;
else
booFound := false;
end;
end else
booFound := false;
inc(N);
end;
if booFound then
intStart := N - 1
else
intStart := -1;
if intStart > 0 then
begin
FiFo.Put(TQREvElementOperator.CreateOperator(Op));
Res1 := EvalFactor(Copy(strTermExpr, 1, intStart - 1));
if Op = opDiv then
Res2 := EvalTerm(Flip(Copy(strTermExpr, intStart + intLen, Length(strTermExpr)), '*', '/'))
else
Res2 := EvalTerm(Copy(strTermExpr, intStart + intLen, Length(strTermExpr)));
end else
result := EvalFactor(strTermExpr);
end;
function TQREvaluator.Evaluate(const strExpr : string) : TQREvResult; n : integer;
booFound : boolean;
intParenteses : integer;
booString : boolean;
booBracket : boolean;
Op : TQREvOperator;
intStart,
intLen : integer;
Res1,
Res2 : TQREvResult; Op := OpEqual;
n := 1;
intParenteses := 0;
booFound := false;
intLen := 1;
booString := false;
booBracket := false;
while (n < Length(strExpr)) and (not booFound) do
begin
booFound := true;
case StrExpr[N] of
'(' : if not (booString or booBracket) then inc(intParenteses);
')' : if not (booString or booBracket) then dec(intParenteses);
'[' : if not (booString or booBracket) then booBracket := true;
']' : if (not booString ) and booBracket then booBracket := false;
'''': if (not booBracket) then booString := not booString;
end;
if (intParenteses = 0) and (n > 1) and not (booString or booBracket) then
case StrExpr[N] of
'<' : begin
if StrExpr[N + 1] = '>' then
begin
Op := opUnequal;
intLen := 2;
end else
if StrExpr[N + 1] = '=' then
begin
Op := opLessOrEqual;
intLen := 2;
end else
Op := opLess;
end;
'>' : if StrExpr[N + 1] = '=' then
begin
Op := opGreaterOrEqual;
intLen := 2;
end else
Op := opGreater;
'=' : Op := opEqual;
else
booFound := false;
end
else
booFound := false;
inc(N);
end;
if booFound then
IntStart := n - 1
else
IntStart := -1;
if intStart > 0 then
begin
FiFo.Put(TQREvElementOperator.CreateOperator(Op));
Res1 := EvalSimpleExpr(Copy(strExpr, 1, intStart - 1));
Res2 := EvalSimpleExpr(Copy(strExpr, intStart + intLen, Length(strExpr)));
end else
result := EvalSimpleExpr(strExpr);
end;
procedure TQREvaluator.Prepare(const strExpr : string); if Prepared then Unprepare;
QRGlobalEnvironment.Prepare;
FiFo := TQRFiFo.Create;
if strExpr = '' then
Value := Evaluate(''' ''')
else
Value := Evaluate(strExpr);
Prepared := true;
end;
procedure TQREvaluator.UnPrepare; //FiFo.Free;
FreeAndNil(FiFo);
QRGlobalEnvironment.Unprepare;
Prepared := false;
end;
procedure TQREvaluator.Reset; TQREvElement(FiFo.FiFo[I]).Reset;
end;
function TQREvaluator.Value : TQREvResult; Raise Exception.Create(SqrEvalNotPrepared);
if assigned(fifo) then
begin
FiFo.Start;
F := FiFo.Get;
end
else
f := nil;
if F = nil then
Result.Kind := resError
else
Result := TQREvElement(F).Value(FiFo);
end;
procedure TQREvaluator.DoAggregate; Aggregate := true;
Value;
Aggregate := false;
end;
function TQREvaluator.AsString : string; AValue := Value;
case AValue.Kind of
resString : Result := AValue.StrResult;
resInt : Result := IntToStr(AValue.IntResult);
resDouble : Result := FloatToStr(AValue.DblResult);
resBool : if AValue.booResult then
Result := SqrTrue
else
Result := SqrFalse;
else
Raise Exception.Create(Format(SqrExpError, [AValue.strResult]));
end;
end;
function TQREvaluator.AsInteger : integer; AValue := Value;
case AValue.Kind of
resInt : Result := AValue.IntResult;
resDouble : Result := Round(AValue.DblResult);
else
Raise Exception.Create(Format(SqrNotValue, [SqrExpNumeric]));
end;
end;
function TQREvaluator.AsFloat : extended; AValue := Value;
case AValue.Kind of
resInt : Result := AValue.IntResult;
resDouble : Result := AValue.DblResult;
else
Raise Exception.Create(Format(SqrNotValue, [SqrExpNumeric]));
end;
end;
function TQREvaluator.AsBoolean : boolean; AValue := Value;
case AValue.Kind of
resBool : Result := AValue.BooResult;
resString : if AnsiUppercase(AValue.StrResult) = 'TRUE' then // Do not translate
Result := true
else
if AnsiUppercase(AValue.StrResult) = 'FALSE' then // Do not translate
Result := false
else
Raise Exception.Create(Format(SqrNotValue, [SqrExpBoolean]));
else
Raise Exception.Create(Format(SqrNotValue, [SqrExpBoolean]));
end;
end;
function TQREvaluator.AsVariant : Variant; AValue := Value;
case AValue.Kind of
resString : Result := AValue.StrResult;
resInt : Result := AValue.IntResult;
resDouble : Result := AValue.dblResult;
resBool : Result := AValue.BooResult;
else
Raise Exception.Create(Format(SqrExpError, [AValue.StrResult]));
end;
end;
function TQREvaluator.GetIsAggreg : boolean; Result := false;
for I := 0 to FiFo.FiFo.Count - 1 do
Result := Result or TQREvElement(FiFo.FiFo[I]).IsAggreg;
end;
function TQREvaluator.GetAggregate : boolean; Result := FiFo.Aggreg;
end;
procedure TQREvaluator.SetAggregate(Value : boolean); FiFo.Aggreg := Value;
end;
function TQREvaluator.Calculate(const strExpr : string) : TQREvResult; Prepare(strExpr);
result := Value;
UnPrepare;
end;
{ Expression evaluator functions }
{ TQREvTrue }
type
TQREvTrue = class(TQREvElementFunction)
public
function Calculate : TQREvResult; override;
end;
TQREvFalse = class(TQREvElementFunction)
public
function Calculate : TQREvResult; override;
end;
function TQREvTrue.Calculate : TQREvResult; Result.Kind := resBool;
Result.booResult := true;
end else
Result := ErrorCreate(SqrExpTooManyArgs);
end;
function TQREvFalse.Calculate : TQREvResult; Result.Kind := resBool;
Result.booResult := false;
end else
Result := ErrorCreate(SqrExpTooManyArgs);
end;
{ TQREvIfFunction }
type
TQREvIfFunction = class(TQREvElementFunction)
public
function Calculate : TQREvResult; override;
end;
function TQREvIfFunction.Calculate : TQREvResult; Result := Argument(2);
end else
Result := ErrorCreate(Format(SqrExpWrongArguments, ['IF'])); // Do not translate
end;
{ TQREvTypeOfFunction }
type
TQREvTypeOfFunction = class(TQREvElementFunction)
public
function Calculate : TQREvResult; override;
end;
function TQREvTypeOfFunction.Calculate : TQREvResult; Result.Kind := resString;
if ArgList.Count = 1 then
begin
case Argument(0).Kind of
resInt : Result.StrResult := 'INTEGER'; // Do not translate
resDouble : Result.StrResult := 'FLOAT'; // Do not translate
resString : Result.StrResult := 'STRING'; // Do not translate
resBool : Result.StrResult := 'BOOLEAN'; // Do not translate
resError : Result.StrResult := 'ERROR'; // Do not translate
else
Result := ErrorCreate(SqrExpUnknownType);
end
end else
Result := ErrorCreate(Format(SqrExpWrongArguments, ['TypeOf'])); // Do not translate
end;
{ TQREvIntFunction }
type
TQREvIntFunction = class(TQREvElementFunction)
public
function Calculate : TQREvResult; override;
end;
function TQREvIntFunction.Calculate : TQREvResult; Result.Kind := resInt;
if ArgList.Count = 1 then
begin
case Argument(0).Kind of
resInt : Result.IntResult := Argument(0).IntResult;
resDouble : Result.IntResult := Round(Int(Argument(0).DblResult));
else
Result := ErrorCreate(Format(SqrExpWrongArguments, ['INT'])); // Do not translate
end
end else
Result := ErrorCreate(Format(SqrExpWrongArguments, ['INT'])); // Do not translate
end;
{ TQREvFracFunction }
type
TQREvFracFunction = class(TQREvElementFunction)
public
function Calculate : TQREvResult; override;
end;
function TQREvFracFunction.Calculate : TQREvResult; Result.Kind := resDouble;
if ArgList.Count = 1 then
begin
case Argument(0).Kind of
resInt : Result.DblResult := 0;
resDouble : Result.DblResult := Frac(Argument(0).DblResult);
else
Result.Kind := resError;
end
end else
Result.Kind := resError;
end;
{ TQREvSQRTFunction }
type
TQREvSQRTFunction = class(TQREvElementFunction)
public
function Calculate : TQREvResult; override;
end;
function TQREvSQRTFunction.Calculate : TQREvResult; Result.Kind := resDouble;
if ArgList.Count = 1 then
begin
try
case Argument(0).Kind of
resInt : Result.DblResult := SQRT(Argument(0).IntResult);
resDouble : Result.DblResult := SQRT(Argument(0).DblResult);
else
Result.Kind := resError;
end
except
Result.Kind := resError
end;
end else
Result.Kind := resError;
if Result.Kind = resError then
Result.StrResult := SqrSQRTInvalid;
end;
type
TQREvDivFunction = class(TQREvElementFunction)
public
function Calculate : TQREvResult; override;
end;
function TQREvDivFunction.Calculate : TQREvResult; Result.Kind := ResInt;
if Argument(0).Kind = ResInt then
v1 := Argument(0).intResult
else
v1 := Round(Argument(0).dblResult);
if Argument(1).Kind = ResInt then
v2 := Argument(1).intResult
else
v2 := Round(Argument(1).dblResult);
if v2 <> 0 then
Result.IntResult := v1 div v2
else
begin
Result.Kind := resError;
Result.strResult := SqrDivisionByZero;
end
end else
begin
Result.Kind := resError;
Result.StrResult := Format(SqrExpWrongArguments, ['DIV']);
end;
end;
{ TQREvStrFunction }
type
TQREvStrFunction = class(TQREvElementFunction)
public
function Calculate : TQREvResult; override;
end;
function TQREvStrFunction.Calculate : TQREvResult; ArgRes := Argument(0);
Result.Kind := resString;
case ArgRes.Kind of
resInt : Result.strResult := IntToStr(ArgRes.IntResult);
resDouble : Result.strResult := FloatToStr(ArgRes.DblResult);
resBool : if ArgRes.booResult then
result.StrResult := 'True' // Do not translate
else
result.StrResult := 'False'; // Do not translate
else
result.Kind := resError;
end
end else
Result.Kind := resError;
if Result.Kind = resError then
Result.strResult := SqrConversionError;
end;
{ TQREvUpperFunction }
type
TQREvUpperFunction = class(TQREvElementFunction)
public
function Calculate : TQREvResult; override;
end;
function TQREvUpperFunction.Calculate : TQREvResult; Result.Kind := resString;
Result.StrResult := AnsiUpperCase(Argument(0).StrResult);
end else
begin
Result.Kind := resError;
if ArgList.Count = 1 then
Result.strResult :=Argument(0).strResult
else
Result.strResult := Format(SqrMissingArgument, ['UPPER']);
end;
end;
{ TQREvLowerFunction }
type
TQREvLowerFunction = class(TQREvElementFunction)
public
function Calculate : TQREvResult; override;
end;
function TQREvLowerFunction.Calculate : TQREvResult; Result.Kind := resString;
Result.StrResult := AnsiLowerCase(Argument(0).StrResult);
end else
begin
Result.Kind := resError;
if ArgList.Count = 1 then
Result.strResult :=Argument(0).strResult
else
Result.strResult := Format(SqrMissingArgument, ['LOWER']);
end;
end;
{ TQREvUpperFunction }
type
TQREvPrettyFunction = class(TQREvElementFunction)
public
function Calculate : TQREvResult; override;
end;
function TQREvPrettyFunction.Calculate : TQREvResult; Result.Kind := resString;
if (Length(Argument(0).StrResult) > 0) and (Argument(0).StrResult[1] in LeadBytes) then
Result.StrResult := AnsiUpperCase(Copy(Argument(0).StrResult, 1, 2)) +
AnsiLowerCase(Copy(Argument(0).StrResult, 3, length(Argument(0).StrResult)))
else
Result.StrResult := AnsiUpperCase(Copy(Argument(0).StrResult, 1, 1)) +
AnsiLowerCase(Copy(Argument(0).StrResult, 2, length(Argument(0).StrResult)));
end else
begin
Result.Kind := resError;
if ArgList.Count = 1 then
Result.strResult :=Argument(0).strResult
else
Result.strResult := Format(SqrMissingArgument, ['PRETTY']);
end;
end;
{ TQREvTimeFunction }
type
TQREvTimeFunction = class(TQREvElementFunction)
public
function Calculate : TQREvResult; override;
end;
function TQREvTimeFunction.Calculate : TQREvResult; Result.Kind := resString;
Result.StrResult := TimeToStr(Now);
end else
Result.Kind := resError;
end;
{ TQREvTimeFunction }
type
TQREvDateFunction = class(TQREvElementFunction)
public
function Calculate : TQREvResult; override;
end;
function TQREvDateFunction.Calculate : TQREvResult; Result.Kind := resString;
Result.StrResult := DateToStr(Date);
end else
Result.Kind := resError;
end;
{ TQREvCopyFunction }
type
TQREvCopyFunction = class(TQREvElementFunction)
public
function Calculate : TQREvResult; override;
end;
function TQREvCopyFunction.Calculate : TQREvResult; Start := Argument(1).IntResult;
Len := Argument(2).IntResult;
if (Start = 0) then Start := 1;
if (ByteType(Argument(0).strResult, Start) = mbTrailByte) and (Len > 0) then
begin
Inc(Start);
Dec(Len);
end;
if (ByteType(Argument(0).strResult, Start + Len - 1) = mbLeadByte) and (Len > 0) then Dec(Len);
Result.StrResult := copy(Argument(0).strResult, Start, Len);
Result.Kind := resString;
end else
Result.Kind := resError;
end;
{ TQREvFormatNumericFunction }
type
TQREvFormatNumericFunction = class(TQREvElementFunction)
public
function Calculate : TQREvResult; override;
end;
function TQREvFormatNumericFunction.Calculate : TQREvResult; Result.Kind := resString;
try
if Argument(1).Kind = resInt then
Result.StrResult := FormatFloat(Argument(0).StrResult, Argument(1).IntResult * 1.0)
else
Result.StrResult := FormatFloat(Argument(0).StrResult, Argument(1).DblResult);
except
Result.Kind := resError;
Result.StrResult := SqrInvalidFormatnumeric;
end;
end else
Result.Kind := resError;
end;
{ TQREvSumFunction }
type
TQREvSumFunction = class(TQREvElementFunction)
private
SumResult : TQREvResult;
ResAssigned : boolean;
public
constructor Create; override;
procedure Aggregate; override;
function Calculate : TQREvResult; override;
procedure Reset; override;
end;
constructor TQREvSumFunction.Create; inherited Create;
ResAssigned := false;
IsAggreg := true;
end;
procedure TQREvSumFunction.Reset; ResAssigned := false;
end;
procedure TQREvSumFunction.Aggregate; aValue := Argument(0);
if ResAssigned then
begin
case aValue.Kind of
resInt : SumResult.IntResult := SumResult.IntResult + aValue.IntResult;
resDouble : SumResult.dblResult := SumResult.dblResult + aValue.dblResult;
resString : SumResult.Kind := resError;
end;
end else
begin
SumResult.Kind := aValue.Kind;
case aValue.Kind of
resInt : SumResult.IntResult := aValue.IntResult;
resDouble : SumResult.dblResult := aValue.dblResult;
else
SumResult.Kind := resError;
end;
end;
ResAssigned := true;
end else
SumResult.Kind := resError;
end;
function TQREvSumFunction.Calculate : TQREvResult; Result.Kind := resInt;
Result.intResult := 0;
end;
end;
{ TQREvAverageFunction }
type
TQREvAverageFunction = class(TQREvSumFunction)
private
Count : longint;
aResult : TQREvResult;
public
function Calculate : TQREvResult; override;
procedure Aggregate; override;
procedure Reset; override;
end;
procedure TQREvAverageFunction.Reset; inherited Reset;
aResult.Kind := resDouble;
aResult.dblResult := 0;
Count := 0;
IsAggreg := true;
end;
procedure TQREvAverageFunction.Aggregate; inherited Aggregate;
inc(Count);
aValue := inherited Calculate;
aResult.Kind := resDouble;
case aValue.Kind of
ResInt : aResult.DblResult := aValue.IntResult / Count;
ResDouble : aResult.DblResult := aValue.DblResult / Count;
else
aResult.Kind := resError;
end;
end;
function TQREvAverageFunction.Calculate : TQREvResult;{ TQREvMaxFunction }
type
TQREvMaxFunction = class(TQREvElementFunction)
private
MaxResult : TQREvResult;
ResAssigned : boolean;
public
constructor Create; override;
function Calculate : TQREvResult; override;
procedure Aggregate; override;
procedure Reset; override;
end;
constructor TQREvMaxFunction.Create; inherited Create;
ResAssigned := false;
IsAggreg := true;
end;
procedure TQREvMaxFunction.Reset; ResAssigned := false;
end;
procedure TQREvMaxFunction.Aggregate; aValue := Argument(0);
if ResAssigned then
begin
case MaxResult.Kind of
resInt : if aValue.IntResult > MaxResult.IntResult then
MaxResult.IntResult := aValue.IntResult;
resDouble : if aValue.DblResult > MaxResult.DblResult then
MaxResult.DblResult := aValue.DblResult;
resString : if aValue.StrResult > MaxResult.StrResult then
MaxResult.StrResult := aValue.StrResult;
resBool : if aValue.booResult > MaxResult.BooResult then
MaxResult.BooResult := aValue.BooResult;
else
MaxResult.Kind := resError;
end
end else
begin
MaxResult := aValue;
ResAssigned := true;
end
end else
MaxResult.Kind := resError;
end;
function TQREvMaxFunction.Calculate : TQREvResult; Result.Kind := resInt;
Result.IntResult := 0;
end;
end;
{ TQREvMinFunction }
type
TQREvMinFunction = class(TQREvElementFunction)
private
MinResult : TQREvResult;
ResAssigned : boolean;
public
constructor Create; override;
function Calculate : TQREvResult; override;
procedure Aggregate; override;
procedure Reset; override;
end;
constructor TQREvMinFunction.Create; inherited Create;
ResAssigned := false;
IsAggreg := true;
end;
procedure TQREvMinFunction.Reset; ResAssigned := false;
end;
procedure TQREvMinFunction.Aggregate; aValue := Argument(0);
if ResAssigned then
begin
case MinResult.Kind of
resInt : if aValue.IntResult < MinResult.IntResult then
MinResult.IntResult := aValue.IntResult;
resDouble : if aValue.DblResult < MinResult.DblResult then
MinResult.DblResult := aValue.DblResult;
resString : if aValue.StrResult < MinResult.StrResult then
MinResult.StrResult := aValue.StrResult;
resBool : if aValue.booResult > MinResult.BooResult then
MinResult.BooResult := aValue.BooResult;
else
MinResult.Kind := resError;
end
end else
begin
MinResult := aValue;
ResAssigned := true;
end
end else
MinResult.Kind := resError;
end;
function TQREvMinFunction.Calculate : TQREvResult; Result.Kind := resInt;
Result.IntResult := 0;
end;
end;
{ TQREvCountFunction }
type
TQREvCountFunction = class(TQREvElementFunction)
private
FCount : integer;
public
constructor Create; override;
function Value(FiFo : TQRFiFo) : TQREvResult; override;
procedure Reset; override;
end;
constructor TQREvCountFunction.Create; inherited Create;
FCount := 0;
IsAggreg := true;
end;
function TQREvCountFunction.Value(FiFo : TQRFiFo) : TQREvResult; GetArguments(FiFo);
if (ArgList.Count = 0) then
begin
if FiFo.Aggreg then
inc(FCount);
Result.Kind := resInt;
Result.intResult := FCount;
end else
Result := ErrorCreate('COUNT - ' + SqrExpTooManyARgs);
FreeArguments;
end;
procedure TQREvCountFunction.Reset; FCount := 0;
end;
constructor TQREvElementWrapper.Create(AEmbeddedFunction : TQREvElement); inherited Create;
FEmbeddedFunction := AEmbeddedFunction;
end;
function TQREvElementWrapper.Value(FiFo : TQRFifo) : TQREvResult; Result := FEmbeddedFunction.Value(FiFo);
end;
constructor TQREvEmbeddedFunction.Create(Expression : string); inherited Create;
FExpression := Expression;
Evaluator := TQREvaluator.Create;
FInEvaluate := false;
end;
destructor TQREvEmbeddedFunction.Destroy; Evaluator.Free;
inherited Destroy;
end;
function TQREvEmbeddedFunction.Value(FiFo : TQRFiFo) : TQREvResult; FInEvaluate := true;
Result := Evaluator.Value;
FInEvaluate := false;
end else
Result := ErrorCreate(SqrExpRecursive);
end;
procedure TQREvEmbeddedFunction.Reset; Evaluator.Reset;
end;
function TQREvEmbeddedFunction.Expression : string; Result := FExpression;
end;
function TQREvEmbeddedFunction.Peek(Index : integer) : TQREvElement; Result := nil;
end;
constructor TQREvEnvironment.Create; inherited Create;
PrepareCount := 0;
FDatasets := nil;
OwnDatasets := nil;
end;
destructor TQREvEnvironment.Destroy; FDatasets.Free;
Clear;
inherited Destroy;
end;
procedure TQREvEnvironment.Clear; AObject : TObject;
I : integer; AObject := Objects[I];
Delete(I);
AObject.Free;
end;
end;
inherited Clear;
end;
procedure TQREvEnvironment.DefineProperties(Filer : TFiler); inherited DefineProperties(Filer);
Filer.DefineProperty('DATA', ReadProperties, WriteProperties, True);
end;
procedure TQREvEnvironment.WriteProperties(Writer : TWriter); Writer.WriteListBegin;
for I := 0 to Count - 1 do
Writer.WriteString(TQREvEmbeddedFunction(Objects[I]).Expression);
Writer.WriteListEnd;
end;
procedure TQREvEnvironment.ReadProperties(Reader : TReader); I : integer;
AString : string; I := 0;
Reader.ReadListBegin;
while not Reader.EndOfList do
begin
AString := Reader.ReadString;
objects[I].Free;
Objects[I] := TQREvEmbeddedFunction.Create(AString);
inc(I);
end;
Reader.ReadListEnd;
end;
procedure TQREvEnvironment.Prepare; inc(PrepareCount);
if PrepareCount = 1 then
for I := 0 to Count - 1 do
with TQREvEmbeddedFunction(Objects[I]) do
begin
Evaluator.Datasets := Self.Datasets;
Evaluator.Environment := self;
Evaluator.Prepare(Expression);
end;
end;
procedure TQREvEnvironment.SetDatasets(Value : TList); FDatasets.Free;
FDatasets := Value;
end;
function TQREvEnvironment.GetDatasets : TList; FDatasets := TList.Create;
OwnDatasets := FDatasets;
end;
Result := FDatasets;
end;
procedure TQREvEnvironment.Unprepare; UnpreparingGlobalEnvironment := true;
dec(PrepareCount);
if PrepareCount = 0 then
for I := 0 to Count - 1 do
TQREvEmbeddedFunction(Objects[I]).Evaluator.Unprepare;
UnpreparingGlobalEnvironment := false;
end;
end;
function TQREVEnvironment.Prepared : boolean; Result := PrepareCount > 0;
end;
procedure TQREvEnvironment.AddFunction(AName, AExpression : string); AName := AnsiUppercase(AName);
if IndexOf(AName) = -1 then
AddObject(AName, TQREvEmbeddedFunction.Create(AExpression));
if Prepared then with TQREvEmbeddedFunction(Objects[Count - 1]) do
begin
Evaluator.Datasets := Self.Datasets; Evaluator.Environment := self;
Evaluator.Prepare(Expression);
end;
end;
function TQREvEnvironment.GetConstant(Name : string) : TQREvElement; AWrapper := Element(Name);
try
if AWrapper is TQREvElementError then
Result := nil
else
Result := TQREvEmbeddedFunction(TQREvElementWrapper(AWrapper).EmbeddedFunction).Peek(0);
finally
AWrapper.Free;
end;
end;
procedure TQREvEnvironment.UpdateConstant(Name : string; Value : TQREvResult); Element := GetConstant(Name);
SetConstant(Element, Value);
end;
procedure TQREvEnvironment.SetStringConstant(Constant : TQREvElement; Value : string); TQREvElementString(Constant).FValue := Value;
end;
procedure TQREvEnvironment.SetIntegerConstant(Constant : TQREvElement; Value : integer); AResult.Kind := ResInt;
AResult.IntResult := Value;
TQREvElementConstant(Constant).FValue := AResult;
end;
end;
procedure TQREvEnvironment.SetFloatConstant(Constant : TQREvElement; Value : Double); AResult.Kind := ResDouble;
AResult.dblResult := Value;
TQREvElementConstant(Constant).FValue := AResult;
end;
end;
procedure TQREvEnvironment.SetBooleanConstant(Constant : TQREvElement; Value : boolean); AResult.Kind := ResBool;
AResult.BooResult := Value;
TQREvElementConstant(Constant).FValue := AResult;
end;
end;
procedure TQREvEnvironment.SetConstant(Constant : TQREvElement; Value : TQREvResult); TQREvElementString(Constant).FValue := Value.StrResult;
end;
procedure TQREvEnvironment.DeleteFunction(AName : string); I := IndexOf(AName);
if (I <> -1) then begin
Objects[ I ].Free;
Delete( I );
end;
end;
procedure TQREvEnvironment.Update;end;
function TQREvEnvironment.Value(Name : string) : TQREvResult; Index := IndexOf(AnsiUppercase(Name));
if Index <> -1 then
Result := TQREvElement(Objects[Index]).Value(nil)
else
Result.Kind := resError;
end;
function TQREvEnvironment.Element(Name : string) : TQREvElement; Index := IndexOf(AnsiUppercase(Name));
if Index <> -1 then
Result := TQREvElementWrapper.Create(TQREvElement(Objects[Index]))
else
Result := TQREvElementError.Create(Format(SqrExpUnknownFunction, [Name]));
end;
procedure UpdateConstant(AConstant : TQREvElement; Value : TQREvResult); TQREvElementString(AConstant).FValue := Value.StrResult;
end;
procedure RegisterQRFunction(FunctionClass : TQRLibraryItemClass; Name, Description, Vendor, Arguments : string); QRFunctionLibrary.Add(FunctionClass, Name, Description, Vendor, Arguments);
end;
initialization
UnpreparingGlobalEnvironment := false;
ArgSeparator := ',';
{ Register QREvaluator functions }
QRFunctionLibrary := TQRFunctionLibrary.Create;
// custom function
//RegisterQRFunction(TQREvCustomFunction,'Custom', 'Custom( V1, ..)' + 'Custom Function', SqrQuSoft, '5BVV');
RegisterQRFunction(TQREvIfFunction,'IF', 'IF(<Exp>, <X>, <Y>)|' + SqrIfDesc, SqrQuSoft, '5BVV');
RegisterQRFunction(TQREvStrFunction, 'STR', 'STR(<X>)|' + SqrStrDesc, SqrQuSoft, '7N');
RegisterQRFunction(TQREvUpperFunction, 'UPPER', 'UPPER(<X>)|' + SqrUpperDesc, SqrQuSoft, '7S');
RegisterQRFunction(TQREvLowerFunction, 'LOWER', 'LOWER(<X>)|' + SqrLowerDesc, SqrQuSoft, '7S');
RegisterQRFunction(TQREvPrettyFunction, 'PRETTY', 'PRETTY(<X>)|' + SqrPrettyDesc, SqrQuSoft, '7S');
RegisterQRFunction(TQREvTimeFunction, 'TIME', 'TIME|' + SqrTimeDesc, SqrQuSoft, '1');
RegisterQRFunction(TQREvDateFunction, 'DATE', 'DATE|' + SqrDateDesc, SqrQuSoft, '1');
RegisterQRFunction(TQREvCopyFunction, 'COPY', 'COPY(<X>, <St>,<Len>)|' + SqrCopyDesc, SqrQuSoft, '7SNN');
RegisterQRFunction(TQREvSumFunction, 'SUM', 'SUM(<X>)|' + SqrSumDesc, SqrQuSoft, '3N');
RegisterQRFunction(TQREvCountFunction, 'COUNT', 'COUNT|'+ SqrCountDesc, SqrQuSoft, '3');
RegisterQRFunction(TQREvMaxFunction, 'MAX', 'MAX(<X>)|' + SqrMaxDesc, SqrQuSoft, '3V');
RegisterQRFunction(TQREvMinFunction, 'MIN', 'MIN(<X>)|' + SqrMinDesc, SqrQuSoft, '3V');
RegisterQRFunction(TQREvAverageFunction, 'AVERAGE', 'AVERAGE(<X>)|' + SqrAverageDesc, SqrQuSoft, '3N');
RegisterQRFunction(TQREvTrue, 'TRUE', 'TRUE|' + SqrBoolDesc, SqrQuSoft, '5');
RegisterQRFunction(TQREvFalse, 'FALSE', 'FALSE|' + SqrBoolDesc, SqrQuSoft, '5');
RegisterQRFunction(TQREvIntFunction, 'INT', 'INT(<X>)|' + SqrIntDesc, SqrQuSoft, '2N');
RegisterQRFunction(TQREvFracFunction, 'FRAC', 'FRAC(<X>)|' + SqrFracDesc, SqrQuSoft, '2N');
RegisterQRFunction(TQREvSQRTFunction, 'SQRT', 'SQRT(<X>)|' + SqrSqrtDesc, SqrQuSoft, '2N');
RegisterQRFunction(TQREvDivFunction, 'DIV', 'DIV(<X>, <Y>) | ' + SqrDivDesc, SqrQuSoft,'2NN');
RegisterQRFunction(TQREvTypeOfFunction, 'TYPEOF', 'TYPEOF(<Exp>)|' + SqrTypeofDesc, SqrQuSoft, '6N');
RegisterQRFunction(TQREvFormatNumericFunction,'FORMATNUMERIC', 'FORMATNUMERIC(<F>,<N>)|' + SqrFormatNumericDesc,
SqrQuSoft, '7SN');
FGlobalEnvironment := TQREvEnvironment.Create;
FGlobalEnvironment.AddFunction('AppStartTime', '''' + TimeToStr(Time) + '''');
FGlobalEnvironment.AddFunction('AppStartDate','''' + DateToStr(Date) + '''');
FGlobalEnvironment.AddFunction('AppName', '''' + Application.Title + '''');
finalization
QRFunctionLibrary.Free;
FGlobalEnvironment.Free;
end.
Carregando comentários...