sc/qa/unit/data/xlsx/tdf156814.xlsx    |binary
 sc/qa/unit/ucalc_solver.cxx            |   48 +++++++++++++++++++++++--------
 sc/source/core/data/SolverSettings.cxx |   51 +++++++++++++++++++++++++++++++++
 3 files changed, 87 insertions(+), 12 deletions(-)

New commits:
commit d3049ab4786005c6bd17c66f8edcb98210bf511c
Author:     Rafael Lima <rafael.palma.l...@gmail.com>
AuthorDate: Fri Mar 8 21:49:47 2024 +0100
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Tue Mar 12 15:36:28 2024 +0100

    tdf#156814 Remove sheet name if range belongs to the same sheet (Solver)
    
    When solver models are imported from XLSX, ranges come with sheet names 
even when they belong to the same sheet, which clutter the solver dialog.
    
    This patch checks when this happens and remove sheet names when the solver 
model is imported.
    
    Change-Id: I3994f1312667946aab330c734ff820e94673d018
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164610
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/sc/qa/unit/data/xlsx/tdf156814.xlsx 
b/sc/qa/unit/data/xlsx/tdf156814.xlsx
new file mode 100644
index 000000000000..49e430b41554
Binary files /dev/null and b/sc/qa/unit/data/xlsx/tdf156814.xlsx differ
diff --git a/sc/qa/unit/ucalc_solver.cxx b/sc/qa/unit/ucalc_solver.cxx
index 7834597e9c07..f7db19cad59a 100644
--- a/sc/qa/unit/ucalc_solver.cxx
+++ b/sc/qa/unit/ucalc_solver.cxx
@@ -34,19 +34,19 @@ std::vector<ModelConstraint> 
SolverTest::CreateConstraintsModelA()
     std::vector<ModelConstraint> aConstraints;
 
     ModelConstraint aConstr1;
-    aConstr1.aLeftStr = "C1:C10";
+    aConstr1.aLeftStr = "$C$1:$C$10";
     aConstr1.nOperator = CO_LESS_EQUAL;
     aConstr1.aRightStr = "100";
     aConstraints.push_back(aConstr1);
 
     ModelConstraint aConstr2;
-    aConstr2.aLeftStr = "F5";
+    aConstr2.aLeftStr = "$F$5";
     aConstr2.nOperator = CO_EQUAL;
     aConstr2.aRightStr = "500";
     aConstraints.push_back(aConstr2);
 
     ModelConstraint aConstr3;
-    aConstr3.aLeftStr = "D1:D5";
+    aConstr3.aLeftStr = "$D$1:$D$5";
     aConstr3.nOperator = CO_BINARY;
     aConstr3.aRightStr = "";
     aConstraints.push_back(aConstr3);
@@ -59,15 +59,15 @@ void SolverTest::TestConstraintsModelA(SolverSettings* 
pSettings)
 {
     std::vector<ModelConstraint> aConstraints = pSettings->GetConstraints();
 
-    CPPUNIT_ASSERT_EQUAL(OUString("C1:C10"), aConstraints[0].aLeftStr);
+    CPPUNIT_ASSERT_EQUAL(OUString("$C$1:$C$10"), aConstraints[0].aLeftStr);
     CPPUNIT_ASSERT_EQUAL(CO_LESS_EQUAL, aConstraints[0].nOperator);
     CPPUNIT_ASSERT_EQUAL(OUString("100"), aConstraints[0].aRightStr);
 
-    CPPUNIT_ASSERT_EQUAL(OUString("F5"), aConstraints[1].aLeftStr);
+    CPPUNIT_ASSERT_EQUAL(OUString("$F$5"), aConstraints[1].aLeftStr);
     CPPUNIT_ASSERT_EQUAL(CO_EQUAL, aConstraints[1].nOperator);
     CPPUNIT_ASSERT_EQUAL(OUString("500"), aConstraints[1].aRightStr);
 
-    CPPUNIT_ASSERT_EQUAL(OUString("D1:D5"), aConstraints[2].aLeftStr);
+    CPPUNIT_ASSERT_EQUAL(OUString("$D$1:$D$5"), aConstraints[2].aLeftStr);
     CPPUNIT_ASSERT_EQUAL(CO_BINARY, aConstraints[2].nOperator);
     CPPUNIT_ASSERT_EQUAL(OUString(""), aConstraints[2].aRightStr);
 }
@@ -93,19 +93,19 @@ CPPUNIT_TEST_FIXTURE(SolverTest, testSingleModel)
     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), 
