You've already forked lazarus-ccr
fpspreadsheet: Extend compare functions (=, <, etc) to cell values (for calculation of formulas)
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3283 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -60,6 +60,7 @@ function CreateNumberArg(AValue: Double): TsArgument;
|
||||
function CreateStringArg(AValue: String): TsArgument;
|
||||
function CreateErrorArg(AError: TsErrorValue): TsArgument;
|
||||
function CreateEmptyArg: TsArgument;
|
||||
function NoCellRangeArg(Arg: TsArgument): TsArgument;
|
||||
|
||||
{
|
||||
These are the functions called when calculating an RPN formula.
|
||||
@ -241,6 +242,14 @@ begin
|
||||
Result.ArgumentType := atEmpty;
|
||||
end;
|
||||
|
||||
function NoCellRangeArg(Arg: TsArgument): TsArgument;
|
||||
begin
|
||||
if Arg.ArgumentType = atCellRange then
|
||||
Result := CreateCellArg(Arg.Worksheet.FindCell(Arg.FirstRow, Arg.FirstCol))
|
||||
else
|
||||
Result := Arg;
|
||||
end;
|
||||
|
||||
{ Compares two arguments and returns -1 if "Arg2 > Arg1", +1 if "Arg1 < Arg2",
|
||||
0 if "Arg1 = Arg2", MaxInt if result meaningless
|
||||
If AExact is true only matching types are compared, otherwise types are converted before comparing. }
|
||||
@ -1007,97 +1016,67 @@ end;
|
||||
function fpsEqual(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||
var
|
||||
arg1, arg2: TsArgument;
|
||||
res: Integer;
|
||||
begin
|
||||
arg2 := Args.Pop;
|
||||
arg1 := Args.Pop;
|
||||
if arg1.ArgumentType = arg2.ArgumentType then
|
||||
case arg1.ArgumentType of
|
||||
atNumber : Result := CreateBoolArg(arg1.NumberValue = arg2.NumberValue);
|
||||
atString : Result := CreateBoolArg(arg1.StringValue = arg2.StringValue);
|
||||
atBool : Result := CreateBoolArg(arg1.Boolvalue = arg2.BoolValue);
|
||||
end
|
||||
else
|
||||
Result := CreateBoolArg(false);
|
||||
arg2 := NoCellRangeArg(Args.Pop);
|
||||
arg1 := NoCellRangeArg(Args.Pop);
|
||||
res := CompareArgs(arg1, arg2, (arg1.ArgumentType <> atCell) and (arg2.ArgumentType <> atCell));
|
||||
Result := CreateBoolArg(res = 0);
|
||||
end;
|
||||
|
||||
function fpsGreater(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||
var
|
||||
arg1, arg2: TsArgument;
|
||||
res: Integer;
|
||||
begin
|
||||
arg2 := Args.Pop;
|
||||
arg1 := Args.Pop;
|
||||
if arg1.ArgumentType = arg2.ArgumentType then
|
||||
case arg1.ArgumentType of
|
||||
atNumber : Result := CreateBoolArg(arg1.NumberValue > arg2.NumberValue);
|
||||
atString : Result := CreateBoolArg(arg1.StringValue > arg2.StringValue);
|
||||
atBool : Result := CreateBoolArg(arg1.Boolvalue > arg2.BoolValue);
|
||||
end
|
||||
else
|
||||
Result := CreateBoolArg(false);
|
||||
arg2 := NoCellRangeArg(Args.Pop);
|
||||
arg1 := NoCellRangeArg(Args.Pop);
|
||||
res := CompareArgs(arg1, arg2, (arg1.ArgumentType <> atCell) and (arg2.ArgumentType <> atCell));
|
||||
Result := CreateBoolArg(res > 0);
|
||||
end;
|
||||
|
||||
function fpsGreaterEqual(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||
var
|
||||
arg1, arg2: TsArgument;
|
||||
res: Integer;
|
||||
begin
|
||||
arg2 := Args.Pop;
|
||||
arg1 := Args.Pop;
|
||||
if arg1.ArgumentType = arg2.ArgumentType then
|
||||
case arg1.ArgumentType of
|
||||
atNumber : Result := CreateBoolArg(arg1.NumberValue >= arg2.NumberValue);
|
||||
atString : Result := CreateBoolArg(arg1.StringValue >= arg2.StringValue);
|
||||
atBool : Result := CreateBoolArg(arg1.Boolvalue >= arg2.BoolValue);
|
||||
end
|
||||
else
|
||||
Result := CreateBoolArg(false);
|
||||
arg2 := NoCellRangeArg(Args.Pop);
|
||||
arg1 := NoCellRangeArg(Args.Pop);
|
||||
res := CompareArgs(arg1, arg2, (arg1.ArgumentType <> atCell) and (arg2.ArgumentType <> atCell));
|
||||
Result := CreateBoolArg(res >= 0);
|
||||
end;
|
||||
|
||||
function fpsLess(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||
var
|
||||
arg1, arg2: TsArgument;
|
||||
res: Integer;
|
||||
begin
|
||||
arg2 := Args.Pop;
|
||||
arg1 := Args.Pop;
|
||||
if arg1.ArgumentType = arg2.ArgumentType then
|
||||
case arg1.ArgumentType of
|
||||
atNumber : Result := CreateBoolArg(arg1.NumberValue < arg2.NumberValue);
|
||||
atString : Result := CreateBoolArg(arg1.StringValue < arg2.StringValue);
|
||||
atBool : Result := CreateBoolArg(arg1.Boolvalue < arg2.BoolValue);
|
||||
end
|
||||
else
|
||||
Result := CreateBoolArg(false);
|
||||
arg2 := NoCellRangeArg(Args.Pop);
|
||||
arg1 := NoCellRangeArg(Args.Pop);
|
||||
res := CompareArgs(arg1, arg2, (arg1.ArgumentType <> atCell) and (arg2.ArgumentType <> atCell));
|
||||
Result := CreateBoolArg(res < 0);
|
||||
end;
|
||||
|
||||
function fpsLessEqual(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||
var
|
||||
arg1, arg2: TsArgument;
|
||||
res: Integer;
|
||||
begin
|
||||
arg2 := Args.Pop;
|
||||
arg1 := Args.Pop;
|
||||
if arg1.ArgumentType = arg2.ArgumentType then
|
||||
case arg1.ArgumentType of
|
||||
atNumber : Result := CreateBoolArg(arg1.NumberValue <= arg2.NumberValue);
|
||||
atString : Result := CreateBoolArg(arg1.StringValue <= arg2.StringValue);
|
||||
atBool : Result := CreateBoolArg(arg1.Boolvalue <= arg2.BoolValue);
|
||||
end
|
||||
else
|
||||
Result := CreateBoolArg(false);
|
||||
arg2 := NoCellRangeArg(Args.Pop);
|
||||
arg1 := NoCellRangeArg(Args.Pop);
|
||||
res := CompareArgs(arg1, arg2, (arg1.ArgumentType <> atCell) and (arg2.ArgumentType <> atCell));
|
||||
Result := CreateBoolArg(res <= 0);
|
||||
end;
|
||||
|
||||
function fpsNotEqual(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||
var
|
||||
arg1, arg2: TsArgument;
|
||||
res: Integer;
|
||||
begin
|
||||
arg2 := Args.Pop;
|
||||
arg1 := Args.Pop;
|
||||
if arg1.ArgumentType = arg2.ArgumentType then
|
||||
case arg1.ArgumentType of
|
||||
atNumber : Result := CreateBoolArg(arg1.NumberValue <> arg2.NumberValue);
|
||||
atString : Result := CreateBoolArg(arg1.StringValue <> arg2.StringValue);
|
||||
atBool : Result := CreateBoolArg(arg1.Boolvalue <> arg2.BoolValue);
|
||||
end
|
||||
else
|
||||
Result := CreateBoolArg(false);
|
||||
arg2 := NoCellRangeArg(Args.Pop);
|
||||
arg1 := NoCellRangeArg(Args.Pop);
|
||||
res := CompareArgs(arg1, arg2, (arg1.ArgumentType <> atCell) and (arg2.ArgumentType <> atCell));
|
||||
Result := CreateBoolArg(res <> 0);
|
||||
end;
|
||||
|
||||
|
||||
|
@ -246,8 +246,7 @@
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNBool(true,
|
||||
RPNBool(false,
|
||||
RPNParenthesis(
|
||||
RPNFunc(fekEqual, nil))))));
|
||||
RPNFunc(fekEqual, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg(true = false);
|
||||
|
||||
@ -257,8 +256,7 @@
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNString('Hallo',
|
||||
RPNString('world',
|
||||
RPNParenthesis(
|
||||
RPNFunc(fekEqual, nil))))));
|
||||
RPNFunc(fekEqual, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg('Hallo' = 'world');
|
||||
|
||||
@ -268,19 +266,45 @@
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNNumber(1.0,
|
||||
RPNNumber(1.0,
|
||||
RPNParenthesis(
|
||||
RPNFunc(fekEqual, nil))))));
|
||||
RPNFunc(fekEqual, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg(1=1);
|
||||
|
||||
// Equal (cell)
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=(M1=1)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('M1',
|
||||
RPNNumber(1.0,
|
||||
RPNFunc(fekEqual, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg(false); // M1 is "A"
|
||||
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=(M2=1)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('M2',
|
||||
RPNNumber(1.0,
|
||||
RPNFunc(fekEqual, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg(true); // M2 is 1
|
||||
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=(M2=N2)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('M2',
|
||||
RPNCellValue('N2',
|
||||
RPNFunc(fekEqual, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg(false); // M2 is 1, N2 is 2
|
||||
|
||||
// Greater (bool)
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=(true>false)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNBool(true,
|
||||
RPNBool(false,
|
||||
RPNParenthesis(
|
||||
RPNFunc(fekGreater, nil))))));
|
||||
RPNFunc(fekGreater, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg(true > false);
|
||||
|
||||
@ -290,8 +314,7 @@
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNString('Hallo',
|
||||
RPNString('world',
|
||||
RPNParenthesis(
|
||||
RPNFunc(fekGreater, nil))))));
|
||||
RPNFunc(fekGreater, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg('Hallo' > 'world');
|
||||
|
||||
@ -301,11 +324,29 @@
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNNumber(1.0,
|
||||
RPNNumber(1.0,
|
||||
RPNParenthesis(
|
||||
RPNFunc(fekGreater, nil))))));
|
||||
RPNFunc(fekGreater, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg(1>1);
|
||||
|
||||
// Greater (cell)
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=(M2>1)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('M2',
|
||||
RPNNumber(1.0,
|
||||
RPNFunc(fekGreater, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg(false); // M2 is 1
|
||||
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=(M2>N2)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('M2',
|
||||
RPNCellValue('N2',
|
||||
RPNFunc(fekGreater, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg(false); // M2 is 1, N2 is 2
|
||||
|
||||
// Greater equal (bool)
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=(true>=false)');
|
||||
@ -339,6 +380,25 @@
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg(1>=1);
|
||||
|
||||
// Greater equal(cell)
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=(M2>=1)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('M2',
|
||||
RPNNumber(1.0,
|
||||
RPNFunc(fekGreaterEqual, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg(true); // M2 is 1
|
||||
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=(M2>=N2)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('M2',
|
||||
RPNCellValue('N2',
|
||||
RPNFunc(fekGreaterEqual, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg(false); // M2 is 1, N2 is 2
|
||||
|
||||
// Less (bool)
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=(true<false)');
|
||||
@ -372,6 +432,25 @@
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg(1<1);
|
||||
|
||||
// Less (cell)
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=(M2<1)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('M2',
|
||||
RPNNumber(1.0,
|
||||
RPNFunc(fekLess, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg(false); // M2 is 1
|
||||
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=(M2<N2)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('M2',
|
||||
RPNCellValue('N2',
|
||||
RPNFunc(fekLess, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg(true); // M2 is 1, N2 is 2
|
||||
|
||||
// Less equal (bool)
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=(true<=false)');
|
||||
@ -405,6 +484,25 @@
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg(1<=1);
|
||||
|
||||
// Less equal (cell)
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=(M2<=1)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('M2',
|
||||
RPNNumber(1.0,
|
||||
RPNFunc(fekLessEqual, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg(true); // M2 is 1
|
||||
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=(M2<=N2)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('M2',
|
||||
RPNCellValue('N2',
|
||||
RPNFunc(fekLessEqual, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg(true); // M2 is 1, N2 is 2
|
||||
|
||||
// Not equal (bool)
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=(true<>false)');
|
||||
@ -438,6 +536,25 @@
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg(1<>1);
|
||||
|
||||
// Not equal (cell)
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=(M2<>1)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('M2',
|
||||
RPNNumber(1.0,
|
||||
RPNFunc(fekNotEqual, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg(false); // M2 is 1
|
||||
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=(M2<>N2)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('M2',
|
||||
RPNCellValue('N2',
|
||||
RPNFunc(fekNotEqual, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateBoolArg(true); // M2 is 1, N2 is 2
|
||||
|
||||
{------------------------------------------------------------------------------}
|
||||
{ Math }
|
||||
{------------------------------------------------------------------------------}
|
||||
|
Reference in New Issue
Block a user