diff options
author | Kohei Yoshida <kyoshida@novell.com> | 2011-06-08 12:53:21 -0400 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2011-06-09 05:51:18 +0200 |
commit | d90ae9eb4072dc0cad8559074c776aa2cc7034ff (patch) | |
tree | 2538958e2749f4ad33051f65adfef6aefd613650 | |
parent | 64efccba4635fbe713cc5d78ae0fdc8494abe049 (diff) |
fdo#33705: Fixed cell function N.
Also added unit test for this built-in function.
-rw-r--r-- | sc/qa/unit/ucalc.cxx | 64 | ||||
-rw-r--r-- | sc/source/core/tool/interpr1.cxx | 48 |
2 files changed, 97 insertions, 15 deletions
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index 7a6d46e13..835f08508 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -60,6 +60,7 @@ #include "drwlayer.hxx" #include "scitems.hxx" #include "reffind.hxx" +#include "markdata.hxx" #include "docsh.hxx" #include "funcdesc.hxx" @@ -422,6 +423,69 @@ void Test::testCellFunctions() m_pDoc->GetValue(0, 4, 0, result); CPPUNIT_ASSERT_MESSAGE("Calculation of PRODUCT with inline array failed", result == 6.0); + { + // N + + // Clear the area first. + ScMarkData aMarkData; + aMarkData.SetMarkArea(ScRange(0, 0, 0, 1, 20, 0)); + m_pDoc->DeleteArea(0, 0, 1, 20, aMarkData, IDF_CONTENTS); + + // Put values to reference. + val = 0; + m_pDoc->SetValue(0, 0, 0, val); + m_pDoc->SetString(0, 2, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("Text"))); + val = 1; + m_pDoc->SetValue(0, 3, 0, val); + val = -1; + m_pDoc->SetValue(0, 4, 0, val); + val = 12.3; + m_pDoc->SetValue(0, 5, 0, val); + m_pDoc->SetString(0, 6, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("'12.3"))); + + // Cell references + m_pDoc->SetString(1, 0, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(A1)"))); + m_pDoc->SetString(1, 1, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(A2)"))); + m_pDoc->SetString(1, 2, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(A3)"))); + m_pDoc->SetString(1, 3, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(A4)"))); + m_pDoc->SetString(1, 4, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(A5)"))); + m_pDoc->SetString(1, 5, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(A6)"))); + m_pDoc->SetString(1, 6, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(A9)"))); + + // In-line values + m_pDoc->SetString(1, 7, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(0)"))); + m_pDoc->SetString(1, 8, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(1)"))); + m_pDoc->SetString(1, 9, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(-1)"))); + m_pDoc->SetString(1, 10, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(123)"))); + m_pDoc->SetString(1, 11, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(\"\")"))); + m_pDoc->SetString(1, 12, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(\"12\")"))); + m_pDoc->SetString(1, 13, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(\"foo\")"))); + + // Range references + m_pDoc->SetString(1, 14, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(A1:A8)"))); + m_pDoc->SetString(1, 15, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(A4:B8)"))); + m_pDoc->SetString(1, 16, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(A6:B8)"))); + m_pDoc->SetString(1, 17, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(A2:B8)"))); + + // Calculate and check the results. + m_pDoc->CalcAll(); + double checks[] = { + 0, 0, 0, 1, -1, 12.3, 0, // cell reference + 0, 1, -1, 123, 0, 0, 0, // in-line values + 0, 1, 12.3, 0 // range references + }; + for (size_t i = 0; i < SAL_N_ELEMENTS(checks); ++i) + { + m_pDoc->GetValue(1, i, 0, result); + bool bGood = result == checks[i]; + if (!bGood) + { + cerr << "row " << (i+1) << ": expected=" << checks[i] << " actual=" << result << endl; + CPPUNIT_ASSERT_MESSAGE("Unexpected result for N", false); + } + } + } + m_pDoc->DeleteTab(0); } diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index 1999bff58..2327e94fb 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -2509,26 +2509,44 @@ void ScInterpreter::ScIsOdd() PushInt( !IsEven() ); } - void ScInterpreter::ScN() { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScN" ); - sal_uInt16 nErr = nGlobalError; - nGlobalError = 0; - // Temporarily override the ConvertStringToValue() error for - // GetCellValue() / GetCellValueOrZero() - sal_uInt16 nSErr = mnStringNoValueError; - mnStringNoValueError = errCellNoValue; + switch (GetRawStackType()) + { + case svSingleRef: + case svDoubleRef: + case svMatrix: + case svExternalSingleRef: + case svExternalDoubleRef: + { + ScMatrixRef pMat = GetMatrix(); + SCSIZE nC, nR; + pMat->GetDimensions(nC, nR); + if (!nC || !nR) + PushDouble(0); + else + PushDouble(pMat->GetDouble(0, 0)); + return; + } + case svString: + PushDouble(0); + return; + default: + ; + } + + // Default action double fVal = GetDouble(); - mnStringNoValueError = nSErr; - if ( nGlobalError == NOTAVAILABLE || nGlobalError == errCellNoValue ) - nGlobalError = 0; // N(#NA) and N("text") are ok - if ( !nGlobalError && nErr != NOTAVAILABLE ) - nGlobalError = nErr; - PushDouble( fVal ); + if (nGlobalError) + { + // Don't propagate the error. Push 0 instead. + nGlobalError = 0; + PushDouble(0); + return; + } + PushDouble(fVal); } - void ScInterpreter::ScTrim() { // Doesn't only trim but writes out twice! String aVal( GetString() ); |