fpspreadsheet: Implement calculation of COUNTBLANK formula. Some formatting cosmetics.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3275 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2014-07-03 21:04:58 +00:00
parent 20645fb0c4
commit 78af234614
3 changed files with 55 additions and 19 deletions

View File

@ -128,6 +128,7 @@ function fpsYEAR (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
function fpsAVEDEV (Args: TsArgumentStack; NumArgs: Integer): TsArgument; function fpsAVEDEV (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
function fpsAVERAGE (Args: TsArgumentStack; NumArgs: Integer): TsArgument; function fpsAVERAGE (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
function fpsCOUNT (Args: TsArgumentStack; NumArgs: Integer): TsArgument; function fpsCOUNT (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
function fpsCOUNTBLANK (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
function fpsMAX (Args: TsArgumentStack; NumArgs: Integer): TsArgument; function fpsMAX (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
function fpsMIN (Args: TsArgumentStack; NumArgs: Integer): TsArgument; function fpsMIN (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
function fpsPRODUCT (Args: TsArgumentStack; NumArgs: Integer): TsArgument; function fpsPRODUCT (Args: TsArgumentStack; NumArgs: Integer): TsArgument;
@ -1414,6 +1415,31 @@ begin
Result := CreateNumber(Length(data)); Result := CreateNumber(Length(data));
end; end;
function fpsCOUNTBLANK(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
// COUNTBLANK( range )
// counts the number of empty cells in a range.
var
arg: TsArgument;
r, c, n: Cardinal;
cell: PCell;
begin
arg := Args.Pop;
case arg.ArgumentType of
atCell:
if arg.Cell = nil then Result := CreateNumber(1) else Result := CreateNumber(0);
atCellRange:
begin
n := 0;
for r := arg.FirstRow to arg.LastRow do
for c := arg.FirstCol to arg.LastCol do
if arg.Worksheet.FindCell(r, c) = nil then inc(n);
Result := CreateNumber(n);
end;
else
Result := CreateError(errWrongType);
end;
end;
function fpsMAX(Args: TsArgumentStack; NumArgs: Integer): TsArgument; function fpsMAX(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
// MAX( number1, number2, ... number_n ) // MAX( number1, number2, ... number_n )
var var

View File

@ -1195,7 +1195,7 @@ var
(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:fpsCOUNT), // 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:fpsCOUNTBLANK), // 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:fpsMAX), // 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

View File

@ -14,9 +14,10 @@
RPNFunc(fekAdd, nil))))); RPNFunc(fekAdd, nil)))));
SetLength(sollValues, Row+1); SetLength(sollValues, Row+1);
sollValues[Row] := CreateNumber(1.0+1.0); // B1 = 2 sollValues[Row] := CreateNumber(1.0+1.0); // B1 = 2
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // don't refer to the cell contents here because they have not yet been calculated!
// DO NOT CHANGE THIS FORMULA - ITS RESULT (2) IS HARD-CODED IN OTHER TESTS ! {!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! DO NOT CHANGE THIS FORMULA - ITS RESULT (-9) IS HARD-CODED IN OTHER TESTS !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
// Subtraction // Subtraction
inc(Row); inc(Row);
@ -27,9 +28,10 @@
RPNFunc(fekSub, nil))))); RPNFunc(fekSub, nil)))));
SetLength(sollValues, Row+1); SetLength(sollValues, Row+1);
sollValues[Row] := CreateNumber(1-10); // B2 = -9 sollValues[Row] := CreateNumber(1-10); // B2 = -9
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // don't refer to the cell contents here because they have not yet been calculated!
// DO NOT CHANGE THIS FORMULA - ITS RESULT (-9) IS HARD-CODED IN OTHER TESTS ! {!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! DO NOT CHANGE THIS FORMULA - ITS RESULT (-9) IS HARD-CODED IN OTHER TESTS !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
// Add cell values - relative addresses // Add cell values - relative addresses
inc(Row); inc(Row);
@ -40,7 +42,6 @@
RPNFunc(fekAdd, nil))))); RPNFunc(fekAdd, nil)))));
SetLength(sollValues, Row+1); SetLength(sollValues, Row+1);
sollValues[Row] := CreateNumber(-7); sollValues[Row] := CreateNumber(-7);
// don't refer to the cell contents here because they have not yet been calculated!
// Add cell values - absolute addresses // Add cell values - absolute addresses
inc(Row); inc(Row);
@ -1124,11 +1125,11 @@
inc(Row); inc(Row);
MyWorksheet.WriteUTF8Text(Row, 0, '=COUNT(1, 1.1, 1.2, 0.9, 0.8)'); MyWorksheet.WriteUTF8Text(Row, 0, '=COUNT(1, 1.1, 1.2, 0.9, 0.8)');
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula( MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
RPNNumber(1.0, RPNNumber(1.0,
RPNNumber(1.1, RPNNumber(1.1,
RPNNumber(1.2, RPNNumber(1.2,
RPNNumber(0.9, RPNNumber(0.9,
RPNNumber(0.8, RPNNumber(0.8,
RPNFunc(fekCOUNT, 5, nil)))))))); RPNFunc(fekCOUNT, 5, nil))))))));
SetLength(sollValues, Row+1); SetLength(sollValues, Row+1);
sollValues[Row] := CreateNumber(5); sollValues[Row] := CreateNumber(5);
@ -1137,8 +1138,8 @@
inc(Row); inc(Row);
MyWorksheet.WriteUTF8Text(Row, 0, '=COUNT(B1:B2)'); MyWorksheet.WriteUTF8Text(Row, 0, '=COUNT(B1:B2)');
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula( MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
RPNCellrange('B1:B2', RPNCellrange('B1:B2',
RPNFunc(fekCOUNT, 1, nil)))); RPNFunc(fekCOUNT, 1, nil))));
SetLength(sollValues, Row+1); SetLength(sollValues, Row+1);
sollValues[Row] := CreateNumber(2); sollValues[Row] := CreateNumber(2);
@ -1146,8 +1147,8 @@
inc(Row); inc(Row);
MyWorksheet.WriteUTF8Text(Row, 0, '=COUNT(A1:B2)'); MyWorksheet.WriteUTF8Text(Row, 0, '=COUNT(A1:B2)');
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula( MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
RPNCellrange('A1:B2', RPNCellrange('A1:B2',
RPNFunc(fekCOUNT, 1, nil)))); RPNFunc(fekCOUNT, 1, nil))));
SetLength(sollValues, Row+1); SetLength(sollValues, Row+1);
sollValues[Row] := CreateNumber(2); sollValues[Row] := CreateNumber(2);
@ -1155,11 +1156,20 @@
inc(Row); inc(Row);
MyWorksheet.WriteUTF8Text(Row, 0, '=COUNT(B1:C2)'); MyWorksheet.WriteUTF8Text(Row, 0, '=COUNT(B1:C2)');
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula( MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
RPNCellrange('B1:C2', RPNCellrange('B1:C2',
RPNFunc(fekCOUNT, 1, nil)))); RPNFunc(fekCOUNT, 1, nil))));
SetLength(sollValues, Row+1); SetLength(sollValues, Row+1);
sollValues[Row] := CreateNumber(2); sollValues[Row] := CreateNumber(2);
// COUNT
inc(Row);
MyWorksheet.WriteUTF8Text(Row, 0, '=COUNTBLANK(A1:D2)');
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
RPNCellRange('A1:D2',
RPNFunc(fekCOUNTBLANK, nil))));
SetLength(sollValues, Row+1);
sollValues[Row] := CreateNumber(4);
// MAX // MAX
inc(Row); inc(Row);
MyWorksheet.WriteUTF8Text(Row, 0, '=MAX(1, 1.1, 1.2, 0.9, 0.8)'); MyWorksheet.WriteUTF8Text(Row, 0, '=MAX(1, 1.1, 1.2, 0.9, 0.8)');