diff --git a/components/fpspreadsheet/source/common/fpsfunc.pas b/components/fpspreadsheet/source/common/fpsfunc.pas index 6277d9c58..f0a362483 100644 --- a/components/fpspreadsheet/source/common/fpsfunc.pas +++ b/components/fpspreadsheet/source/common/fpsfunc.pas @@ -2070,29 +2070,25 @@ end; // IF( condition, value_if_true, [value_if_false] ) procedure fpsIF(var Result: TsExpressionResult; const Args: TsExprParameterArray); +var + res: Boolean; begin if IsError(Args[0], Result) then exit; - if IsError(Args[1], Result) then - exit; + if (Args[0].ResultType = rtString) then begin Result := ErrorResult(errWrongType); exit; end; - if Length(Args) > 2 then + res := ArgToBoolean(Args[0], false); + if res then + Result := Args[1] + else begin - if IsError(Args[2], Result) then - exit; - if ArgToBoolean(Args[0], false) then - Result := Args[1] - else - Result := Args[2]; - end else - begin - if ArgToBoolean(Args[0], false) then - Result := Args[1] + if Length(Args) > 2 then + Result := Args[2] else Result.ResBoolean := false; end; diff --git a/components/fpspreadsheet/unit-tests/common/calcformulatests.pas b/components/fpspreadsheet/unit-tests/common/calcformulatests.pas index ea99cf546..cf0a961e0 100644 --- a/components/fpspreadsheet/unit-tests/common/calcformulatests.pas +++ b/components/fpspreadsheet/unit-tests/common/calcformulatests.pas @@ -1158,21 +1158,31 @@ begin FWorksheet.CalcFormulas; 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.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 - FWorksheet.WriteFormula(0, 1, '=IF(A1>=100, 1/0,"not ok")'); + // Error propagation: error in 3rd argument - result is error argument + FWorksheet.WriteFormula(0, 1, '=IF(A1<100, "ok", 1/0)'); 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 FWorksheet.WriteFormula(0, 0, '=1/0'); FWorksheet.WriteFormula(0, 1, '=IF(A1>=100,"ok","not ok")'); 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; procedure TCalcFormulaTests.Test_IFERROR;