sc/qa/unit/ucalc_formula.cxx     |    2 +-
 sc/source/core/tool/compiler.cxx |    9 +++++++--
 2 files changed, 8 insertions(+), 3 deletions(-)

New commits:
commit 969ddf72824942be9755a8d14482d6549a2231ce
Author:     Balazs Varga <balazs.varga.ext...@allotropia.de>
AuthorDate: Wed Apr 10 17:48:20 2024 +0100
Commit:     Gabor Kelemen <gabor.kelemen.ext...@allotropia.de>
CommitDate: Thu Apr 11 16:12:58 2024 +0200

    tdf#160616 - Fix SUMPRODUCT calculation is broken in some cases
    
    Double refs with operators only trimmable in case of one root paramater.
    
    Follow up of: ba0ec4a5d2b025b675410cd18890d1cca3bc5a2f
    
    Change-Id: If61fb39696d9539ffc9d32a6ecad79bfa1bf92e5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165957
    Tested-by: Gabor Kelemen <gabor.kelemen.ext...@allotropia.de>
    Tested-by: Jenkins
    Reviewed-by: Gabor Kelemen <gabor.kelemen.ext...@allotropia.de>

diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index adbc9c121042..105c7e4a772d 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -1464,7 +1464,7 @@ CPPUNIT_TEST_FIXTURE(TestFormula, 
testFormulaAnnotateTrimOnDoubleRefs)
 
         {
             "=SUMPRODUCT(A:A=$C$1; 1-(A:A=$C$1))",
-            ScRange(0, 0, 0, 0, 1048575, 0),
+            ScRange(-1, -1, -1, -1, -1, -1),     // Has no trimmable 
double-ref.
             0.0,
             false                                // Not in matrix mode.
         },
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 7b655d72c944..a0529fbe0f4e 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -6468,6 +6468,8 @@ void ScCompiler::AnnotateTrimOnDoubleRefs()
 
     // OpCode of the "root" operator (which is already in RPN array).
     OpCode eOpCode = (*(pCode - 1))->GetOpCode();
+    // Param number of the "root" operator (which is already in RPN array).
+    sal_uInt8 nRootParam = (*(pCode - 1))->GetByte();
     // eOpCode can be some operator which does not change with operands with 
or contains zero values.
     if (eOpCode == ocSum)
     {
@@ -6560,7 +6562,8 @@ void ScCompiler::AnnotateTrimOnDoubleRefs()
         // such that one of the operands of ocEqual is a double-ref.
         // Examples of formula that matches this are:
         //   SUMPRODUCT(IF($A:$A=$L12;$D:$D*G:G))
-        // Also in case of DoubleRef arguments around other Binary operators 
can be trimmable:
+        // Also in case of DoubleRef arguments around other Binary operators 
can be trimmable inside one parameter
+        // of the root operator:
         //   SUMPRODUCT(($D:$D>M47:M47)*($D:$D<M48:M48)*($I:$I=N$41))
         bool bTillClose = true;
         bool bCloseTillIf = false;
@@ -6612,7 +6615,9 @@ void ScCompiler::AnnotateTrimOnDoubleRefs()
                 case ocUnion:
                 case ocRange:
                     {
-                        if (!pTok->IsInForceArray())
+                        // tdf#160616: Double refs with these operators only
+                        // trimmable in case of one paramater
+                        if (!pTok->IsInForceArray() || nRootParam > 1)
                             break;
                         FormulaToken* pLHS = *(ppTok - 1);
                         FormulaToken* pRHS = *(ppTok - 2);

Reply via email to