From 02e90b8949d890141828898b5d78c3e0113c8938 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Thu, 30 Aug 2018 15:06:33 +0000 Subject: [PATCH] fpspreadsheet: Fix usage of empty cells as numeric value 0 in formulas (https://forum.lazarus.freepascal.org/index.php/topic,42396.msg295893.html) git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6627 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../source/common/fpsexprparser.pas | 45 +++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/components/fpspreadsheet/source/common/fpsexprparser.pas b/components/fpspreadsheet/source/common/fpsexprparser.pas index dc759ca33..43234bae0 100644 --- a/components/fpspreadsheet/source/common/fpsexprparser.pas +++ b/components/fpspreadsheet/source/common/fpsexprparser.pas @@ -841,6 +841,7 @@ function EmptyResult: TsExpressionResult; function ErrorResult(const AValue: TsErrorValue): TsExpressionResult; function FloatResult(const AValue: TsExprFloat): TsExpressionResult; function IntegerResult(const AValue: Integer): TsExpressionResult; +function IsBlank(const AValue: TsExpressionResult): Boolean; function IsInteger(const AValue: TsExpressionResult): Boolean; function IsString(const AValue: TsExpressionResult): Boolean; function StringResult(const AValue: String): TsExpressionResult; @@ -3238,7 +3239,11 @@ begin if HasError(AResult) then exit; - if IsString(LRes) and IsString(RRes) then + if IsBlank(LRes) then + AResult := BooleanResult(IsBlank(RRes)) + else if IsBlank(RRes) then + AResult := BooleanResult(IsBlank(LRes)) + else if IsString(LRes) and IsString(RRes) then AResult := BooleanResult(ArgToString(LRes) = ArgToString(RRes)) else begin fL := ArgToFloat(LRes); @@ -3302,6 +3307,9 @@ begin Left.GetNodeValue(LRes); Right.GetNodeValue(RRes); + if IsBlank(LRes) or IsBlank(RRes) then + AResult := BooleanResult(false) + else if IsString(LRes) and IsString(RRes) then AResult := BooleanResult(ArgToString(LRes) < ArgToString(RRes)) else begin @@ -3342,6 +3350,9 @@ begin Left.GetNodeValue(LRes); Right.GetNodeValue(RRes); + if IsBlank(LRes) or IsBlank(RRes) then + AResult := BooleanResult(false) + else if IsString(LRes) and IsString(RRes) then AResult := BooleanResult(ArgToString(LRes) > ArgToString(RRes)) else begin @@ -3382,7 +3393,11 @@ begin Left.GetNodeValue(LRes); Right.GetNodeValue(RRes); - if IsString(LRes) and IsString(RRes) then + if IsBlank(LRes) then + AResult := BooleanResult(IsBlank(RRes)) + else if IsBlank(RRes) then + AResult := BooleanResult(IsBlank(LRes)) + else if IsString(LRes) and IsString(RRes) then AResult := BooleanResult(ArgToString(LRes) >= ArgToString(RRes)) else begin fL := ArgToFloat(LRes); @@ -3422,7 +3437,11 @@ begin Left.GetNodeValue(LRes); Right.GetNodeValue(RRes); - if IsString(LRes) and IsString(RRes) then + if IsBlank(LRes) then + AResult := BooleanResult(IsBlank(RRes)) + else if IsBlank(RRes) then + AResult := BooleanResult(IsBlank(LRes)) + else if IsString(LRes) and IsString(RRes) then AResult := BooleanResult(ArgToString(LRes) <= ArgToString(RRes)) else begin fL := ArgToFloat(LRes); @@ -4631,6 +4650,26 @@ begin Result.ResInteger := AValue; end; +function IsBlank(const AValue: TsExpressionResult): Boolean; +var + cell: PCell; +begin + case AValue.ResultType of + rtString : + Result := (AValue.ResString = ''); + rtInteger, rtFloat, rtError: + Result := false; + rtEmpty: + Result := true; + rtCell: + begin + cell := (AValue.Worksheet as TsWorksheet).FindCell(AValue.ResRow, AValue.ResCol); + Result := (cell = nil) or (cell^.ContentType = cctEmpty) or + ((cell^.ContentType = cctUTF8String) and (cell^.UTF8StringValue = '')); + end; + end; +end; + function IsInteger(const AValue: TsExpressionResult): Boolean; var i: Int64;