You've already forked lazarus-ccr
fpspreadsheet: Calculate most statistical and some string functions in rpn formulas. Beginning to handle missing arguments correctly.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3256 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -33,10 +33,6 @@ type
|
|||||||
procedure Delete(AIndex: Integer);
|
procedure Delete(AIndex: Integer);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure FixMissingBool (var Arg: TsArgument; ABool: Boolean);
|
|
||||||
procedure FixMissingNumber(var Arg: TsArgument; ANumber: Double);
|
|
||||||
procedure FixMissingString(var Arg: TsArgument; AString: String);
|
|
||||||
|
|
||||||
function CreateBool(AValue: Boolean): TsArgument;
|
function CreateBool(AValue: Boolean): TsArgument;
|
||||||
function CreateNumber(AValue: Double): TsArgument;
|
function CreateNumber(AValue: Double): TsArgument;
|
||||||
function CreateString(AValue: String): TsArgument;
|
function CreateString(AValue: String): TsArgument;
|
||||||
@ -90,13 +86,30 @@ function fpsSINH (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
|||||||
function fpsSQRT (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
function fpsSQRT (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
function fpsTAN (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
function fpsTAN (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
function fpsTANH (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
function fpsTANH (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
{ Logic }
|
{ Statistical functions }
|
||||||
|
function fpsAVEDEV (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
function fpsAVERAGE (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
function fpsCOUNT (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
function fpsMAX (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
function fpsMIN (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
function fpsPRODUCT (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
function fpsSTDEV (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
function fpsSTDEVP (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
function fpsSUM (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
function fpsSUMSQ (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
function fpsVAR (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
function fpsVARP (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
{ Logical functions }
|
||||||
function fpsAND (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
function fpsAND (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
function fpsFALSE (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
function fpsFALSE (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
function fpsIF (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
function fpsIF (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
function fpsNOT (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
function fpsNOT (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
function fpsOR (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
function fpsOR (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
function fpsTRUE (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
function fpsTRUE (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
{ String functions }
|
||||||
|
function fpsLOWER (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
function fpsTRIM (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
function fpsUPPER (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@ -104,9 +117,9 @@ uses
|
|||||||
Math;
|
Math;
|
||||||
|
|
||||||
type
|
type
|
||||||
TBoolArray = array of boolean;
|
TBoolArray = array of boolean;
|
||||||
TFloatArray = array of double;
|
TFloatArray = array of double;
|
||||||
TStrArray = array of string;
|
TStrArray = array of string;
|
||||||
|
|
||||||
{ TsArgumentStack }
|
{ TsArgumentStack }
|
||||||
|
|
||||||
@ -194,39 +207,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ Missing arguments }
|
|
||||||
|
|
||||||
{@@
|
|
||||||
Replaces a missing boolean argument by the passed boolean value
|
|
||||||
@param Arg Argument to be considered
|
|
||||||
@param ABool Replacement for the missing value
|
|
||||||
}
|
|
||||||
procedure FixMissingBool(var Arg: TsArgument; ABool: Boolean);
|
|
||||||
begin
|
|
||||||
if Arg.IsMissing then Arg.BoolValue := ABool;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{@@
|
|
||||||
Replaces a missing number argument by the passed number value
|
|
||||||
@param Arg Argument to be considered
|
|
||||||
@param ANumber Replacement for the missing value
|
|
||||||
}
|
|
||||||
procedure FixMissingNumber(var Arg: TsArgument; ANumber: Double);
|
|
||||||
begin
|
|
||||||
if Arg.IsMissing then Arg.NumberValue := ANumber;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{@@
|
|
||||||
Replaces a missing string argument by the passed string value
|
|
||||||
@param Arg Argument to be considered
|
|
||||||
@param AString Replacement for the missing value
|
|
||||||
}
|
|
||||||
procedure FixMissingString(var Arg: TsArgument; AString: String);
|
|
||||||
begin
|
|
||||||
if Arg.IsMissing then Arg.StringValue := AString;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
{ Preparing arguments }
|
{ Preparing arguments }
|
||||||
|
|
||||||
function GetBoolFromArgument(Arg: TsArgument; var AValue: Boolean): TsErrorValue;
|
function GetBoolFromArgument(Arg: TsArgument; var AValue: Boolean): TsErrorValue;
|
||||||
@ -265,29 +245,34 @@ function CreateBool(AValue: Boolean): TsArgument;
|
|||||||
begin
|
begin
|
||||||
Result.ArgumentType := atBool;
|
Result.ArgumentType := atBool;
|
||||||
Result.Boolvalue := AValue;
|
Result.Boolvalue := AValue;
|
||||||
|
Result.IsMissing := false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function CreateNumber(AValue: Double): TsArgument;
|
function CreateNumber(AValue: Double): TsArgument;
|
||||||
begin
|
begin
|
||||||
Result.ArgumentType := atNumber;
|
Result.ArgumentType := atNumber;
|
||||||
Result.NumberValue := AValue;
|
Result.NumberValue := AValue;
|
||||||
|
Result.IsMissing := false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function CreateString(AValue: String): TsArgument;
|
function CreateString(AValue: String): TsArgument;
|
||||||
begin
|
begin
|
||||||
Result.ArgumentType := atString;
|
Result.ArgumentType := atString;
|
||||||
Result.StringValue := AValue;
|
Result.StringValue := AValue;
|
||||||
|
Result.IsMissing := false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function CreateError(AError: TsErrorValue): TsArgument;
|
function CreateError(AError: TsErrorValue): TsArgument;
|
||||||
begin
|
begin
|
||||||
Result.ArgumentType := atError;
|
Result.ArgumentType := atError;
|
||||||
Result.ErrorValue := AError;
|
Result.ErrorValue := AError;
|
||||||
|
Result.IsMissing := false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function CreateEmpty: TsArgument;
|
function CreateEmpty: TsArgument;
|
||||||
begin
|
begin
|
||||||
Result.ArgumentType := atEmpty;
|
Result.ArgumentType := atEmpty;
|
||||||
|
Result.IsMissing := false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@
|
{@@
|
||||||
@ -298,29 +283,47 @@ end;
|
|||||||
@param AValues (output) Array containing the retrieved boolean values.
|
@param AValues (output) Array containing the retrieved boolean values.
|
||||||
The array length is given by NumArgs. The data in the array
|
The array length is given by NumArgs. The data in the array
|
||||||
are in the same order in which they were pushed onto the stack.
|
are in the same order in which they were pushed onto the stack.
|
||||||
|
Missing arguments are not included in the array, the case
|
||||||
|
of missing arguments must be handled separately if the are
|
||||||
|
important.
|
||||||
@param AErrArg (output) Argument containing an error code, e.g. errWrongType
|
@param AErrArg (output) Argument containing an error code, e.g. errWrongType
|
||||||
if non-boolean data were met on the stack.
|
if non-boolean data were met on the stack.
|
||||||
@return TRUE if everything was ok, FALSE, if AErrArg reports an error. }
|
@return TRUE if everything was ok, FALSE, if AErrArg reports an error. }
|
||||||
function PopBoolValues(Args: TsArgumentStack; NumArgs: Integer;
|
function PopBoolValues(Args: TsArgumentStack; NumArgs: Integer;
|
||||||
out AValues: TBoolArray; out AErrArg: TsArgument): Boolean;
|
out AValues: TBoolArray; out AErrArg: TsArgument): Boolean;
|
||||||
var
|
var
|
||||||
|
arg: TsArgument;
|
||||||
err: TsErrorValue;
|
err: TsErrorValue;
|
||||||
i: Integer;
|
counter, j: Integer;
|
||||||
|
b: Boolean;
|
||||||
begin
|
begin
|
||||||
SetLength(AValues, NumArgs);
|
SetLength(AValues, NumArgs);
|
||||||
// Pop the data in reverse order they were pushed! Otherwise they will be
|
j := 0;
|
||||||
// applied to the function in the wrong order.
|
for counter := 1 to NumArgs do begin
|
||||||
for i := NumArgs-1 downto 0 do begin
|
arg := Args.Pop;
|
||||||
err := GetBoolFromArgument(Args.Pop, AValues[i]);
|
if not arg.IsMissing then begin
|
||||||
if err <> errOK then begin
|
err := GetBoolFromArgument(arg, b);
|
||||||
Result := false;
|
if err = errOK then begin
|
||||||
AErrArg := CreateError(err);
|
AValues[j] := b;
|
||||||
SetLength(AValues, 0);
|
inc(j);
|
||||||
exit;
|
end else begin
|
||||||
|
Result := false;
|
||||||
|
AErrArg := CreateError(err);
|
||||||
|
SetLength(AValues, 0);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
Result := true;
|
Result := true;
|
||||||
AErrArg := CreateError(errOK);
|
AErrArg := CreateError(errOK);
|
||||||
|
SetLength(AValues, j);
|
||||||
|
// Flip array - we want to have the arguments in the array in the same order
|
||||||
|
// they were pushed.
|
||||||
|
for j:=0 to Length(AValues) div 2 - 1 do begin
|
||||||
|
b := AValues[j];
|
||||||
|
AValues[j] := AValues[High(AValues)-j];
|
||||||
|
AValues[High(AValues)-j] := b;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@
|
{@@
|
||||||
@ -331,28 +334,46 @@ end;
|
|||||||
@param AValues (output) Array containing the retrieved float values.
|
@param AValues (output) Array containing the retrieved float values.
|
||||||
The array length is given by NumArgs. The data in the array
|
The array length is given by NumArgs. The data in the array
|
||||||
are in the same order in which they were pushed onto the stack.
|
are in the same order in which they were pushed onto the stack.
|
||||||
|
Missing arguments are not included in the array, the case
|
||||||
|
of missing arguments must be handled separately if the are
|
||||||
|
important.
|
||||||
@param AErrArg (output) Argument containing an error code, e.g. errWrongType
|
@param AErrArg (output) Argument containing an error code, e.g. errWrongType
|
||||||
if non-float data were met on the stack.
|
if non-float data were met on the stack.
|
||||||
@return TRUE if everything was ok, FALSE, if AErrArg reports an error. }
|
@return TRUE if everything was ok, FALSE, if AErrArg reports an error. }
|
||||||
function PopFloatValues(Args: TsArgumentStack; NumArgs: Integer;
|
function PopFloatValues(Args: TsArgumentStack; NumArgs: Integer;
|
||||||
out AValues: TFloatArray; out AErrArg: TsArgument): Boolean;
|
out AValues: TFloatArray; out AErrArg: TsArgument): Boolean;
|
||||||
var
|
var
|
||||||
|
arg: TsArgument;
|
||||||
err: TsErrorValue;
|
err: TsErrorValue;
|
||||||
i: Integer;
|
counter, j: Integer;
|
||||||
|
val: double;
|
||||||
begin
|
begin
|
||||||
SetLength(AValues, NumArgs);
|
SetLength(AValues, NumArgs);
|
||||||
// Pop the data in reverse order they were pushed! Otherwise they will be
|
j := 0;
|
||||||
// applied to the function in the wrong order.
|
for counter := 1 to NumArgs do begin
|
||||||
for i := NumArgs-1 downto 0 do begin
|
arg := Args.Pop;
|
||||||
err := GetNumberFromArgument(Args.Pop, AValues[i]);
|
if not arg.IsMissing then begin
|
||||||
if err <> errOK then begin
|
err := GetNumberFromArgument(arg, val);
|
||||||
Result := false;
|
if err = errOK then begin
|
||||||
SetLength(AValues, 0);
|
AValues[j] := val;
|
||||||
AErrArg := CreateError(errWrongType);
|
inc(j);
|
||||||
exit;
|
end else begin
|
||||||
|
Result := false;
|
||||||
|
SetLength(AValues, 0);
|
||||||
|
AErrArg := CreateError(errWrongType);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
Result := true;
|
Result := true;
|
||||||
|
SetLength(AValues, j);
|
||||||
|
// Flip array - we want to have the arguments in the array in the same order
|
||||||
|
// they were pushed.
|
||||||
|
for j:=0 to Length(AValues) div 2 - 1 do begin
|
||||||
|
val := AValues[j];
|
||||||
|
AValues[j] := AValues[High(AValues)-j];
|
||||||
|
AValues[High(AValues)-j] := val;
|
||||||
|
end;
|
||||||
AErrArg := CreateError(errOK);
|
AErrArg := CreateError(errOK);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -364,29 +385,47 @@ end;
|
|||||||
@param AValues (output) Array containing the retrieved strings. The array
|
@param AValues (output) Array containing the retrieved strings. The array
|
||||||
length is given by NumArgs. The data in the array are in the
|
length is given by NumArgs. The data in the array are in the
|
||||||
same order in which they were pushed onto the stack.
|
same order in which they were pushed onto the stack.
|
||||||
|
Missing arguments are not included in the array, the case
|
||||||
|
of missing arguments must be handled separately if the are
|
||||||
|
important.
|
||||||
@param AErrArg (output) Argument containing an error code , e.g. errWrongType
|
@param AErrArg (output) Argument containing an error code , e.g. errWrongType
|
||||||
if non-string data were met on the stack.
|
if non-string data were met on the stack.
|
||||||
@return TRUE if everything was ok, FALSE, if AErrArg reports an error. }
|
@return TRUE if everything was ok, FALSE, if AErrArg reports an error. }
|
||||||
function PopStringValues(Args: TsArgumentStack; NumArgs: Integer;
|
function PopStringValues(Args: TsArgumentStack; NumArgs: Integer;
|
||||||
out AValues: TStrArray; out AErrArg: TsArgument): Boolean;
|
out AValues: TStrArray; out AErrArg: TsArgument): Boolean;
|
||||||
var
|
var
|
||||||
|
arg: TsArgument;
|
||||||
err: TsErrorValue;
|
err: TsErrorValue;
|
||||||
i: Integer;
|
counter, j: Integer;
|
||||||
|
s: String;
|
||||||
begin
|
begin
|
||||||
SetLength(AValues, NumArgs);
|
SetLength(AValues, NumArgs);
|
||||||
// Pop the data in reverse order they were pushed! Otherwise they will be
|
j := 0;
|
||||||
// applied to the function in the wrong order.
|
for counter := 1 to NumArgs do begin
|
||||||
for i := NumArgs-1 downto 0 do begin
|
arg := Args.Pop;
|
||||||
err := GetStringFromArgument(Args.Pop, AValues[i]);
|
if not arg.IsMissing then begin
|
||||||
if err <> errOK then begin
|
err := GetStringFromArgument(arg, s);
|
||||||
Result := false;
|
if err = errOK then begin
|
||||||
AErrArg := CreateError(errWrongType);
|
AValues[j] := s;
|
||||||
SetLength(AValues, 0);
|
inc(j);
|
||||||
exit;
|
end else begin
|
||||||
|
Result := false;
|
||||||
|
AErrArg := CreateError(errWrongType);
|
||||||
|
SetLength(AValues, 0);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
Result :=true;
|
Result := true;
|
||||||
AErrArg := CreateError(errOK);
|
AErrArg := CreateError(errOK);
|
||||||
|
SetLength(AValues, j);
|
||||||
|
// Flip array - we want to have the arguments in the array in the same order
|
||||||
|
// they were pushed.
|
||||||
|
for j:=0 to Length(AValues) div 2 - 1 do begin
|
||||||
|
s := AValues[j];
|
||||||
|
AValues[j] := AValues[High(AValues)-j];
|
||||||
|
AValues[High(AValues)-j] := s;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -826,6 +865,122 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ Statistical functions }
|
||||||
|
|
||||||
|
function fpsAVEDEV(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
// Average value of absolute deviations of data from their mean.
|
||||||
|
var
|
||||||
|
data: TFloatArray;
|
||||||
|
m: Double;
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
if PopFloatValues(Args, NumArgs, data, Result) then begin
|
||||||
|
m := Mean(data);
|
||||||
|
for i:=0 to High(data) do
|
||||||
|
data[i] := abs(data[i] - m);
|
||||||
|
m := Mean(data);
|
||||||
|
Result := CreateNumber(m)
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function fpsAVERAGE(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
var
|
||||||
|
data: TFloatArray;
|
||||||
|
begin
|
||||||
|
if PopFloatValues(Args, NumArgs, data, Result) then
|
||||||
|
Result := CreateNumber(Mean(data))
|
||||||
|
end;
|
||||||
|
|
||||||
|
function fpsCOUNT(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
{ Count non-missing arguments }
|
||||||
|
var
|
||||||
|
n, i: Integer;
|
||||||
|
begin
|
||||||
|
n := 0;
|
||||||
|
for i:=1 to NumArgs do
|
||||||
|
if not Args.Pop.IsMissing then inc(n);
|
||||||
|
Result := CreateNumber(n);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function fpsMAX(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
var
|
||||||
|
data: TFloatArray;
|
||||||
|
begin
|
||||||
|
if PopFloatValues(Args, NumArgs, data, Result) then
|
||||||
|
Result := CreateNumber(MaxValue(data))
|
||||||
|
end;
|
||||||
|
|
||||||
|
function fpsMIN(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
var
|
||||||
|
data: TFloatArray;
|
||||||
|
begin
|
||||||
|
if PopFloatValues(Args, NumArgs, data, Result) then
|
||||||
|
Result := CreateNumber(MinValue(data))
|
||||||
|
end;
|
||||||
|
|
||||||
|
function fpsPRODUCT(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
var
|
||||||
|
data: TFloatArray;
|
||||||
|
i: Integer;
|
||||||
|
p: Double;
|
||||||
|
begin
|
||||||
|
if PopFloatValues(Args, NumArgs, data, Result) then begin
|
||||||
|
p := 1.0;
|
||||||
|
for i:=0 to High(data) do
|
||||||
|
p := p * data[i];
|
||||||
|
Result := CreateNumber(p);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function fpsSTDEV(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
var
|
||||||
|
data: TFloatArray;
|
||||||
|
begin
|
||||||
|
if PopFloatValues(Args, NumArgs, data, Result) then
|
||||||
|
Result := CreateNumber(StdDev(data))
|
||||||
|
end;
|
||||||
|
|
||||||
|
function fpsSTDEVP(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
var
|
||||||
|
data: TFloatArray;
|
||||||
|
begin
|
||||||
|
if PopFloatValues(Args, NumArgs, data, Result) then
|
||||||
|
Result := CreateNumber(PopnStdDev(data))
|
||||||
|
end;
|
||||||
|
|
||||||
|
function fpsSUM(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
var
|
||||||
|
data: TFloatArray;
|
||||||
|
begin
|
||||||
|
if PopFloatValues(Args, NumArgs, data, Result) then
|
||||||
|
Result := CreateNumber(Sum(data))
|
||||||
|
end;
|
||||||
|
|
||||||
|
function fpsSUMSQ(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
var
|
||||||
|
data: TFloatArray;
|
||||||
|
begin
|
||||||
|
if PopFloatValues(Args, NumArgs, data, Result) then
|
||||||
|
Result := CreateNumber(SumOfSquares(data))
|
||||||
|
end;
|
||||||
|
|
||||||
|
function fpsVAR(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
var
|
||||||
|
data: TFloatArray;
|
||||||
|
begin
|
||||||
|
if PopFloatValues(Args, NumArgs, data, Result) then
|
||||||
|
Result := CreateNumber(Variance(data))
|
||||||
|
end;
|
||||||
|
|
||||||
|
function fpsVARP(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
var
|
||||||
|
data: TFloatArray;
|
||||||
|
begin
|
||||||
|
if PopFloatValues(Args, NumArgs, data, Result) then
|
||||||
|
Result := CreateNumber(PopnVariance(data))
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ Logical functions }
|
{ Logical functions }
|
||||||
|
|
||||||
function fpsAND(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
function fpsAND(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
@ -901,4 +1056,31 @@ begin
|
|||||||
Result := CreateBool(true);
|
Result := CreateBool(true);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ String functions }
|
||||||
|
|
||||||
|
function fpsLOWER(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
var
|
||||||
|
data: TStrArray;
|
||||||
|
begin
|
||||||
|
if PopStringValues(Args, NumArgs, data, Result) then
|
||||||
|
Result := CreateString(lowercase(data[0]));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function fpsTRIM(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
var
|
||||||
|
data: TStrArray;
|
||||||
|
begin
|
||||||
|
if PopStringValues(Args, NumArgs, data, Result) then
|
||||||
|
Result := CreateString(trim(data[0]));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function fpsUPPER(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||||
|
var
|
||||||
|
data: TStrArray;
|
||||||
|
begin
|
||||||
|
if PopStringValues(Args, NumArgs, data, Result) then
|
||||||
|
Result := CreateString(uppercase(data[0]));
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@ -1164,30 +1164,30 @@ const
|
|||||||
(Symbol:'WEEKDAY'; MinParams:1; MaxParams:2; Func:nil), // fekWEEKDAY
|
(Symbol:'WEEKDAY'; MinParams:1; MaxParams:2; Func:nil), // fekWEEKDAY
|
||||||
(Symbol:'YEAR'; MinParams:1; MaxParams:1; Func:nil), // fekYEAR
|
(Symbol:'YEAR'; MinParams:1; MaxParams:1; Func:nil), // fekYEAR
|
||||||
{ statistical }
|
{ statistical }
|
||||||
(Symbol:'AVEDEV'; MinParams:1; MaxParams:30; Func:nil), // fekAVEDEV
|
(Symbol:'AVEDEV'; MinParams:1; MaxParams:30; Func:fpsAVEDEV), // fekAVEDEV
|
||||||
(Symbol:'AVERAGE'; MinParams:1; MaxParams:30; Func:nil), // fekAVERAGE
|
(Symbol:'AVERAGE'; MinParams:1; MaxParams:30; Func:fpsAVERAGE), // fekAVERAGE
|
||||||
(Symbol:'BETADIST'; MinParams:3; MaxParams:5; Func:nil), // fekBETADIST
|
(Symbol:'BETADIST'; MinParams:3; MaxParams:5; Func:nil), // fekBETADIST
|
||||||
(Symbol:'BETAINV'; MinParams:3; MaxParams:5; Func:nil), // fekBETAINV
|
(Symbol:'BETAINV'; MinParams:3; MaxParams:5; Func:nil), // fekBETAINV
|
||||||
(Symbol:'BINOMDIST'; MinParams:4; MaxParams:4; Func:nil), // fekBINOMDIST
|
(Symbol:'BINOMDIST'; MinParams:4; MaxParams:4; Func:nil), // fekBINOMDIST
|
||||||
(Symbol:'CHIDIST'; MinParams:2; MaxParams:2; Func:nil), // fekCHIDIST
|
(Symbol:'CHIDIST'; MinParams:2; MaxParams:2; Func:nil), // fekCHIDIST
|
||||||
(Symbol:'CHIINV'; MinParams:2; MaxParams:2; Func:nil), // fekCHIINV
|
(Symbol:'CHIINV'; MinParams:2; MaxParams:2; Func:nil), // fekCHIINV
|
||||||
(Symbol:'COUNT'; MinParams:0; MaxParams:30; Func:nil), // fekCOUNT
|
(Symbol:'COUNT'; MinParams:0; MaxParams:30; Func:fpsCOUNT), // fekCOUNT
|
||||||
(Symbol:'COUNTA'; MinParams:0; MaxParams:30; Func:nil), // fekCOUNTA
|
(Symbol:'COUNTA'; MinParams:0; MaxParams:30; Func:nil), // fekCOUNTA
|
||||||
(Symbol:'COUNTBLANK';MinParams:1; MaxParams:1; Func:nil), // fekCOUNTBLANK
|
(Symbol:'COUNTBLANK';MinParams:1; MaxParams:1; Func:nil), // fekCOUNTBLANK
|
||||||
(Symbol:'COUNTIF'; MinParams:2; MaxParams:2; Func:nil), // fekCOUNTIF
|
(Symbol:'COUNTIF'; MinParams:2; MaxParams:2; Func:nil), // fekCOUNTIF
|
||||||
(Symbol:'MAX'; MinParams:1; MaxParams:30; Func:nil), // fekMAX
|
(Symbol:'MAX'; MinParams:1; MaxParams:30; Func:fpsMAX), // fekMAX
|
||||||
(Symbol:'MEDIAN'; MinParams:1; MaxParams:30; Func:nil), // fekMEDIAN
|
(Symbol:'MEDIAN'; MinParams:1; MaxParams:30; Func:nil), // fekMEDIAN
|
||||||
(Symbol:'MIN'; MinParams:1; MaxParams:30; Func:nil), // fekMIN
|
(Symbol:'MIN'; MinParams:1; MaxParams:30; Func:fpsMIN), // fekMIN
|
||||||
(Symbol:'PERMUT'; MinParams:2; MaxParams:2; Func:nil), // fekPERMUT
|
(Symbol:'PERMUT'; MinParams:2; MaxParams:2; Func:nil), // fekPERMUT
|
||||||
(Symbol:'POISSON'; MinParams:3; MaxParams:3; Func:nil), // fekPOISSON
|
(Symbol:'POISSON'; MinParams:3; MaxParams:3; Func:nil), // fekPOISSON
|
||||||
(Symbol:'PRODUCT'; MinParams:0; MaxParams:30; Func:nil), // fekPRODUCT
|
(Symbol:'PRODUCT'; MinParams:0; MaxParams:30; Func:fpsPRODUCT), // fekPRODUCT
|
||||||
(Symbol:'STDEV'; MinParams:1; MaxParams:30; Func:nil), // fekSTDEV
|
(Symbol:'STDEV'; MinParams:1; MaxParams:30; Func:fpsSTDEV), // fekSTDEV
|
||||||
(Symbol:'STDEVP'; MinParams:1; MaxParams:30; Func:nil), // fekSTDEVP
|
(Symbol:'STDEVP'; MinParams:1; MaxParams:30; Func:fpsSTDEVP), // fekSTDEVP
|
||||||
(Symbol:'SUM'; MinParams:0; MaxParams:30; Func:nil), // fekSUM
|
(Symbol:'SUM'; MinParams:0; MaxParams:30; Func:fpsSUM), // fekSUM
|
||||||
(Symbol:'SUMIF'; MinParams:2; MaxParams:3; Func:nil), // fekSUMIF
|
(Symbol:'SUMIF'; MinParams:2; MaxParams:3; Func:nil), // fekSUMIF
|
||||||
(Symbol:'SUMSQ'; MinParams:0; MaxParams:30; Func:nil), // fekSUMSQ
|
(Symbol:'SUMSQ'; MinParams:0; MaxParams:30; Func:fpsSUMSQ), // fekSUMSQ
|
||||||
(Symbol:'VAR'; MinParams:1; MaxParams:30; Func:nil), // fekVAR
|
(Symbol:'VAR'; MinParams:1; MaxParams:30; Func:fpsVAR), // fekVAR
|
||||||
(Symbol:'VARP'; MinParams:1; MaxParams:30; Func:nil), // fekVARP
|
(Symbol:'VARP'; MinParams:1; MaxParams:30; Func:fpsVARP), // fekVARP
|
||||||
{ financial }
|
{ financial }
|
||||||
(Symbol:'FV'; MinParams:3; MaxParams:5; Func:nil), // fekFV
|
(Symbol:'FV'; MinParams:3; MaxParams:5; Func:nil), // fekFV
|
||||||
(Symbol:'NPER'; MinParams:3; MaxParams:5; Func:nil), // fekNPER
|
(Symbol:'NPER'; MinParams:3; MaxParams:5; Func:nil), // fekNPER
|
||||||
@ -1205,14 +1205,14 @@ const
|
|||||||
(Symbol:'CHAR'; MinParams:1; MaxParams:1; Func:nil), // fekCHAR
|
(Symbol:'CHAR'; MinParams:1; MaxParams:1; Func:nil), // fekCHAR
|
||||||
(Symbol:'CODE'; MinParams:1; MaxParams:1; Func:nil), // fekCODE
|
(Symbol:'CODE'; MinParams:1; MaxParams:1; Func:nil), // fekCODE
|
||||||
(Symbol:'LEFT'; MinParams:1; MaxParams:2; Func:nil), // fekLEFT
|
(Symbol:'LEFT'; MinParams:1; MaxParams:2; Func:nil), // fekLEFT
|
||||||
(Symbol:'LOWER'; MinParams:1; MaxParams:1; Func:nil), // fekLOWER
|
(Symbol:'LOWER'; MinParams:1; MaxParams:1; Func:fpsLOWER), // fekLOWER
|
||||||
(Symbol:'MID'; MinParams:3; MaxParams:3; Func:nil), // fekMID
|
(Symbol:'MID'; MinParams:3; MaxParams:3; Func:nil), // fekMID
|
||||||
(Symbol:'PROPER'; MinParams:1; MaxParams:1; Func:nil), // fekPROPER
|
(Symbol:'PROPER'; MinParams:1; MaxParams:1; Func:nil), // fekPROPER
|
||||||
(Symbol:'REPLACE'; MinParams:4; MaxParams:4; Func:nil), // fekREPLACE
|
(Symbol:'REPLACE'; MinParams:4; MaxParams:4; Func:nil), // fekREPLACE
|
||||||
(Symbol:'RIGHT'; MinParams:1; MaxParams:2; Func:nil), // fekRIGHT
|
(Symbol:'RIGHT'; MinParams:1; MaxParams:2; Func:nil), // fekRIGHT
|
||||||
(Symbol:'SUBSTITUTE';MinParams:3; MaxParams:4; Func:nil), // fekSUBSTITUTE
|
(Symbol:'SUBSTITUTE';MinParams:3; MaxParams:4; Func:nil), // fekSUBSTITUTE
|
||||||
(Symbol:'TRIM'; MinParams:1; MaxParams:1; Func:nil), // fekTRIM
|
(Symbol:'TRIM'; MinParams:1; MaxParams:1; Func:fpsTRIM), // fekTRIM
|
||||||
(Symbol:'UPPER'; MinParams:1; MaxParams:1; Func:nil), // fekUPPER
|
(Symbol:'UPPER'; MinParams:1; MaxParams:1; Func:fpsUPPER), // fekUPPER
|
||||||
{ lookup/reference }
|
{ lookup/reference }
|
||||||
(Symbol:'COLUMN'; MinParams:0; MaxParams:1; Func:nil), // fekCOLUMN
|
(Symbol:'COLUMN'; MinParams:0; MaxParams:1; Func:nil), // fekCOLUMN
|
||||||
(Symbol:'COLUMNS'; MinParams:1; MaxParams:1; Func:nil), // fekCOLUMNS
|
(Symbol:'COLUMNS'; MinParams:1; MaxParams:1; Func:nil), // fekCOLUMNS
|
||||||
|
@ -680,6 +680,193 @@
|
|||||||
SetLength(sollValues, Row+1);
|
SetLength(sollValues, Row+1);
|
||||||
sollValues[Row] := CreateNumber(tanh(0.1));
|
sollValues[Row] := CreateNumber(tanh(0.1));
|
||||||
|
|
||||||
|
{------------------------------------------------------------------------------}
|
||||||
|
{ Statistical functions }
|
||||||
|
{------------------------------------------------------------------------------}
|
||||||
|
|
||||||
|
// AVEDEV
|
||||||
|
inc(Row);
|
||||||
|
MyWorksheet.WriteUTF8Text(Row, 0, '=AVEDEV(1, 1.1, 1.2, 0.9, 0.8)');
|
||||||
|
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||||
|
RPNNumber(1.0,
|
||||||
|
RPNNumber(1.1,
|
||||||
|
RPNNumber(1.2,
|
||||||
|
RPNNumber(0.9,
|
||||||
|
RPNNumber(0.8,
|
||||||
|
RPNFunc(fekAVEDEV, 5, nil))))))));
|
||||||
|
SetLength(sollValues, Row+1);
|
||||||
|
sollValues[Row] := CreateNumber(mean([0.0, 0.1, 0.2, 0.1, 0.2]));
|
||||||
|
// these values are the absolute deviations from mean (1.0)
|
||||||
|
// AVERAGE
|
||||||
|
inc(Row);
|
||||||
|
MyWorksheet.WriteUTF8Text(Row, 0, '=AVERAGE(1, 1.1, 1.2, 0.9, 0.8)');
|
||||||
|
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||||
|
RPNNumber(1.0,
|
||||||
|
RPNNumber(1.1,
|
||||||
|
RPNNumber(1.2,
|
||||||
|
RPNNumber(0.9,
|
||||||
|
RPNNumber(0.8,
|
||||||
|
RPNFunc(fekAVERAGE, 5, nil))))))));
|
||||||
|
SetLength(sollValues, Row+1);
|
||||||
|
sollValues[Row] := CreateNumber(mean([1.0, 1.1, 1.2, 0.9, 0.8]));
|
||||||
|
|
||||||
|
// COUNT (no missing values)
|
||||||
|
inc(Row);
|
||||||
|
MyWorksheet.WriteUTF8Text(Row, 0, '=COUNT(1, 1.1, 1.2, 0.9, 0.8)');
|
||||||
|
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||||
|
RPNNumber(1.0,
|
||||||
|
RPNNumber(1.1,
|
||||||
|
RPNNumber(1.2,
|
||||||
|
RPNNumber(0.9,
|
||||||
|
RPNNumber(0.8,
|
||||||
|
RPNFunc(fekCOUNT, 5, nil))))))));
|
||||||
|
SetLength(sollValues, Row+1);
|
||||||
|
sollValues[Row] := CreateNumber(5);
|
||||||
|
|
||||||
|
// COUNT (with missing values)
|
||||||
|
inc(Row);
|
||||||
|
MyWorksheet.WriteUTF8Text(Row, 0, '=COUNT(1, , 1.2, , 0.8)');
|
||||||
|
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||||
|
RPNNumber(1.0,
|
||||||
|
RPNMissingArg(
|
||||||
|
RPNNumber(1.2,
|
||||||
|
RPNMissingArg(
|
||||||
|
RPNNumber(0.8,
|
||||||
|
RPNFunc(fekCOUNT, 5, nil))))))));
|
||||||
|
SetLength(sollValues, Row+1);
|
||||||
|
sollValues[Row] := CreateNumber(3);
|
||||||
|
|
||||||
|
// MAX
|
||||||
|
inc(Row);
|
||||||
|
MyWorksheet.WriteUTF8Text(Row, 0, '=MAX(1, 1.1, 1.2, 0.9, 0.8)');
|
||||||
|
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||||
|
RPNNumber(1.0,
|
||||||
|
RPNNumber(1.1,
|
||||||
|
RPNNumber(1.2,
|
||||||
|
RPNNumber(0.9,
|
||||||
|
RPNNumber(0.8,
|
||||||
|
RPNFunc(fekMAX, 5, nil))))))));
|
||||||
|
SetLength(sollValues, Row+1);
|
||||||
|
sollValues[Row] := CreateNumber(MaxValue([1.0, 1.1, 1.2, 0.9, 0.8]));
|
||||||
|
|
||||||
|
// MAX (with missing values)
|
||||||
|
inc(Row);
|
||||||
|
MyWorksheet.WriteUTF8Text(Row, 0, '=MAX(1, , , 0.9, 0.8)');
|
||||||
|
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||||
|
RPNNumber(1.0,
|
||||||
|
RPNMissingArg(
|
||||||
|
RPNMissingArg(
|
||||||
|
RPNNumber(0.9,
|
||||||
|
RPNNumber(0.8,
|
||||||
|
RPNFunc(fekMAX, 5, nil))))))));
|
||||||
|
SetLength(sollValues, Row+1);
|
||||||
|
sollValues[Row] := CreateNumber(MaxValue([1.0, {1.1, 1.2,} 0.9, 0.8]));
|
||||||
|
|
||||||
|
// MIN
|
||||||
|
inc(Row);
|
||||||
|
MyWorksheet.WriteUTF8Text(Row, 0, '=MIN(1, 1.1, 1.2, 0.9, 0.8)');
|
||||||
|
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||||
|
RPNNumber(1.0,
|
||||||
|
RPNNumber(1.1,
|
||||||
|
RPNNumber(1.2,
|
||||||
|
RPNNumber(0.9,
|
||||||
|
RPNNumber(0.8,
|
||||||
|
RPNFunc(fekMIN, 5, nil))))))));
|
||||||
|
SetLength(sollValues, Row+1);
|
||||||
|
sollValues[Row] := CreateNumber(MinValue([1.0, 1.1, 1.2, 0.9, 0.8]));
|
||||||
|
|
||||||
|
// PRODUCT
|
||||||
|
inc(Row);
|
||||||
|
MyWorksheet.WriteUTF8Text(Row, 0, '=PRODUCT(1, 1.1, 1.2, 0.9, 0.8)');
|
||||||
|
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||||
|
RPNNumber(1.0,
|
||||||
|
RPNNumber(1.1,
|
||||||
|
RPNNumber(1.2,
|
||||||
|
RPNNumber(0.9,
|
||||||
|
RPNNumber(0.8,
|
||||||
|
RPNFunc(fekPRODUCT, 5, nil))))))));
|
||||||
|
SetLength(sollValues, Row+1);
|
||||||
|
sollValues[Row] := CreateNumber(1.0*1.1*1.2*0.9*0.8);
|
||||||
|
|
||||||
|
// STDEV
|
||||||
|
inc(Row);
|
||||||
|
MyWorksheet.WriteUTF8Text(Row, 0, '=STDEV(1, 1.1, 1.2, 0.9, 0.8)');
|
||||||
|
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||||
|
RPNNumber(1.0,
|
||||||
|
RPNNumber(1.1,
|
||||||
|
RPNNumber(1.2,
|
||||||
|
RPNNumber(0.9,
|
||||||
|
RPNNumber(0.8,
|
||||||
|
RPNFunc(fekSTDEV, 5, nil))))))));
|
||||||
|
SetLength(sollValues, Row+1);
|
||||||
|
sollValues[Row] := CreateNumber(StdDev([1.0, 1.1, 1.2, 0.9, 0.8]));
|
||||||
|
|
||||||
|
// STDEVP
|
||||||
|
inc(Row);
|
||||||
|
MyWorksheet.WriteUTF8Text(Row, 0, '=STDEVP(1, 1.1, 1.2, 0.9, 0.8)');
|
||||||
|
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||||
|
RPNNumber(1.0,
|
||||||
|
RPNNumber(1.1,
|
||||||
|
RPNNumber(1.2,
|
||||||
|
RPNNumber(0.9,
|
||||||
|
RPNNumber(0.8,
|
||||||
|
RPNFunc(fekSTDEVP, 5, nil))))))));
|
||||||
|
SetLength(sollValues, Row+1);
|
||||||
|
sollValues[Row] := CreateNumber(PopnStdDev([1.0, 1.1, 1.2, 0.9, 0.8]));
|
||||||
|
|
||||||
|
// SUM
|
||||||
|
inc(Row);
|
||||||
|
MyWorksheet.WriteUTF8Text(Row, 0, '=SUM(1, 1.1, 1.2, 0.9, 0.8)');
|
||||||
|
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||||
|
RPNNumber(1.0,
|
||||||
|
RPNNumber(1.1,
|
||||||
|
RPNNumber(1.2,
|
||||||
|
RPNNumber(0.9,
|
||||||
|
RPNNumber(0.8,
|
||||||
|
RPNFunc(fekSUM, 5, nil))))))));
|
||||||
|
SetLength(sollValues, Row+1);
|
||||||
|
sollValues[Row] := CreateNumber(Sum([1.0, 1.1, 1.2, 0.9, 0.8]));
|
||||||
|
|
||||||
|
// SUMSQ
|
||||||
|
inc(Row);
|
||||||
|
MyWorksheet.WriteUTF8Text(Row, 0, '=SUMSQ(1, 1.1, 1.2, 0.9, 0.8)');
|
||||||
|
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||||
|
RPNNumber(1.0,
|
||||||
|
RPNNumber(1.1,
|
||||||
|
RPNNumber(1.2,
|
||||||
|
RPNNumber(0.9,
|
||||||
|
RPNNumber(0.8,
|
||||||
|
RPNFunc(fekSUMSQ, 5, nil))))))));
|
||||||
|
SetLength(sollValues, Row+1);
|
||||||
|
sollValues[Row] := CreateNumber(SumOfSquares([1.0, 1.1, 1.2, 0.9, 0.8]));
|
||||||
|
|
||||||
|
// VAR
|
||||||
|
inc(Row);
|
||||||
|
MyWorksheet.WriteUTF8Text(Row, 0, '=VAR(1, 1.1, 1.2, 0.9, 0.8)');
|
||||||
|
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||||
|
RPNNumber(1.0,
|
||||||
|
RPNNumber(1.1,
|
||||||
|
RPNNumber(1.2,
|
||||||
|
RPNNumber(0.9,
|
||||||
|
RPNNumber(0.8,
|
||||||
|
RPNFunc(fekVAR, 5, nil))))))));
|
||||||
|
SetLength(sollValues, Row+1);
|
||||||
|
sollValues[Row] := CreateNumber(Variance([1.0, 1.1, 1.2, 0.9, 0.8]));
|
||||||
|
|
||||||
|
// VARP
|
||||||
|
inc(Row);
|
||||||
|
MyWorksheet.WriteUTF8Text(Row, 0, '=VARP(1, 1.1, 1.2, 0.9, 0.8)');
|
||||||
|
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||||
|
RPNNumber(1.0,
|
||||||
|
RPNNumber(1.1,
|
||||||
|
RPNNumber(1.2,
|
||||||
|
RPNNumber(0.9,
|
||||||
|
RPNNumber(0.8,
|
||||||
|
RPNFunc(fekVARP, 5, nil))))))));
|
||||||
|
SetLength(sollValues, Row+1);
|
||||||
|
sollValues[Row] := CreateNumber(PopnVariance([1.0, 1.1, 1.2, 0.9, 0.8]));
|
||||||
|
|
||||||
|
|
||||||
{------------------------------------------------------------------------------}
|
{------------------------------------------------------------------------------}
|
||||||
{ Logical functions }
|
{ Logical functions }
|
||||||
{------------------------------------------------------------------------------}
|
{------------------------------------------------------------------------------}
|
||||||
@ -854,3 +1041,34 @@
|
|||||||
sollValues[Row] := CreateString('A');
|
sollValues[Row] := CreateString('A');
|
||||||
|
|
||||||
|
|
||||||
|
{------------------------------------------------------------------------------}
|
||||||
|
{ String functions }
|
||||||
|
{------------------------------------------------------------------------------}
|
||||||
|
|
||||||
|
// Lower case
|
||||||
|
inc(Row);
|
||||||
|
MyWorksheet.WriteUTF8Text(Row, 0, '=LOWER("Hallo word")');
|
||||||
|
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||||
|
RPNString('Hallo world',
|
||||||
|
RPNFunc(fekLOWER, nil))));
|
||||||
|
SetLength(sollValues, Row+1);
|
||||||
|
sollValues[Row] := CreateString(LowerCase('Hallo world'));
|
||||||
|
|
||||||
|
// Trim
|
||||||
|
inc(Row);
|
||||||
|
MyWorksheet.WriteUTF8Text(Row, 0, '=TRIM(" Hallo word ")');
|
||||||
|
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||||
|
RPNString(' Hallo world ',
|
||||||
|
RPNFunc(fekTRIM, nil))));
|
||||||
|
SetLength(sollValues, Row+1);
|
||||||
|
sollValues[Row] := CreateString(Trim(' Hallo world '));
|
||||||
|
|
||||||
|
// Upper case
|
||||||
|
inc(Row);
|
||||||
|
MyWorksheet.WriteUTF8Text(Row, 0, '=UPPER("Hallo word")');
|
||||||
|
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||||
|
RPNString('Hallo world',
|
||||||
|
RPNFunc(fekUPPER, nil))));
|
||||||
|
SetLength(sollValues, Row+1);
|
||||||
|
sollValues[Row] := CreateString(UpperCase('Hallo world'));
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user