1 diff --git sc/source/core/inc/interpre.hxx sc/source/core/inc/interpre.hxx
2 index b9b91a8..681766d 100644
3 --- sc/source/core/inc/interpre.hxx
4 +++ sc/source/core/inc/interpre.hxx
5 @@ -178,8 +178,18 @@ void ReplaceCell( ScAddress& ); // for TableOp
6 void ReplaceCell( SCCOL& rCol, SCROW& rRow, SCTAB& rTab ); // for TableOp
7 BOOL IsTableOpInRange( const ScRange& );
8 ULONG GetCellNumberFormat( const ScAddress&, const ScBaseCell* );
9 -double GetCellValue( const ScAddress&, const ScBaseCell* );
10 -double GetCellValueOrZero( const ScAddress&, const ScBaseCell* );
13 + * @param bNoValueAsError when true, cell having no numerical value
14 + * (errCellNoValue) is interpreted as a legitimate
15 + * no-value (errNoValue) error.
16 + * @param bBlankAsZero when true, a cell having a blank text value is
17 + * interpreted as a no-value error.
19 + * @return double cell value.
21 +double GetCellValue( const ScAddress&, const ScBaseCell*, bool bNoValueAsError = false, bool bBlankAsZero = false );
22 +double GetCellValueOrZero( const ScAddress&, const ScBaseCell*, bool bBlankAsZero );
23 double GetValueCellValue( const ScAddress&, const ScValueCell* );
24 ScBaseCell* GetCell( const ScAddress& rPos )
25 { return pDok->GetCell( rPos ); }
26 @@ -318,7 +328,7 @@ formula::StackVar GetStackType( BYTE nParam );
27 BYTE GetByte() { return cPar; }
28 // generiert aus DoubleRef positionsabhaengige SingleRef
29 BOOL DoubleRefToPosSingleRef( const ScRange& rRange, ScAddress& rAdr );
31 +double GetDouble( bool bNoValueAsError = false, bool bBlankAsZero = false );
32 double GetDoubleWithDefault(double nDefault);
34 BOOL GetBool() { return GetDouble() != 0.0; }
35 diff --git sc/source/core/tool/interpr1.cxx sc/source/core/tool/interpr1.cxx
36 index 5a6eb67..7e5a478 100644
37 --- sc/source/core/tool/interpr1.cxx
38 +++ sc/source/core/tool/interpr1.cxx
39 @@ -3189,12 +3189,13 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, BOOL bTextAsZero )
41 while (nParamCount-- > 0)
43 - switch (GetStackType())
44 + StackVar eStackType = GetStackType();
51 - if( eFunc == ifCOUNT )
52 + if( eFunc == ifCOUNT && eStackType == svString )
54 String aStr( PopString() );
55 sal_uInt32 nFIndex = 0; // damit default Land/Spr.
56 @@ -3203,42 +3204,23 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, BOOL bTextAsZero )
60 + if ( bTextAsZero && eStackType == svString )
64 + if ( eFunc == ifPRODUCT )
84 - if ( eFunc == ifPRODUCT )
89 - while (nParamCount-- > 0)
91 - SetError( errNoValue );
103 - fVal = GetDouble();
109 if ( bNull && fVal != 0.0 )
112 @@ -3247,12 +3229,15 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, BOOL bTextAsZero )
116 - case ifSUMSQ: fRes += fVal * fVal; break;
117 - case ifPRODUCT: fRes *= fVal; break;
118 - default: ; // nothing
119 + case ifSUMSQ: fRes += fVal * fVal; break;
120 + case ifPRODUCT: fRes *= fVal; break;
125 nFuncFmtType = NUMBERFORMAT_NUMBER;
131 PopSingleRef( aAdr );
132 diff --git sc/source/core/tool/interpr4.cxx sc/source/core/tool/interpr4.cxx
133 index cd2fccc..ef0d533 100644
134 --- sc/source/core/tool/interpr4.cxx
135 +++ sc/source/core/tool/interpr4.cxx
136 @@ -207,19 +207,27 @@ double ScInterpreter::GetValueCellValue( const ScAddress& rPos, const ScValueCel
140 -double ScInterpreter::GetCellValue( const ScAddress& rPos, const ScBaseCell* pCell )
141 +double ScInterpreter::GetCellValue( const ScAddress& rPos, const ScBaseCell* pCell,
142 + bool bNoValueAsError, bool bBlankAsZero )
144 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetCellValue" );
145 USHORT nErr = nGlobalError;
147 - double nVal = GetCellValueOrZero( rPos, pCell );
148 - if ( !nGlobalError || nGlobalError == errCellNoValue )
149 + double nVal = GetCellValueOrZero( rPos, pCell, bBlankAsZero );
151 + // no global error. good.
153 + else if (nGlobalError == errCellNoValue)
154 + // Internal cell-no-value error. If the caller wants to treat no
155 + // value as error, then we need to translate this to a legitimate
156 + // error number (#VALUE!). If not, we should re-assign the prior error
158 + nGlobalError = bNoValueAsError ? errNoValue : nErr;
163 -double ScInterpreter::GetCellValueOrZero( const ScAddress& rPos, const ScBaseCell* pCell )
164 +double ScInterpreter::GetCellValueOrZero( const ScAddress& rPos, const ScBaseCell* pCell, bool bBlankAsZero )
166 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetCellValueOrZero" );
168 @@ -264,7 +272,7 @@ double ScInterpreter::GetCellValueOrZero( const ScAddress& rPos, const ScBaseCel
170 case CELLTYPE_STRING:
173 +#if 1 /* JEG : re-enable because compatibility is more important than consistency for this */
174 // Xcl does it, but SUM(A1:A2) differs from A1+A2. No good.
177 @@ -275,14 +283,15 @@ double ScInterpreter::GetCellValueOrZero( const ScAddress& rPos, const ScBaseCel
178 sal_uInt32 nFIndex = 0; // damit default Land/Spr.
179 if ( !pFormatter->IsNumberFormat( aStr, nFIndex, fValue ) )
181 - SetError(errNoValue);
182 + SetError(errCellNoValue); /* CellNoValue is not really an error */
189 - SetError(errCellNoValue);
191 + SetError(errCellNoValue);
195 @@ -1621,7 +1630,7 @@ BOOL ScInterpreter::DoubleRefToPosSingleRef( const ScRange& rRange, ScAddress& r
199 -double ScInterpreter::GetDouble()
200 +double ScInterpreter::GetDouble( bool bNoValueAsError, bool bBlankAsZero )
202 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetDouble" );
204 @@ -1646,7 +1655,7 @@ double ScInterpreter::GetDouble()
206 PopSingleRef( aAdr );
207 ScBaseCell* pCell = GetCell( aAdr );
208 - nVal = GetCellValue( aAdr, pCell );
209 + nVal = GetCellValue( aAdr, pCell, bNoValueAsError, bBlankAsZero );
213 diff --git sc/source/core/tool/interpr5.cxx sc/source/core/tool/interpr5.cxx
214 index 5b05f0c..c5b4770 100644
215 --- sc/source/core/tool/interpr5.cxx
216 +++ sc/source/core/tool/interpr5.cxx
217 @@ -1184,7 +1184,12 @@ void ScInterpreter::CalculateAddSub(BOOL _bSub)
221 - fVal2 = GetDouble();
222 + fVal2 = GetDouble(true, true);
225 + PushError(nGlobalError);
228 switch ( nCurFmtType )
230 case NUMBERFORMAT_DATE :
231 @@ -1205,7 +1210,12 @@ void ScInterpreter::CalculateAddSub(BOOL _bSub)
235 - fVal1 = GetDouble();
236 + fVal1 = GetDouble(true, true);
239 + PushError(nGlobalError);
242 switch ( nCurFmtType )
244 case NUMBERFORMAT_DATE :
245 @@ -1414,7 +1424,12 @@ void ScInterpreter::ScMul()
249 - fVal2 = GetDouble();
250 + fVal2 = GetDouble(true, true);
253 + PushError(nGlobalError);
256 switch ( nCurFmtType )
258 case NUMBERFORMAT_CURRENCY :
259 @@ -1427,7 +1442,12 @@ void ScInterpreter::ScMul()
263 - fVal1 = GetDouble();
264 + fVal1 = GetDouble(true, true);
267 + PushError(nGlobalError);
270 switch ( nCurFmtType )
272 case NUMBERFORMAT_CURRENCY :
273 @@ -1494,7 +1514,12 @@ void ScInterpreter::ScDiv()
277 - fVal2 = GetDouble();
278 + fVal2 = GetDouble(true, true);
281 + PushError(nGlobalError);
284 // hier kein Currency uebernehmen, 123kg/456DM sind nicht DM
285 nFmtCurrencyType2 = nCurFmtType;
287 @@ -1502,7 +1527,12 @@ void ScInterpreter::ScDiv()
291 - fVal1 = GetDouble();
292 + fVal1 = GetDouble(true, true);
295 + PushError(nGlobalError);
298 switch ( nCurFmtType )
300 case NUMBERFORMAT_CURRENCY :