sc/qa/unit/ucalc_formula.cxx | 29 ++++++++++++++++++++++++++ sc/source/core/tool/interpr6.cxx | 42 +++++++++++++++++++++++++++++++++++---- 2 files changed, 66 insertions(+), 5 deletions(-)
New commits: commit d658c092f488fc0d4cb924fe3e34cab997db76e2 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Fri Mar 7 18:03:24 2014 -0500 fdo#75628: SUM should inherit error if one is present in its references. Change-Id: I94017fe91295dbb929f57be5e3fb26edf5032a8f diff --git a/sc/source/core/tool/interpr6.cxx b/sc/source/core/tool/interpr6.cxx index a32b3c1..b98fb9b 100644 --- a/sc/source/core/tool/interpr6.cxx +++ b/sc/source/core/tool/interpr6.cxx @@ -210,8 +210,10 @@ namespace { class NumericCellAccumulator { double mfSum; + sal_uInt16 mnError; + public: - NumericCellAccumulator() : mfSum(0.0) {} + NumericCellAccumulator() : mfSum(0.0), mnError(0) {} void operator() (size_t, double fVal) { @@ -220,11 +222,28 @@ public: void operator() (size_t, const ScFormulaCell* pCell) { + if (mnError) + // Skip all the rest if we have an error. + return; + + double fVal = 0.0; + sal_uInt16 nErr = 0; ScFormulaCell& rCell = const_cast<ScFormulaCell&>(*pCell); - if (rCell.IsValue()) - mfSum += rCell.GetValue(); + if (!rCell.GetErrorOrValue(nErr, fVal)) + // The cell has neither error nor value. Perhaps string result. + return; + + if (nErr) + { + // Cell has error. + mnError = nErr; + return; + } + + mfSum += fVal; } + sal_uInt16 getError() const { return mnError; } double getSum() const { return mfSum; } }; @@ -299,10 +318,11 @@ class FuncSum : public sc::ColumnSpanSet::ColumnAction sc::ColumnBlockConstPosition maPos; ScColumn* mpCol; double mfSum; + sal_uInt16 mnError; sal_uInt32 mnNumFmt; public: - FuncSum() : mpCol(0), mfSum(0.0), mnNumFmt(0) {} + FuncSum() : mpCol(0), mfSum(0.0), mnError(0), mnNumFmt(0) {} virtual void startColumn(ScColumn* pCol) { @@ -315,12 +335,20 @@ public: if (!bVal) return; + if (mnError) + return; + NumericCellAccumulator aFunc; maPos.miCellPos = sc::ParseFormulaNumeric(maPos.miCellPos, mpCol->GetCellStore(), nRow1, nRow2, aFunc); + mnError = aFunc.getError(); + if (mnError) + return; + mfSum += aFunc.getSum(); mnNumFmt = mpCol->GetNumberFormat(nRow2); }; + sal_uInt16 getError() const { return mnError; } double getSum() const { return mfSum; } sal_uInt32 getNumberFormat() const { return mnNumFmt; } }; @@ -806,6 +834,12 @@ void ScInterpreter::ScSum() FuncSum aAction; aSet.executeColumnAction(*pDok, aAction); + sal_uInt16 nErr = aAction.getError(); + if (nErr) + { + SetError(nErr); + return; + } fRes += aAction.getSum(); // Get the number format of the last iterated cell. commit 78e6b7a94265507e43dd80182706970f49cdb303 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Fri Mar 7 18:00:24 2014 -0500 fdo#75628: Write unit test for this. Change-Id: I26e5d0bf4344eeb518222ba036c61eca861c5fcf diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx index 580e2a3..f4c6f7a 100644 --- a/sc/qa/unit/ucalc_formula.cxx +++ b/sc/qa/unit/ucalc_formula.cxx @@ -1841,6 +1841,8 @@ void Test::testFuncSUM() CPPUNIT_ASSERT_MESSAGE ("failed to insert sheet", m_pDoc->InsertTab (0, aTabName)); + sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn on auto calc. + // Single argument case. m_pDoc->SetValue(ScAddress(0,0,0), 1); m_pDoc->SetValue(ScAddress(0,1,0), 1); @@ -1864,11 +1866,36 @@ void Test::testFuncSUM() m_pDoc->SetString(ScAddress(3,0,0), "=SUM(A1:A2;B1:B2)"); m_pDoc->SetString(ScAddress(3,1,0), "=SUM(A2:A3;B2:B3)"); m_pDoc->SetString(ScAddress(3,2,0), "=SUM(A3:A4;B3:B4)"); - m_pDoc->CalcAll(); CPPUNIT_ASSERT_EQUAL(30.0, m_pDoc->GetValue(ScAddress(3,0,0))); CPPUNIT_ASSERT_EQUAL(35.0, m_pDoc->GetValue(ScAddress(3,1,0))); CPPUNIT_ASSERT_EQUAL(20.0, m_pDoc->GetValue(ScAddress(3,2,0))); + // Clear and start over. + clearRange(m_pDoc, ScRange(0,0,0,3,MAXROW,0)); + + // SUM needs to take the first error in case the range contains an error. + m_pDoc->SetValue(ScAddress(0,0,0), 1.0); + m_pDoc->SetValue(ScAddress(0,1,0), 10.0); + m_pDoc->SetValue(ScAddress(0,2,0), 100.0); + m_pDoc->SetString(ScAddress(0,3,0), "=SUM(A1:A3)"); + CPPUNIT_ASSERT_EQUAL(111.0, m_pDoc->GetValue(ScAddress(0,3,0))); + + // Set #DIV/0! error to A3. A4 should also inherit this error. + m_pDoc->SetString(ScAddress(0,2,0), "=1/0"); + sal_uInt16 nErr = m_pDoc->GetErrCode(ScAddress(0,2,0)); + CPPUNIT_ASSERT_MESSAGE("Cell should have a division by zero error.", + nErr == errDivisionByZero); + nErr = m_pDoc->GetErrCode(ScAddress(0,3,0)); + CPPUNIT_ASSERT_MESSAGE("SUM should have also inherited a div-by-zero error.", + nErr == errDivisionByZero); + + // Set #NA! to A2. A4 should now inherit this error. + m_pDoc->SetString(ScAddress(0,1,0), "=NA()"); + nErr = m_pDoc->GetErrCode(ScAddress(0,1,0)); + CPPUNIT_ASSERT_MESSAGE("A2 should be an error.", nErr); + CPPUNIT_ASSERT_MESSAGE("A4 should have inherited the same error as A2.", + nErr == m_pDoc->GetErrCode(ScAddress(0,3,0))); + m_pDoc->DeleteTab(0); } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits