summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kyoshida@novell.com>2011-06-08 12:53:21 -0400
committerMarkus Mohrhard <markus.mohrhard@googlemail.com>2011-06-09 05:51:18 +0200
commitd90ae9eb4072dc0cad8559074c776aa2cc7034ff (patch)
tree2538958e2749f4ad33051f65adfef6aefd613650
parent64efccba4635fbe713cc5d78ae0fdc8494abe049 (diff)
fdo#33705: Fixed cell function N.
Also added unit test for this built-in function.
-rw-r--r--sc/qa/unit/ucalc.cxx64
-rw-r--r--sc/source/core/tool/interpr1.cxx48
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() );