From 1f686ef1c9628e66d769e20353d4bc4d934e079f Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Tue, 4 Jun 2024 09:28:10 +0000 Subject: [PATCH] fpspreadsheet: Compare strings in COUNTIF(S), SUMIF(S), AVERAGEIF(S) with wildcards. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9366 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../fpspreadsheet/source/common/fpsfunc.pas | 52 ++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/components/fpspreadsheet/source/common/fpsfunc.pas b/components/fpspreadsheet/source/common/fpsfunc.pas index d01e7dc59..aa87a033c 100644 --- a/components/fpspreadsheet/source/common/fpsfunc.pas +++ b/components/fpspreadsheet/source/common/fpsfunc.pas @@ -11,6 +11,7 @@ interface uses Classes, SysUtils, fpstypes; +function CompareStringWithWildcards(AString1, AString2: String): Boolean; procedure RegisterStdBuiltins(AManager: TComponent); @@ -24,6 +25,53 @@ uses const EPS = 1E-12; +{ AString1 is the string with wildcards. } +function CompareStringWithWildCards(AString1, AString2: String): Boolean; +var + P1, P2, P10, P20: PAnsiChar; + n1, n2: Integer; +begin + if (AString1 = '') and (AString2 = '') then + begin + Result := true; + exit; + end; + if ((AString1 <> '') and (AString2 = '')) or ((AString1 = '') and (AString2 <> '')) then + begin + Result := false; + exit; + end; + + n1 := Length(AString1); + n2 := Length(AString2); + P10 := PAnsiChar(AString1); + P20 := PAnsiChar(AString2); + P1 := P10; + P2 := P20; + while P1 < P10 + n1 do begin + if P1^ = '*' then + begin + Result := True; + exit; + end else + if (P1^ = '?') or (P1^ = P2^) then begin + inc(P1); + if P2 < P20 + n2 then + inc(P2) + else + begin + Result := false; + exit; + end; + end else + if (P1^ <> P2^) then + begin + Result := false; + exit; + end; + end; +end; + type TsFuncType = (ftCountIF, ftCountIFS, ftSumIF, ftSUMIFS, ftAverageIF, ftAverageIFS); TsCompareType = (ctNumber, ctString, ctEmpty); @@ -106,12 +154,12 @@ begin Result := false; AString := UTF8Lowercase(AString); case FCompareOperation of - coEqual : if AString = FCompareString then Result := true; + coEqual : Result := CompareStringWithWildCards(FCompareString, AString); coLess : if AString < FCompareString then Result := true; coGreater : if AString > FCompareString then Result := true; coLessEqual : if AString <= FCompareString then Result := true; coGreaterEqual : if AString >= FCompareString then Result := true; - coNotEqual : if AString <> FCompareString then Result := true; + coNotEqual : Result := not CompareStringWithWildCards(FCompareString, AString); end; end;