FPSpreadsheet: Fix error in IF formula when second argument contains an error and is selected. See https://forum.lazarus.freepascal.org/index.php/topic,70117.msg546252. Update unit test.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9620 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz 2025-02-06 21:26:55 +00:00
parent 9bb978ae0f
commit 016a7136bb
2 changed files with 25 additions and 19 deletions

View File

@ -2070,29 +2070,25 @@ end;
// IF( condition, value_if_true, [value_if_false] ) // IF( condition, value_if_true, [value_if_false] )
procedure fpsIF(var Result: TsExpressionResult; const Args: TsExprParameterArray); procedure fpsIF(var Result: TsExpressionResult; const Args: TsExprParameterArray);
var
res: Boolean;
begin begin
if IsError(Args[0], Result) then if IsError(Args[0], Result) then
exit; exit;
if IsError(Args[1], Result) then
exit;
if (Args[0].ResultType = rtString) then if (Args[0].ResultType = rtString) then
begin begin
Result := ErrorResult(errWrongType); Result := ErrorResult(errWrongType);
exit; exit;
end; end;
if Length(Args) > 2 then res := ArgToBoolean(Args[0], false);
begin if res then
if IsError(Args[2], Result) then
exit;
if ArgToBoolean(Args[0], false) then
Result := Args[1] Result := Args[1]
else else
Result := Args[2];
end else
begin begin
if ArgToBoolean(Args[0], false) then if Length(Args) > 2 then
Result := Args[1] Result := Args[2]
else else
Result.ResBoolean := false; Result.ResBoolean := false;
end; end;

View File

@ -1158,21 +1158,31 @@ begin
FWorksheet.CalcFormulas; FWorksheet.CalcFormulas;
CheckEquals('FALSE', FWorksheet.ReadAsText(0, 1), 'Formula #7 IF(A1<100,"ok") result mismatch'); CheckEquals('FALSE', FWorksheet.ReadAsText(0, 1), 'Formula #7 IF(A1<100,"ok") result mismatch');
// Error propagation: error in 3rd argument // Error propagation: error in 3rd argument - result is non-error argument
FWorksheet.WriteFormula(0, 1, '=IF(A1>=100, "ok", 1/0)'); FWorksheet.WriteFormula(0, 1, '=IF(A1>=100, "ok", 1/0)');
FWorksheet.CalcFormulas; FWorksheet.CalcFormulas;
CheckEquals(STR_ERR_DIVIDE_BY_ZERO, FWorksheet.ReadAsText(0, 1), 'Formula #8 IF(A1>=100,"ok",1/0) result mismatch'); CheckEquals('ok', FWorksheet.ReadAsText(0, 1), 'Formula #8 IF(A1>=100,"ok",1/0) result mismatch');
// Error propagation: error in 2nd argument // Error propagation: error in 3rd argument - result is error argument
FWorksheet.WriteFormula(0, 1, '=IF(A1>=100, 1/0,"not ok")'); FWorksheet.WriteFormula(0, 1, '=IF(A1<100, "ok", 1/0)');
FWorksheet.CalcFormulas; FWorksheet.CalcFormulas;
CheckEquals(STR_ERR_DIVIDE_BY_ZERO, FWorksheet.ReadAsText(0, 1), 'Formula #9 IF(A1>=100,1/0,"not ok") result mismatch'); CheckEquals(STR_ERR_DIVIDE_BY_ZERO, FWorksheet.ReadAsText(0, 1), 'Formula #9 IF(A1<100,"ok",1/0) result mismatch');
// Error propagation: error in 2nd argument - result is error argument
FWorksheet.WriteFormula(0, 1, '=IF(A1>=100, 1/0,"abc")');
FWorksheet.CalcFormulas;
CheckEquals(STR_ERR_DIVIDE_BY_ZERO, FWorksheet.ReadAsText(0, 1), 'Formula #10 IF(A1>=100,1/0,"abc") result mismatch');
// Error propagation: error in 2nd argument - result is 3rd argument
FWorksheet.WriteFormula(0, 1, '=IF(A1<100, 1/0,"abc")');
FWorksheet.CalcFormulas;
CheckEquals('abc', FWorksheet.ReadAsText(0, 1), 'Formula #11 IF(A1<100,1/0,"abc") result mismatch');
// Error propagaton: error in 1st argument // Error propagaton: error in 1st argument
FWorksheet.WriteFormula(0, 0, '=1/0'); FWorksheet.WriteFormula(0, 0, '=1/0');
FWorksheet.WriteFormula(0, 1, '=IF(A1>=100,"ok","not ok")'); FWorksheet.WriteFormula(0, 1, '=IF(A1>=100,"ok","not ok")');
FWorksheet.CalcFormulas; FWorksheet.CalcFormulas;
CheckEquals(STR_ERR_DIVIDE_BY_ZERO, FWorksheet.ReadAsText(0, 1), 'Formula #10 IF(A1>=100,"ok","not ok") with A1=1/0 result mismatch'); CheckEquals(STR_ERR_DIVIDE_BY_ZERO, FWorksheet.ReadAsText(0, 1), 'Formula #12 IF(A1>=100,"ok","not ok") with A1=1/0 result mismatch');
end; end;
procedure TCalcFormulaTests.Test_IFERROR; procedure TCalcFormulaTests.Test_IFERROR;