git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9596 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz 2025-01-22 12:02:41 +00:00
parent e7384d44ad
commit e5e12455ea
4 changed files with 169 additions and 113 deletions

View File

@ -123,7 +123,6 @@ type
FParser: TsExpressionParser; FParser: TsExpressionParser;
protected protected
procedure GetNodeValue(out AResult: TsExpressionResult); virtual; abstract; procedure GetNodeValue(out AResult: TsExpressionResult); virtual; abstract;
function HasError(out AResult: TsExpressionResult): boolean; virtual;
public public
function AsRPNItem(ANext: PRPNItem): PRPNItem; virtual; abstract; function AsRPNItem(ANext: PRPNItem): PRPNItem; virtual; abstract;
function AsString: string; virtual; abstract; function AsString: string; virtual; abstract;
@ -144,7 +143,7 @@ type
FLeft: TsExprNode; FLeft: TsExprNode;
FRight: TsExprNode; FRight: TsExprNode;
protected protected
function HasError(out AResult: TsExpressionResult): Boolean; override; function GetLeftRightValues(out ALeft, ARight, AError: TsExpressionResult): Boolean;
public public
constructor Create(AParser: TsExpressionParser; ALeft, ARight: TsExprNode); constructor Create(AParser: TsExpressionParser; ALeft, ARight: TsExprNode);
destructor Destroy; override; destructor Destroy; override;
@ -293,6 +292,8 @@ type
TsUnaryOperationExprNode = class(TsExprNode) TsUnaryOperationExprNode = class(TsExprNode)
private private
FOperand: TsExprNode; FOperand: TsExprNode;
protected
function OperandError(out AResult: TsExpressionResult): Boolean;
public public
constructor Create(AParser: TsExpressionParser; AOperand: TsExprNode); constructor Create(AParser: TsExpressionParser; AOperand: TsExprNode);
procedure Check; override; procedure Check; override;
@ -305,7 +306,7 @@ type
{ TsUPlusExprNode } { TsUPlusExprNode }
TsUPlusExprNode = class(TsUnaryOperationExprNode) TsUPlusExprNode = class(TsUnaryOperationExprNode)
protected protected
procedure GetNodeValue(out Result: TsExpressionResult); override; procedure GetNodeValue(out AResult: TsExpressionResult); override;
public public
function AsRPNItem(ANext: PRPNItem): PRPNItem; override; function AsRPNItem(ANext: PRPNItem): PRPNItem; override;
function AsString: String; override; function AsString: String; override;
@ -316,7 +317,7 @@ type
{ TsUMinusExprNode } { TsUMinusExprNode }
TsUMinusExprNode = class(TsUnaryOperationExprNode) TsUMinusExprNode = class(TsUnaryOperationExprNode)
protected protected
procedure GetNodeValue(out Result: TsExpressionResult); override; procedure GetNodeValue(out AResult: TsExpressionResult); override;
public public
function AsRPNItem(ANext: PRPNItem): PRPNItem; override; function AsRPNItem(ANext: PRPNItem): PRPNItem; override;
function AsString: String; override; function AsString: String; override;
@ -327,7 +328,7 @@ type
{ TsPercentExprNode } { TsPercentExprNode }
TsPercentExprNode = class(TsUnaryOperationExprNode) TsPercentExprNode = class(TsUnaryOperationExprNode)
protected protected
procedure GetNodeValue(out Result: TsExpressionResult); override; procedure GetNodeValue(out AResult: TsExpressionResult); override;
public public
function AsRPNItem(ANext: PRPNItem): PRPNItem; override; function AsRPNItem(ANext: PRPNItem): PRPNItem; override;
function AsString: String; override; function AsString: String; override;
@ -338,7 +339,7 @@ type
{ TsParenthesisExprNode } { TsParenthesisExprNode }
TsParenthesisExprNode = class(TsUnaryOperationExprNode) TsParenthesisExprNode = class(TsUnaryOperationExprNode)
protected protected
procedure GetNodeValue(out Result: TsExpressionResult); override; procedure GetNodeValue(out AResult: TsExpressionResult); override;
public public
function AsRPNItem(ANext: PRPNItem): PRPNItem; override; function AsRPNItem(ANext: PRPNItem): PRPNItem; override;
function AsString: String; override; function AsString: String; override;
@ -521,7 +522,7 @@ type
FArgumentNodes: TsExprArgumentArray; FArgumentNodes: TsExprArgumentArray;
FargumentParams: TsExprParameterArray; FargumentParams: TsExprParameterArray;
protected protected
procedure CalcParams; function CalcParams: TsErrorValue;
public public
constructor CreateFunction(AParser: TsExpressionParser; constructor CreateFunction(AParser: TsExpressionParser;
AID: TsExprIdentifierDef; const Args: TsExprArgumentArray); virtual; AID: TsExprIdentifierDef; const Args: TsExprArgumentArray); virtual;
@ -553,7 +554,7 @@ type
private private
FCallBack: TsExprFunctionEvent; FCallBack: TsExprFunctionEvent;
protected protected
procedure GetNodeValue(out Result: TsExpressionResult); override; procedure GetNodeValue(out AResult: TsExpressionResult); override;
public public
constructor CreateFunction(AParser: TsExpressionParser; constructor CreateFunction(AParser: TsExpressionParser;
AID: TsExprIdentifierDef; const Args: TsExprArgumentArray); override; AID: TsExprIdentifierDef; const Args: TsExprArgumentArray); override;
@ -857,6 +858,7 @@ function BuiltinIdentifiers: TsBuiltInExpressionManager;
function ArgToBoolean(Arg: TsExpressionResult): Boolean; function ArgToBoolean(Arg: TsExpressionResult): Boolean;
function ArgToCell(Arg: TsExpressionResult): PCell; function ArgToCell(Arg: TsExpressionResult): PCell;
function ArgToDateTime(Arg: TsExpressionResult): TDateTime; function ArgToDateTime(Arg: TsExpressionResult): TDateTime;
function ArgToError(Arg: TsExpressionResult): TsErrorValue;
function ArgToInt(Arg: TsExpressionResult): Integer; function ArgToInt(Arg: TsExpressionResult): Integer;
function ArgToFloat(Arg: TsExpressionResult): TsExprFloat; function ArgToFloat(Arg: TsExpressionResult): TsExprFloat;
function ArgToString(Arg: TsExpressionResult): String; function ArgToString(Arg: TsExpressionResult): String;
@ -2990,17 +2992,6 @@ procedure TsExprNode.Check;
begin begin
end; end;
function TsExprNode.HasError(out AResult: TsExpressionResult): Boolean;
begin
GetNodeValue(AResult);
if AResult.ResultType = rtError then
begin
Result := true;
AResult := ErrorResult(AResult.ResError);
end else
Result := false;
end;
function TsExprNode.Has3DLink: Boolean; function TsExprNode.Has3DLink: Boolean;
begin begin
Result := false; Result := false;
@ -3041,6 +3032,14 @@ begin
RaiseParserError(rsNoOperand, [Self.ClassName]); RaiseParserError(rsNoOperand, [Self.ClassName]);
end; end;
{ Returns in AResult the calculated value of the operand. If operand contains an
error, the function returns true and AResult contains the error result. }
function TsUnaryOperationExprNode.OperandError(out AResult: TsExpressionResult): boolean;
begin
FOperand.GetNodeValue(AResult);
Result := AResult.ResultType = rtError;
end;
procedure TsUnaryOperationExprNode.IterateNodes(AProc: TsExprNodeProc; procedure TsUnaryOperationExprNode.IterateNodes(AProc: TsExprNodeProc;
AData1, AData2: Pointer; var MustRebuildFormulas: Boolean); AData1, AData2: Pointer; var MustRebuildFormulas: Boolean);
begin begin
@ -3065,6 +3064,31 @@ begin
inherited Destroy; inherited Destroy;
end; end;
{ Calculates the node values of the FLeft and FRight nodes and returns them
in ALeft and ARight.
If one of the two results contains an error, the function returns false, and
the error result is in AError (otherwise AError is undefined). }
function TsBinaryOperationExprNode.GetLeftRightValues(out ALeft, ARight, AError: TsExpressionResult): Boolean;
begin
Result := false;
FLeft.GetNodeValue(ALeft);
if ALeft.ResultType = rtError then
begin
AError := ErrorResult(ALeft.ResError);
exit;
end;
FRight.GetNodeValue(ARight);
if ARight.ResultType = rtError then
begin
AError := ErrorResult(ARight.ResError);
exit;
end;
Result := true;
end;
function TsBinaryOperationExprNode.Has3DLink: Boolean; function TsBinaryOperationExprNode.Has3DLink: Boolean;
begin begin
Result := FLeft.Has3DLink or FRight.Has3DLink; Result := FLeft.Has3DLink or FRight.Has3DLink;
@ -3081,11 +3105,6 @@ begin
MustRebuildFormulas := MustRebuildFormulas or rebuildLeft or rebuildRight; MustRebuildFormulas := MustRebuildFormulas or rebuildLeft or rebuildRight;
end; end;
function TsBinaryOperationExprNode.HasError(out AResult: TsExpressionResult): Boolean;
begin
Result := Left.HasError(AResult) or Right.HasError(AResult);
end;
{ TsBooleanOperationExprNode } { TsBooleanOperationExprNode }
@ -3255,26 +3274,28 @@ begin
Result := '+' + TrimLeft(Operand.AsString); Result := '+' + TrimLeft(Operand.AsString);
end; end;
procedure TsUPlusExprNode.GetNodeValue(out Result: TsExpressionResult); procedure TsUPlusExprNode.GetNodeValue(out AResult: TsExpressionResult);
var var
cell: PCell; cell: PCell;
val: Extended; val: Extended;
begin begin
Operand.GetNodeValue(Result); if OperandError(AResult) then
case Result.ResultType of exit;
rtInteger, rtFloat, rtError:
case AResult.ResultType of
rtInteger, rtFloat:
exit; exit;
rtCell: rtCell:
begin begin
cell := ArgToCell(Result); cell := ArgToCell(AResult);
if cell = nil then if cell = nil then
Result := FloatResult(0.0) AResult := FloatResult(0.0)
else else
if (cell^.ContentType = cctUTF8String) then begin if (cell^.ContentType = cctUTF8String) then begin
if TryStrToFloat(cell^.UTF8StringValue, val) then if TryStrToFloat(cell^.UTF8StringValue, val) then
Result := FloatResult(val) AResult := FloatResult(val)
else else
Result := StringResult(cell^.UTF8StringValue); AResult := StringResult(cell^.UTF8StringValue);
end else end else
if cell^.ContentType = cctNumber then if cell^.ContentType = cctNumber then
begin begin
@ -3282,15 +3303,15 @@ begin
(cell^.Numbervalue >= -Integer(MaxInt)-1) and (cell^.Numbervalue >= -Integer(MaxInt)-1) and
(cell^.NumberValue <= MaxInt) (cell^.NumberValue <= MaxInt)
then then
Result := IntegerResult(trunc(cell^.NumberValue)) AResult := IntegerResult(trunc(cell^.NumberValue))
else else
Result := FloatResult(cell^.NumberValue); AResult := FloatResult(cell^.NumberValue);
end; end;
end; end;
rtEmpty: rtEmpty:
Result := FloatResult(0.0); AResult := FloatResult(0.0);
else else
Result := ErrorResult(errWrongType); AResult := ErrorResult(errWrongType);
end; end;
end; end;
@ -3315,29 +3336,29 @@ begin
Result := '-' + TrimLeft(Operand.AsString); Result := '-' + TrimLeft(Operand.AsString);
end; end;
procedure TsUMinusExprNode.GetNodeValue(out Result: TsExpressionResult); procedure TsUMinusExprNode.GetNodeValue(out AResult: TsExpressionResult);
var var
cell: PCell; cell: PCell;
val: Extended; val: Extended;
begin begin
Operand.GetNodeValue(Result); if OperandError(AResult) then
case Result.ResultType of exit;
rtError:
exit; case AResult.ResultType of
rtFloat: rtFloat:
Result := FloatResult(-Result.ResFloat); AResult := FloatResult(-AResult.ResFloat);
rtInteger: rtInteger:
Result := IntegerResult(-Result.ResInteger); AResult := IntegerResult(-AResult.ResInteger);
rtCell: rtCell:
begin begin
cell := ArgToCell(Result); cell := ArgToCell(AResult);
if cell = nil then if cell = nil then
Result := FloatResult(0.0) AResult := FloatResult(0.0)
else if (cell^.ContentType = cctUTF8String) then begin else if (cell^.ContentType = cctUTF8String) then begin
if TryStrToFloat(cell^.UTF8StringValue, val) then if TryStrToFloat(cell^.UTF8StringValue, val) then
Result := FloatResult(-val) AResult := FloatResult(-val)
else else
Result := ErrorResult(errWrongType); AResult := ErrorResult(errWrongType);
end else end else
if (cell^.ContentType = cctNumber) or (cell^.ContentType = cctDateTime) then if (cell^.ContentType = cctNumber) or (cell^.ContentType = cctDateTime) then
begin begin
@ -3345,22 +3366,22 @@ begin
(cell^.NumberValue >= -Integer(MaxInt)-1) and (cell^.NumberValue >= -Integer(MaxInt)-1) and
(cell^.NumberValue <= MaxInt) (cell^.NumberValue <= MaxInt)
then then
Result := IntegerResult(-trunc(cell^.NumberValue)) AResult := IntegerResult(-trunc(cell^.NumberValue))
else else
Result := FloatResult(-cell^.NumberValue); AResult := FloatResult(-cell^.NumberValue);
end else end else
if (cell^.ContentType = cctBool) then if (cell^.ContentType = cctBool) then
Result := ErrorResult(errWrongType); AResult := ErrorResult(errWrongType);
end; end;
rtEmpty: rtEmpty:
Result := FloatResult(0.0); AResult := FloatResult(0.0);
rtString: rtString:
if TryStrToFloat(Result.ResString, val) then if TryStrToFloat(AResult.ResString, val) then
Result := FloatResult(-val) AResult := FloatResult(-val)
else else
Result := ErrorResult(errWrongType); AResult := ErrorResult(errWrongType);
else else
Result := ErrorResult(errWrongType); AResult := ErrorResult(errWrongType);
end; end;
end; end;
@ -3394,16 +3415,16 @@ begin
RaiseParserError(rsNoPercentOperation, [ResultTypeName(Operand.NodeType), Operand.AsString]) RaiseParserError(rsNoPercentOperation, [ResultTypeName(Operand.NodeType), Operand.AsString])
end; end;
procedure TsPercentExprNode.GetNodeValue(out Result: TsExpressionResult); procedure TsPercentExprNode.GetNodeValue(out AResult: TsExpressionResult);
begin begin
Operand.GetNodeValue(Result); if OperandError(AResult) then
case Result.ResultType of exit;
rtError:
exit; case AResult.ResultType of
rtFloat, rtInteger, rtCell: rtFloat, rtInteger, rtCell:
Result := FloatResult(ArgToFloat(Result)*0.01); AResult := FloatResult(ArgToFloat(AResult)*0.01);
else else
Result := ErrorResult(errWrongType); AResult := ErrorResult(errWrongType);
end; end;
end; end;
@ -3433,9 +3454,9 @@ begin
Result := Operand.NodeType; Result := Operand.NodeType;
end; end;
procedure TsParenthesisExprNode.GetNodeValue(out Result: TsExpressionResult); procedure TsParenthesisExprNode.GetNodeValue(out AResult: TsExpressionResult);
begin begin
Result := Operand.NodeValue; FOperand.GetNodeValue(AResult);
end; end;
(* (*
@ -3505,17 +3526,9 @@ procedure TsEqualExprNode.GetNodeValue(out AResult: TsExpressionResult);
var var
LRes, RRes: TsExpressionResult; LRes, RRes: TsExpressionResult;
fL, fR: TsExprFloat; fL, fR: TsExprFloat;
err: TsErrorValue;
begin begin
Left.GetNodeValue(LRes); if not GetLeftRightValues(LRes, RRes, AResult) then
Right.GetNodeValue(RRes);
if Left.HasError(AResult) and Right.HasError(AResult) then
begin
AResult := BooleanResult(LRes.ResError = RRes.ResError);
exit;
end;
if HasError(AResult) then
exit; exit;
if IsBlank(LRes) then if IsBlank(LRes) then
@ -3580,12 +3593,9 @@ var
LRes, RRes: TsExpressionResult; LRes, RRes: TsExpressionResult;
fL, fR: TsExprFloat; fL, fR: TsExprFloat;
begin begin
if HasError(AResult) then if not GetLeftRightValues(LRes, RRes, AResult) then
exit; exit;
Left.GetNodeValue(LRes);
Right.GetNodeValue(RRes);
if IsBlank(LRes) or IsBlank(RRes) then if IsBlank(LRes) or IsBlank(RRes) then
AResult := BooleanResult(false) AResult := BooleanResult(false)
else else
@ -3623,7 +3633,7 @@ var
LRes, RRes: TsExpressionResult; LRes, RRes: TsExpressionResult;
fL, fR: TsExprFloat; fL, fR: TsExprFloat;
begin begin
if HasError(AResult) then if not GetLeftRightValues(LRes, RRes, AResult) then
exit; exit;
Left.GetNodeValue(LRes); Left.GetNodeValue(LRes);
@ -3666,7 +3676,7 @@ var
LRes, RRes: TsExpressionResult; LRes, RRes: TsExpressionResult;
fL, fR: TsExprFloat; fL, fR: TsExprFloat;
begin begin
if HasError(AResult) then if not GetLeftRightValues(LRes, RRes, AResult) then
exit; exit;
Left.GetNodeValue(LRes); Left.GetNodeValue(LRes);
@ -3710,7 +3720,7 @@ var
LRes, RRes: TsExpressionResult; LRes, RRes: TsExpressionResult;
fL, fR: TsExprFloat; fL, fR: TsExprFloat;
begin begin
if HasError(AResult) then if not GetLeftRightValues(LRes, RRes, AResult) then
exit; exit;
Left.GetNodeValue(LRes); Left.GetNodeValue(LRes);
@ -3752,7 +3762,7 @@ procedure TsConcatExprNode.GetNodeValue(out AResult: TsExpressionResult);
var var
LRes, RRes : TsExpressionResult; LRes, RRes : TsExpressionResult;
begin begin
if HasError(AResult) then if not GetLeftRightValues(LRes, RRes, AResult) then
exit; exit;
Left.GetNodeValue(LRes); Left.GetNodeValue(LRes);
@ -3796,10 +3806,9 @@ var
LRes, RRes: TsExpressionResult; LRes, RRes: TsExpressionResult;
fL, fR: TsExprFloat; fL, fR: TsExprFloat;
begin begin
{ if not GetLeftRightValues(LRes, RRes, AResult) then
if HasError(AResult) then
exit; exit;
}
Left.GetNodeValue(LRes); Left.GetNodeValue(LRes);
Right.GetNodeValue(RRes); Right.GetNodeValue(RRes);
@ -3833,10 +3842,9 @@ var
lRes, RRes: TsExpressionResult; lRes, RRes: TsExpressionResult;
fL, fR: TsExprFloat; fL, fR: TsExprFloat;
begin begin
{ if not GetLeftRightValues(LRes, RRes, AResult) then
if HasError(AResult) then
exit; exit;
}
Left.GetNodeValue(LRes); Left.GetNodeValue(LRes);
Right.GetNodeValue(RRes); Right.GetNodeValue(RRes);
@ -3870,10 +3878,9 @@ var
LRes, RRes: TsExpressionResult; LRes, RRes: TsExpressionResult;
fL, fR: TsExprFloat; fL, fR: TsExprFloat;
begin begin
{ if not GetLeftRightValues(LRes, RRes, AResult) then
if HasError(AResult) then
exit; exit;
}
Left.GetNodeValue(LRes); Left.GetNodeValue(LRes);
Right.GetNodeValue(RRes); Right.GetNodeValue(RRes);
fL := ArgToFloat(LRes); fL := ArgToFloat(LRes);
@ -3910,10 +3917,9 @@ var
LRes, RRes: TsExpressionResult; LRes, RRes: TsExpressionResult;
fL, fR: TsExprFloat; fL, fR: TsExprFloat;
begin begin
{ if not GetLeftRightValues(LRes, RRes, AResult) then
if HasError(AResult) then
exit; exit;
}
Left.GetNodeValue(LRes); Left.GetNodeValue(LRes);
Right.GetNodeValue(RRes); Right.GetNodeValue(RRes);
@ -3959,10 +3965,9 @@ var
LRes, RRes: TsExpressionResult; LRes, RRes: TsExpressionResult;
fL, fR: TsExprFloat; fL, fR: TsExprFloat;
begin begin
{ if not GetLeftRightValues(LRes, RRes, AResult) then
if HasError(AResult) then
exit; exit;
}
Left.GetNodeValue(LRes); Left.GetNodeValue(LRes);
Right.GetNodeValue(RRes); Right.GetNodeValue(RRes);
fL := ArgToFloat(LRes); fL := ArgToFloat(LRes);
@ -4129,13 +4134,21 @@ begin
Result := FID.Name + S; Result := FID.Name + S;
end; end;
procedure TsFunctionExprNode.CalcParams; function TsFunctionExprNode.CalcParams: TsErrorValue;
var var
i : Integer; i : Integer;
begin begin
for i := 0 to Length(FArgumentParams)-1 do for i := 0 to Length(FArgumentParams)-1 do
if FArgumentNodes[i] <> nil then if FArgumentNodes[i] <> nil then
begin
FArgumentNodes[i].GetNodeValue(FArgumentParams[i]); FArgumentNodes[i].GetNodeValue(FArgumentParams[i]);
if FArgumentParams[i].ResultType = rtError then
begin
Result := FArgumentParams[i].ResError;
exit;
end;
end;
Result := errOK;
end; end;
procedure TsFunctionExprNode.Check; procedure TsFunctionExprNode.Check;
@ -4206,11 +4219,20 @@ begin
end; end;
procedure TsFunctionCallBackExprNode.GetNodeValue(out AResult: TsExpressionResult); procedure TsFunctionCallBackExprNode.GetNodeValue(out AResult: TsExpressionResult);
var
err: TsErrorValue = errOK;
begin begin
AResult.ResultType := NodeType; AResult.ResultType := NodeType;
if Length(FArgumentParams) > 0 then if Length(FArgumentParams) > 0 then
CalcParams; begin
FCallBack(AResult, FArgumentParams); err := CalcParams;
if err <> errOK then
begin
AResult := ErrorResult(err);
exit;
end;
end;
FCallBack(AResult, FArgumentParams)
end; end;
@ -4223,12 +4245,21 @@ begin
FCallBack := AID.OnGetFunctionValue; FCallBack := AID.OnGetFunctionValue;
end; end;
procedure TFPFunctionEventHandlerExprNode.GetNodeValue(out Result: TsExpressionResult); procedure TFPFunctionEventHandlerExprNode.GetNodeValue(out AResult: TsExpressionResult);
var
err: TsErrorValue = errOK;
begin begin
Result.ResultType := NodeType; AResult.ResultType := NodeType;
if Length(FArgumentParams) > 0 then if Length(FArgumentParams) > 0 then
CalcParams; begin
FCallBack(Result, FArgumentParams); err := CalcParams;
if err <> errOK then
begin
AResult := ErrorResult(err);
exit;
end;
end;
FCallBack(AResult, FArgumentParams)
end; end;
@ -4356,8 +4387,7 @@ var
sheet: TsWorksheet; sheet: TsWorksheet;
begin begin
if FError <> errOK then begin if FError <> errOK then begin
AResult.ResultType := rtError; AResult := ErrorResult(FError);
AResult.ResError := FError;
exit; exit;
end; end;
@ -4378,6 +4408,11 @@ begin
csCalculating: csCalculating:
raise ECalcEngine.CreateFmt(rsCircularReference, [GetCellString(cell^.Row, cell^.Col)]); raise ECalcEngine.CreateFmt(rsCircularReference, [GetCellString(cell^.Row, cell^.Col)]);
end; end;
if cell^.ContentType = cctError then
begin
AResult := ErrorResult(cell^.ErrorValue);
exit;
end;
end; end;
AResult.ResultType := rtCell; AResult.ResultType := rtCell;
@ -4651,8 +4686,7 @@ var
formula: PsFormula; formula: PsFormula;
begin begin
if FError <> errOK then begin if FError <> errOK then begin
AResult.ResultType := rtError; AResult := ErrorResult(FError);
AResult.ResError := FError;
exit; exit;
end; end;
@ -4893,6 +4927,22 @@ begin
end; end;
end; end;
function ArgToError(Arg: TsExpressionResult): TsErrorValue;
var
cell: PCell;
begin
Result := errOK;
if Arg.ResultType = rtError then
Result := Arg.ResError
else
if Arg.ResultType = rtCell then
begin
cell := ArgToCell(Arg);
if Assigned(cell) and (cell^.ContentType = cctError) then
Result := cell^.ErrorValue;
end;
end;
function ArgToString(Arg: TsExpressionResult): String; function ArgToString(Arg: TsExpressionResult): String;
// The Office applications are very fuzzy about data types... // The Office applications are very fuzzy about data types...
var var

View File

@ -2720,6 +2720,7 @@ begin
case Args[0].ResultType of case Args[0].ResultType of
rtCell : Result := CellResult(ArgToString(Args[0])); rtCell : Result := CellResult(ArgToString(Args[0]));
rtString : Result := CellResult(Args[0].ResString); rtString : Result := CellResult(Args[0].ResString);
rtError : Result := ErrorResult(Args[0].ResError);
end; end;
(* (*
if Length(Args) = 0 then if Length(Args) = 0 then
@ -2842,7 +2843,7 @@ begin
cell := ArgToCell(Args[0]); cell := ArgToCell(Args[0]);
if cell = nil then if cell = nil then
begin begin
Result := ErrorResult(errWrongType); Result := ErrorResult(errArgError);
exit; exit;
end; end;
case cell^.ContentType of case cell^.ContentType of
@ -2850,8 +2851,8 @@ begin
cctNumber: numSearchValue := cell^.NumberValue; cctNumber: numSearchValue := cell^.NumberValue;
cctDateTime: numSearchValue := cell^.DateTimeValue; cctDateTime: numSearchValue := cell^.DateTimeValue;
cctBool: numSearchValue := ord(cell^.BoolValue); cctBool: numSearchValue := ord(cell^.BoolValue);
cctEmpty: begin Result := ErrorResult(errWrongType); exit; end; cctEmpty: begin Result := ErrorResult(errArgError); exit; end;
cctError: begin Result := ErrorResult(errWrongType); exit; end; cctError: begin Result := ErrorResult(cell^.ErrorValue); exit; end;
end; end;
end; end;
else else

View File

@ -74,7 +74,7 @@
<PackageName Value="FCL"/> <PackageName Value="FCL"/>
</Item4> </Item4>
</RequiredPackages> </RequiredPackages>
<Units Count="35"> <Units Count="36">
<Unit0> <Unit0>
<Filename Value="spreadtestgui.lpr"/> <Filename Value="spreadtestgui.lpr"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
@ -217,6 +217,10 @@
<Filename Value="definednames_tests.pas"/> <Filename Value="definednames_tests.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
</Unit34> </Unit34>
<Unit35>
<Filename Value="calcformulatests.pas"/>
<IsPartOfProject Value="True"/>
</Unit35>
</Units> </Units>
</ProjectOptions> </ProjectOptions>
<CompilerOptions> <CompilerOptions>

View File

@ -11,7 +11,8 @@ uses
Interfaces, Forms, GuiTestRunner, testsutility, datetests, stringtests, Interfaces, Forms, GuiTestRunner, testsutility, datetests, stringtests,
numberstests, manualtests, internaltests, mathtests, fileformattests, numberstests, manualtests, internaltests, mathtests, fileformattests,
formattests, colortests, fonttests, optiontests, conditionalformattests, formattests, colortests, fonttests, optiontests, conditionalformattests,
numformatparsertests, formulatests, rpnFormulaUnit, singleformulatests, numformatparsertests,
formulatests, rpnFormulaUnit, singleformulatests, calcformulatests,
exceltests, emptycelltests, errortests, virtualmodetests, colrowtests, exceltests, emptycelltests, errortests, virtualmodetests, colrowtests,
ssttests, celltypetests, sortingtests, copytests, movetests, enumeratortests, ssttests, celltypetests, sortingtests, copytests, movetests, enumeratortests,
commenttests, hyperlinktests, pagelayouttests, protectiontests, commenttests, hyperlinktests, pagelayouttests, protectiontests,