pSettings->GetParameter(SP_CONSTR_COUNT).toInt32());
 
     // Create a simple model
-    pSettings->SetParameter(SP_OBJ_CELL, OUString("A1"));
+    pSettings->SetParameter(SP_OBJ_CELL, OUString("$A$1"));
     pSettings->SetParameter(SP_OBJ_TYPE, OUString::number(OT_MINIMIZE));
     pSettings->SetParameter(SP_OBJ_VAL, OUString::number(0));
-    pSettings->SetParameter(SP_VAR_CELLS, OUString("D1:D5"));
+    pSettings->SetParameter(SP_VAR_CELLS, OUString("$D$1:$D$5"));
     std::vector<ModelConstraint> aConstraints = CreateConstraintsModelA();
     pSettings->SetConstraints(aConstraints);
 
     // Test if the model parameters were set
-    CPPUNIT_ASSERT_EQUAL(OUString("A1"), pSettings->GetParameter(SP_OBJ_CELL));
+    CPPUNIT_ASSERT_EQUAL(OUString("$A$1"), 
pSettings->GetParameter(SP_OBJ_CELL));
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(OT_MINIMIZE),
                          pSettings->GetParameter(SP_OBJ_TYPE).toInt32());
     CPPUNIT_ASSERT_EQUAL(OUString("0"), pSettings->GetParameter(SP_OBJ_VAL));
-    CPPUNIT_ASSERT_EQUAL(OUString("D1:D5"), 
pSettings->GetParameter(SP_VAR_CELLS));
+    CPPUNIT_ASSERT_EQUAL(OUString("$D$1:$D$5"), 
pSettings->GetParameter(SP_VAR_CELLS));
 
     // Test if the constraints were correctly set before saving
     CPPUNIT_ASSERT_EQUAL(sal_Int32(3), 
pSettings->GetParameter(SP_CONSTR_COUNT).toInt32());
@@ -120,11 +120,11 @@ CPPUNIT_TEST_FIXTURE(SolverTest, testSingleModel)
     CPPUNIT_ASSERT(pSettings);
 
     // Test if the model parameters remain set in the file
-    CPPUNIT_ASSERT_EQUAL(OUString("A1"), pSettings->GetParameter(SP_OBJ_CELL));
+    CPPUNIT_ASSERT_EQUAL(OUString("$A$1"), 
pSettings->GetParameter(SP_OBJ_CELL));
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(OT_MINIMIZE),
                          pSettings->GetParameter(SP_OBJ_TYPE).toInt32());
     CPPUNIT_ASSERT_EQUAL(OUString("0"), pSettings->GetParameter(SP_OBJ_VAL));
-    CPPUNIT_ASSERT_EQUAL(OUString("D1:D5"), 
pSettings->GetParameter(SP_VAR_CELLS));
+    CPPUNIT_ASSERT_EQUAL(OUString("$D$1:$D$5"), 
pSettings->GetParameter(SP_VAR_CELLS));
 
     // Test if the constraints remain correct after saving
     CPPUNIT_ASSERT_EQUAL(sal_Int32(3), 
pSettings->GetParameter(SP_CONSTR_COUNT).toInt32());
@@ -192,4 +192,28 @@ CPPUNIT_TEST_FIXTURE(SolverTest, tdf158735)
     CPPUNIT_ASSERT_EQUAL(OUString("80"), 
pSettings->GetParameter(SP_STAGNATION_LIMIT));
 }
 
+// Tests if range addresses from XLSX files that belong to the same sheet are 
not imported
+// with the sheet name, since it is unnecessary and clutters the dialog
+CPPUNIT_TEST_FIXTURE(SolverTest, tdf156814)
+{
+    createScDoc("xlsx/tdf156814.xlsx");
+    ScDocument* pDoc = getScDoc();
+
+    ScTable* pTable = pDoc->FetchTable(0);
+    std::shared_ptr<sc::SolverSettings> pSettings = 
pTable->GetSolverSettings();
+    CPPUNIT_ASSERT(pSettings);
+    // Ranges must not contain the sheet name
+    CPPUNIT_ASSERT_EQUAL(OUString("$F$2"), 
pSettings->GetParameter(SP_OBJ_CELL));
+    CPPUNIT_ASSERT_EQUAL(OUString("$A$2:$A$11,$C$2:$D$11"), 
pSettings->GetParameter(SP_VAR_CELLS));
+
+    // Check also the constraints (ranges must not contain sheet name either)
+    std::vector<ModelConstraint> aConstraints = pSettings->GetConstraints();
+    CPPUNIT_ASSERT_EQUAL(OUString("$H$2:$H$11"), aConstraints[0].aLeftStr);
+    CPPUNIT_ASSERT_EQUAL(OUString("$I$2:$I$11"), aConstraints[0].aRightStr);
+    CPPUNIT_ASSERT_EQUAL(OUString("$H$2:$H$11"), aConstraints[1].aLeftStr);
+    CPPUNIT_ASSERT_EQUAL(OUString("10"), aConstraints[1].aRightStr);
+    CPPUNIT_ASSERT_EQUAL(OUString("$I$2:$I$11"), aConstraints[2].aLeftStr);
+    CPPUNIT_ASSERT_EQUAL(OUString("0"), aConstraints[2].aRightStr);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sc/source/core/data/SolverSettings.cxx 
b/sc/source/core/data/SolverSettings.cxx
index 64badb8c2790..dd618d1e868b 100644
--- a/sc/source/core/data/SolverSettings.cxx
+++ b/sc/source/core/data/SolverSettings.cxx
@@ -9,9 +9,11 @@
  */
 
 #include <global.hxx>
+#include <compiler.hxx>
 #include <table.hxx>
 #include <docsh.hxx>
 #include <rtl/math.hxx>
+#include <o3tl/string_view.hxx>
 #include <solverutil.hxx>
 #include <unotools/charclass.hxx>
 #include <SolverSettings.hxx>
@@ -412,6 +414,12 @@ bool SolverSettings::ReadConstraintPart(ConstraintPart 
ePart, tools::Long nIndex
     if (pRangeData)
     {
         rValue = pRangeData->GetSymbol();
+        // tdf#156814 Remove sheet name if it is a range that refers to the 
same sheet
+        ScRange aRange;
+        ScRefFlags nFlags = aRange.ParseAny(rValue, m_rDoc);
+        bool bIsValidRange = (nFlags & ScRefFlags::VALID) == ScRefFlags::VALID;
+        if (bIsValidRange && m_rTable.GetTab() == aRange.aStart.Tab())
+            rValue = aRange.Format(m_rDoc, ScRefFlags::RANGE_ABS);
         return true;
     }
     return false;
@@ -521,6 +529,49 @@ bool SolverSettings::ReadParamValue(SolverParameter 
eParam, OUString& rValue, bo
         rValue = pRangeData->GetSymbol();
         if (bRemoveQuotes)
             ScGlobal::EraseQuotes(rValue, '"');
+
+        // tdf#156814 Remove sheet name from the objective cell and value if 
they refer to the same sheet
+        if (eParam == SP_OBJ_CELL || eParam == SP_OBJ_VAL)
+        {
+            ScRange aRange;
+            ScRefFlags nFlags = aRange.ParseAny(rValue, m_rDoc);
+            bool bIsValidRange = ((nFlags & ScRefFlags::VALID) == 
ScRefFlags::VALID);
+
+            if (bIsValidRange && m_rTable.GetTab() == aRange.aStart.Tab())
+                rValue = aRange.Format(m_rDoc, ScRefFlags::RANGE_ABS);
+        }
+        else if (eParam == SP_VAR_CELLS)
+        {
+            // Variable cells may contain multiple ranges separated by ';'
+            sal_Int32 nIdx = 0;
+            OUString sNewValue;
+            bool bFirst = true;
+            // Delimiter character to separate ranges
+            sal_Unicode cDelimiter = 
ScCompiler::GetNativeSymbolChar(OpCode::ocSep);
+
+            do
+            {
+                OUString aRangeStr(o3tl::getToken(rValue, 0, cDelimiter, 
nIdx));
+                ScRange aRange;
+                ScRefFlags nFlags = aRange.ParseAny(aRangeStr, m_rDoc);
+                bool bIsValidRange = (nFlags & ScRefFlags::VALID) == 
ScRefFlags::VALID;
+
+                if (bIsValidRange && m_rTable.GetTab() == aRange.aStart.Tab())
+                    aRangeStr = aRange.Format(m_rDoc, ScRefFlags::RANGE_ABS);
+
+                if (bFirst)
+                {
+                    sNewValue = aRangeStr;
+                    bFirst = false;
+                }
+                else
+                {
+                    sNewValue += OUStringChar(cDelimiter) + aRangeStr;
+                }
+            } while (nIdx > 0);
+
+            rValue = sNewValue;
+        }
         return true;
     }
     return false;

Reply via email to