diff options
-rw-r--r-- | formula/source/core/api/FormulaCompiler.cxx | 3 | ||||
-rw-r--r-- | sc/inc/dociter.hxx | 19 | ||||
-rw-r--r-- | sc/inc/global.hxx | 7 | ||||
-rw-r--r-- | sc/qa/unit/data/xlsx/functions-excel-2010.xlsx | bin | 16074 -> 21127 bytes | |||
-rw-r--r-- | sc/qa/unit/helper/shared_test_impl.hxx | 4 | ||||
-rw-r--r-- | sc/qa/unit/ucalc.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/dociter.cxx | 132 | ||||
-rw-r--r-- | sc/source/core/data/formulacell.cxx | 9 | ||||
-rw-r--r-- | sc/source/core/inc/interpre.hxx | 2 | ||||
-rw-r--r-- | sc/source/core/tool/interpr1.cxx | 45 | ||||
-rw-r--r-- | sc/source/core/tool/interpr2.cxx | 6 | ||||
-rw-r--r-- | sc/source/core/tool/interpr3.cxx | 14 | ||||
-rw-r--r-- | sc/source/core/tool/interpr4.cxx | 3 | ||||
-rw-r--r-- | sc/source/core/tool/interpr5.cxx | 4 | ||||
-rw-r--r-- | sc/source/core/tool/interpr6.cxx | 573 | ||||
-rw-r--r-- | sc/source/ui/src/scfuncs.src | 2 |
16 files changed, 434 insertions, 391 deletions
diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx index 2e066af8d01d..5f63fcf9928a 100644 --- a/formula/source/core/api/FormulaCompiler.cxx +++ b/formula/source/core/api/FormulaCompiler.cxx @@ -1089,7 +1089,8 @@ bool FormulaCompiler::GetToken() mpToken = new FormulaByteToken( ocStop ); return false; } - if( mpToken->GetOpCode() == ocSubTotal ) + if ( mpToken->GetOpCode() == ocSubTotal || + mpToken->GetOpCode() == ocAggregate ) glSubTotal = true; else if ( mpToken->IsExternalRef() ) { diff --git a/sc/inc/dociter.hxx b/sc/inc/dociter.hxx index f0d82fe99573..f7f9b2bebc87 100644 --- a/sc/inc/dociter.hxx +++ b/sc/inc/dociter.hxx @@ -60,11 +60,11 @@ class ScValueIterator // walk through all values in an area SCCOL mnCol; SCTAB mnTab; SCROW nAttrEndRow; + sal_uInt16 mnSubTotalFlags; short nNumFmtType; - bool bNumValid:1; - bool bSubTotal:1; - bool bCalcAsShown:1; - bool bTextAsZero:1; + bool bNumValid; + bool bCalcAsShown; + bool bTextAsZero; const sc::CellStoreType* mpCells; PositionType maCurPos; @@ -83,7 +83,7 @@ class ScValueIterator // walk through all values in an area public: ScValueIterator( - ScDocument* pDocument, const ScRange& rRange, bool bSTotal = false, + ScDocument* pDocument, const ScRange& rRange, sal_uInt16 nSubTotalFlags = 0x00, bool bTextAsZero = false ); void GetCurNumFmtInfo( short& nType, sal_uLong& nIndex ); @@ -184,8 +184,7 @@ public: }; /** - * Walk through all cells in an area. For SubTotal no hidden and no - * sub-total lines. + * Walk through all cells in an area. For SubTotal and Aggregate depending on mnSubTotalFlags. **/ class ScCellIterator { @@ -197,7 +196,7 @@ class ScCellIterator ScAddress maCurPos; PositionType maCurColPos; - bool mbSubTotal; + sal_uInt16 mnSubTotalFlags; ScRefCellValue maCurCell; @@ -211,7 +210,7 @@ class ScCellIterator bool getCurrent(); public: - ScCellIterator( ScDocument* pDoc, const ScRange& rRange, bool bSTotal = false ); + ScCellIterator( ScDocument* pDoc, const ScRange& rRange, sal_uInt16 nSubTotalFlags = 0x00 ); const ScAddress& GetPos() const { return maCurPos; } @@ -462,7 +461,6 @@ private: SCROW nAttrEndRow; short nNumFmtType; bool bNumValid; - bool bSubTotal; bool bCalcAsShown; bool bTextAsZero; @@ -470,7 +468,6 @@ public: ScHorizontalValueIterator( ScDocument* pDocument, const ScRange& rRange, - bool bSTotal = false, bool bTextAsZero = false ); ~ScHorizontalValueIterator(); /// Does NOT reset rValue if no value found! diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx index 0614bce65c65..fb2e120cf465 100644 --- a/sc/inc/global.hxx +++ b/sc/inc/global.hxx @@ -234,9 +234,10 @@ const sal_uInt16 IDF_AUTOFILL = IDF_ALL & ~(IDF_NOTE | IDF_OBJECTS); #define SC_SCENARIO_VALUE 32 #define SC_SCENARIO_PROTECT 64 -#define AGGR_IGN_NESTED_ST_AG 0x04 -#define AGGR_IGN_ERR_VAL 0x02 -#define AGGR_IGN_HID_ROW 0x01 +#define SUBTOTAL_IGN_NESTED_ST_AG 0x08 +#define SUBTOTAL_IGN_ERR_VAL 0x04 +#define SUBTOTAL_IGN_HIDDEN 0x02 +#define SUBTOTAL_IGN_FILTERED 0x01 /** Default cell clone flags: do not start listening, do not adjust 3D refs to old position, clone note captions of cell notes. */ diff --git a/sc/qa/unit/data/xlsx/functions-excel-2010.xlsx b/sc/qa/unit/data/xlsx/functions-excel-2010.xlsx Binary files differindex c6d6ebb8abcc..152fbbc45a9f 100644 --- a/sc/qa/unit/data/xlsx/functions-excel-2010.xlsx +++ b/sc/qa/unit/data/xlsx/functions-excel-2010.xlsx diff --git a/sc/qa/unit/helper/shared_test_impl.hxx b/sc/qa/unit/helper/shared_test_impl.hxx index c339efa20c46..bc2ee65c036d 100644 --- a/sc/qa/unit/helper/shared_test_impl.hxx +++ b/sc/qa/unit/helper/shared_test_impl.hxx @@ -161,7 +161,7 @@ void testFunctionsExcel2010_Impl( ScDocument& rDoc ) SCROW nRow; bool bEvaluate; } aTests[] = { - { 2, false }, + { 2, false }, // name=[ AGGREGATE ], result=0, expected=1 { 3, true }, { 4, true }, { 5, true }, @@ -246,7 +246,7 @@ void testFunctionsExcel2010_Impl( ScDocument& rDoc ) { if (aTests[i].bEvaluate) { - // Column A is description, B is formula, C is Excel result, D is + // Column 0 is description, 1 is formula, 2 is Excel result, 3 is // comparison. SCROW nRow = aTests[i].nRow - 1; // 0-based diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index c0e1eb98f521..af272a54a532 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -2591,7 +2591,7 @@ void Test::testFunctionLists() "ACOSH", "ACOT", "ACOTH", -// "AGGREGATE", // fdo73148 function not yet visble in UI + "AGGREGATE", "ASIN", "ASINH", "ATAN", diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx index d6799d203a72..2c5a59710f4a 100644 --- a/sc/source/core/data/dociter.cxx +++ b/sc/source/core/data/dociter.cxx @@ -98,7 +98,7 @@ void ScAttrArray_IterGetNumberFormat( sal_uLong& nFormat, const ScAttrArray*& rp } ScValueIterator::ScValueIterator( ScDocument* pDocument, const ScRange& rRange, - bool bSTotal, bool bTextZero ) + sal_uInt16 nSubTotalFlags, bool bTextZero ) : pDoc(pDocument) , pAttrArray(NULL) , nNumFormat(0) // Initialized in GetNumberFormat @@ -108,9 +108,9 @@ ScValueIterator::ScValueIterator( ScDocument* pDocument, const ScRange& rRange, , mnCol(0) , mnTab(0) , nAttrEndRow(0) + , mnSubTotalFlags(nSubTotalFlags) , nNumFmtType(NUMBERFORMAT_UNDEFINED) , bNumValid(false) - , bSubTotal(bSTotal) , bCalcAsShown(pDocument->GetDocOptions().IsCalcAsShown()) , bTextAsZero(bTextZero) , mpCells(NULL) @@ -191,9 +191,12 @@ bool ScValueIterator::GetThis(double& rValue, sal_uInt16& rErr) SCROW nCurRow = GetRow(); SCROW nLastRow; - if (bSubTotal && pDoc->maTabs[mnTab]->RowFiltered(nCurRow, NULL, &nLastRow)) + // Skip all filtered or hidden rows, depending on mnSubTotalFlags + if ( ( ( mnSubTotalFlags & SUBTOTAL_IGN_FILTERED ) && + pDoc->RowFiltered( nCurRow, mnTab, NULL, &nLastRow ) ) || + ( ( mnSubTotalFlags & SUBTOTAL_IGN_HIDDEN ) && + pDoc->RowHidden( nCurRow, mnTab, NULL, &nLastRow ) ) ) { - // Skip all filtered rows for subtotal mode. SetPos(nLastRow+1); continue; } @@ -217,7 +220,7 @@ bool ScValueIterator::GetThis(double& rValue, sal_uInt16& rErr) case sc::element_type_formula: { ScFormulaCell& rCell = *sc::formula_block::at(*maCurPos.first->data, maCurPos.second); - if (bSubTotal && rCell.IsSubTotal()) + if ( ( mnSubTotalFlags & SUBTOTAL_IGN_NESTED_ST_AG ) && rCell.IsSubTotal() ) { // Skip subtotal formula cells. IncPos(); @@ -226,6 +229,11 @@ bool ScValueIterator::GetThis(double& rValue, sal_uInt16& rErr) if (rCell.GetErrorOrValue(rErr, rValue)) { + if ( rErr && ( mnSubTotalFlags & SUBTOTAL_IGN_ERR_VAL ) ) + { + IncPos(); + break; + } bNumValid = false; return true; // Found it! } @@ -777,11 +785,11 @@ bool ScDBQueryDataIterator::GetNext(Value& rValue) return mpData->getNext(rValue); } -ScCellIterator::ScCellIterator( ScDocument* pDoc, const ScRange& rRange, bool bSTotal ) : +ScCellIterator::ScCellIterator( ScDocument* pDoc, const ScRange& rRange, sal_uInt16 nSubTotalFlags ) : mpDoc(pDoc), maStartPos(rRange.aStart), maEndPos(rRange.aEnd), - mbSubTotal(bSTotal) + mnSubTotalFlags(nSubTotalFlags) { init(); } @@ -891,21 +899,28 @@ bool ScCellIterator::getCurrent() } SCROW nLastRow; - if (mbSubTotal && pCol->GetDoc().maTabs[maCurPos.Tab()]->RowFiltered(maCurPos.Row(), NULL, &nLastRow)) + // Skip all filtered or hidden rows, depending on mSubTotalFlags + if ( ( ( mnSubTotalFlags & SUBTOTAL_IGN_FILTERED ) && + pCol->GetDoc().RowFiltered(maCurPos.Row(), maCurPos.Tab(), NULL, &nLastRow) ) || + ( ( mnSubTotalFlags & SUBTOTAL_IGN_HIDDEN ) && + pCol->GetDoc().RowHidden(maCurPos.Row(), maCurPos.Tab(), NULL, &nLastRow) ) ) { - // Skip all filtered rows for subtotal mode. setPos(nLastRow+1); continue; } if (maCurColPos.first->type == sc::element_type_formula) { - const ScFormulaCell* pCell = sc::formula_block::at(*maCurColPos.first->data, maCurColPos.second); - if (pCell->IsSubTotal()) + if ( mnSubTotalFlags ) { - // Skip subtotal formula cells. - incPos(); - continue; + ScFormulaCell* pCell = sc::formula_block::at(*maCurColPos.first->data, maCurColPos.second); + // Skip formula cells with Subtotal formulae or errors, depending on mnSubTotalFlags + if ( ( ( mnSubTotalFlags & SUBTOTAL_IGN_NESTED_ST_AG ) && pCell->IsSubTotal() ) || + ( ( mnSubTotalFlags & SUBTOTAL_IGN_ERR_VAL ) && pCell->GetErrCode() ) ) + { + incPos(); + continue; + } } } @@ -2090,13 +2105,12 @@ void ScHorizontalCellIterator::SkipInvalid() } ScHorizontalValueIterator::ScHorizontalValueIterator( ScDocument* pDocument, - const ScRange& rRange, bool bSTotal, bool bTextZero ) : + const ScRange& rRange, bool bTextZero ) : pDoc( pDocument ), nNumFmtIndex(0), nEndTab( rRange.aEnd.Tab() ), nNumFmtType( NUMBERFORMAT_UNDEFINED ), bNumValid( false ), - bSubTotal( bSTotal ), bCalcAsShown( pDocument->GetDocOptions().IsCalcAsShown() ), bTextAsZero( bTextZero ) { @@ -2149,61 +2163,55 @@ bool ScHorizontalValueIterator::GetNext( double& rValue, sal_uInt16& rErr ) else return false; } - if ( !bSubTotal || !pDoc->maTabs[nCurTab]->RowFiltered( nCurRow ) ) + switch (pCell->meType) { - switch (pCell->meType) - { - case CELLTYPE_VALUE: + case CELLTYPE_VALUE: + { + bNumValid = false; + rValue = pCell->mfValue; + rErr = 0; + if ( bCalcAsShown ) { + ScColumn* pCol = &pDoc->maTabs[nCurTab]->aCol[nCurCol]; + ScAttrArray_IterGetNumberFormat( nNumFormat, pAttrArray, + nAttrEndRow, pCol->pAttrArray, nCurRow, pDoc ); + rValue = pDoc->RoundValueAsShown( rValue, nNumFormat ); + } + bFound = true; + } + break; + case CELLTYPE_FORMULA: + { + rErr = pCell->mpFormula->GetErrCode(); + if (rErr || pCell->mpFormula->IsValue()) + { + rValue = pCell->mpFormula->GetValue(); bNumValid = false; - rValue = pCell->mfValue; - rErr = 0; - if ( bCalcAsShown ) - { - ScColumn* pCol = &pDoc->maTabs[nCurTab]->aCol[nCurCol]; - ScAttrArray_IterGetNumberFormat( nNumFormat, pAttrArray, - nAttrEndRow, pCol->pAttrArray, nCurRow, pDoc ); - rValue = pDoc->RoundValueAsShown( rValue, nNumFormat ); - } bFound = true; } - break; - case CELLTYPE_FORMULA: + else if ( bTextAsZero ) { - if (!bSubTotal || !pCell->mpFormula->IsSubTotal()) - { - rErr = pCell->mpFormula->GetErrCode(); - if (rErr || pCell->mpFormula->IsValue()) - { - rValue = pCell->mpFormula->GetValue(); - bNumValid = false; - bFound = true; - } - else if ( bTextAsZero ) - { - rValue = 0.0; - bNumValid = false; - bFound = true; - } - } + rValue = 0.0; + bNumValid = false; + bFound = true; } - break; - case CELLTYPE_STRING : - case CELLTYPE_EDIT : + } + break; + case CELLTYPE_STRING : + case CELLTYPE_EDIT : + { + if ( bTextAsZero ) { - if ( bTextAsZero ) - { - rErr = 0; - rValue = 0.0; - nNumFmtType = NUMBERFORMAT_NUMBER; - nNumFmtIndex = 0; - bNumValid = true; - bFound = true; - } + rErr = 0; + rValue = 0.0; + nNumFmtType = NUMBERFORMAT_NUMBER; + nNumFmtIndex = 0; + bNumValid = true; + bFound = true; } - break; - default: ; // nothing - } + } + break; + default: ; // nothing } } return bFound; diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx index 5e051f6fe787..c1fbfab03553 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -491,8 +491,7 @@ void ScFormulaCellGroup::compileCode( } else { - mpCode->Reset(); - mbSubTotal = mpCode->GetNextOpCodeRPN(ocSubTotal) != NULL; + mbSubTotal = mpCode->HasOpCodeRPN( ocSubTotal ) || mpCode->HasOpCodeRPN( ocAggregate ); } } @@ -604,8 +603,7 @@ ScFormulaCell::ScFormulaCell( } else { - pCode->Reset(); - if (pCode->GetNextOpCodeRPN(ocSubTotal)) + if ( pCode->HasOpCodeRPN( ocSubTotal ) || pCode->HasOpCodeRPN( ocAggregate ) ) bSubTotal = true; } @@ -651,8 +649,7 @@ ScFormulaCell::ScFormulaCell( } else { - pCode->Reset(); - if ( pCode->GetNextOpCodeRPN( ocSubTotal ) ) + if ( pCode->HasOpCodeRPN( ocSubTotal ) || pCode->HasOpCodeRPN( ocAggregate ) ) bSubTotal = true; } diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index b3b999a6c7bc..eb24eb9645f6 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -174,7 +174,7 @@ private: short nCurFmtType; // current NumberFormatType short nRetFmtType; // NumberFormatType of an expression sal_uInt16 mnStringNoValueError; // the error set in ConvertStringToValue() if no value - bool glSubTotal; // flag for subtotal functions + sal_uInt16 mnSubTotalFlags; // flags for subtotal and aggregate functions sal_uInt8 cPar; // current count of parameters bool bCalcAsShown; // precision as shown bool bMatrixFormula; // formula cell is a matrix formula diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index d9a7d588dcc0..b9e3d122e7c2 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -3345,7 +3345,7 @@ void ScInterpreter::ScMin( bool bTextAsZero ) { sal_uInt16 nErr = 0; PopDoubleRef( aRange, nParamCount, nRefInList); - ScValueIterator aValIter( pDok, aRange, glSubTotal, bTextAsZero ); + ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags, bTextAsZero ); if (aValIter.GetFirst(nVal, nErr)) { if (nMin > nVal) @@ -3441,7 +3441,7 @@ void ScInterpreter::ScMax( bool bTextAsZero ) { sal_uInt16 nErr = 0; PopDoubleRef( aRange, nParamCount, nRefInList); - ScValueIterator aValIter( pDok, aRange, glSubTotal, bTextAsZero ); + ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags, bTextAsZero ); if (aValIter.GetFirst(nVal, nErr)) { if (nMax < nVal) @@ -3543,7 +3543,7 @@ void ScInterpreter::GetStVarParams( double& rVal, double& rValCount, { sal_uInt16 nErr = 0; PopDoubleRef( aRange, nParamCount, nRefInList); - ScValueIterator aValIter( pDok, aRange, glSubTotal, bTextAsZero ); + ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags, bTextAsZero ); if (aValIter.GetFirst(fVal, nErr)) { do @@ -4539,7 +4539,7 @@ void ScInterpreter::ScCountEmptyCells() static_cast<sal_uLong>(aRange.aEnd.Col() - aRange.aStart.Col() + 1) * static_cast<sal_uLong>(aRange.aEnd.Tab() - aRange.aStart.Tab() + 1); - ScCellIterator aIter( pDok, aRange, glSubTotal); + ScCellIterator aIter( pDok, aRange, mnSubTotalFlags); for (bool bHas = aIter.first(); bHas; bHas = aIter.next()) { if (!aIter.hasEmptyData()) @@ -6491,22 +6491,20 @@ void ScInterpreter::ScSubTotal() const FormulaToken* p = pStack[ sp - nParamCount ]; PushTempToken( *p ); int nFunc = (int) ::rtl::math::approxFloor( GetDouble() ); - bool bIncludeHidden = true; + mnSubTotalFlags |= SUBTOTAL_IGN_NESTED_ST_AG | SUBTOTAL_IGN_FILTERED; if (nFunc > 100) { // For opcodes 101 through 111, we need to skip hidden cells. // Other than that these opcodes are identical to 1 through 11. - bIncludeHidden = false; + mnSubTotalFlags |= SUBTOTAL_IGN_HIDDEN; nFunc -= 100; } - if (nFunc < 1 || nFunc > 11 || !bIncludeHidden) + if ( nFunc < 1 || nFunc > 11 ) PushIllegalArgument(); // simulate return on stack, not SetError(...) else { - // TODO: Make use of bIncludeHidden flag. Then it's false, we do need to skip hidden cells. cPar = nParamCount - 1; - glSubTotal = true; switch( nFunc ) { case SUBTOTAL_FUNC_AVE : ScAverage(); break; @@ -6522,8 +6520,8 @@ void ScInterpreter::ScSubTotal() case SUBTOTAL_FUNC_VARP : ScVarP(); break; default : PushIllegalArgument(); break; } - glSubTotal = false; } + mnSubTotalFlags = 0x00; // Get rid of the 1st (fished) parameter. double nVal = GetDouble(); Pop(); @@ -6549,45 +6547,38 @@ void ScInterpreter::ScAggregate() PushIllegalArgument(); else { - sal_uInt16 nAggrFlags = 0x00; switch ( nOption) { case 0 : // ignore nested SUBTOTAL and AGGREGATE functions - nAggrFlags = AGGR_IGN_NESTED_ST_AG; + mnSubTotalFlags = SUBTOTAL_IGN_NESTED_ST_AG; break; case 1 : // ignore hidden rows, nested SUBTOTAL and AGGREGATE functions - nAggrFlags = AGGR_IGN_HID_ROW | AGGR_IGN_NESTED_ST_AG; + mnSubTotalFlags = SUBTOTAL_IGN_HIDDEN | SUBTOTAL_IGN_NESTED_ST_AG; break; case 2 : // ignore error values, nested SUBTOTAL and AGGREGATE functions - nAggrFlags = AGGR_IGN_ERR_VAL | AGGR_IGN_NESTED_ST_AG; + mnSubTotalFlags = SUBTOTAL_IGN_ERR_VAL | SUBTOTAL_IGN_NESTED_ST_AG; break; case 3 : // ignore hidden rows, error values, nested SUBTOTAL and AGGREGATE functions - nAggrFlags = AGGR_IGN_HID_ROW | AGGR_IGN_ERR_VAL | AGGR_IGN_NESTED_ST_AG; + mnSubTotalFlags = SUBTOTAL_IGN_HIDDEN | SUBTOTAL_IGN_ERR_VAL | SUBTOTAL_IGN_NESTED_ST_AG; break; case 4 : // ignore nothing + mnSubTotalFlags = 0x00; break; case 5 : // ignore hidden rows - nAggrFlags = AGGR_IGN_HID_ROW ; + mnSubTotalFlags = SUBTOTAL_IGN_HIDDEN ; break; case 6 : // ignore error values - nAggrFlags = AGGR_IGN_ERR_VAL ; + mnSubTotalFlags = SUBTOTAL_IGN_ERR_VAL ; break; - case 7 : // igniore hidden rows and error values - nAggrFlags = AGGR_IGN_HID_ROW | AGGR_IGN_ERR_VAL ; + case 7 : // ignore hidden rows and error values + mnSubTotalFlags = SUBTOTAL_IGN_HIDDEN | SUBTOTAL_IGN_ERR_VAL ; break; default : PushIllegalArgument(); return; } - // TODO: implement filter options - if ( nAggrFlags != 0x00 ) - { - PushError( errUnknownVariable ); - return; - } cPar = nParamCount - 2; - glSubTotal = true; switch ( nFunc ) { case SUBTOTAL_FUNC_AVE : ScAverage(); break; @@ -6611,7 +6602,7 @@ void ScInterpreter::ScAggregate() case AGGREGATE_FUNC_QRTEXC : ScQuartile( false ); break; default : PushIllegalArgument(); break; } - glSubTotal = false; + mnSubTotalFlags = 0x00; } double nVal = GetDouble(); // Get rid of the 1st and 2nd (fished) parameters. diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx index 02938092f217..567b728ba8cc 100644 --- a/sc/source/core/tool/interpr2.cxx +++ b/sc/source/core/tool/interpr2.cxx @@ -1007,7 +1007,7 @@ void ScInterpreter::ScNPV() sal_uInt16 nErr = 0; double nCellVal; PopDoubleRef( aRange, nParamCount, nRefInList); - ScHorizontalValueIterator aValIter( pDok, aRange, glSubTotal); + ScHorizontalValueIterator aValIter( pDok, aRange ); while ((nErr == 0) && aValIter.GetNext(nCellVal, nErr)) { nVal += (nCellVal / pow(1.0 + nZins, (double)nCount)); @@ -1064,7 +1064,7 @@ void ScInterpreter::ScIRR() fNenner = 0.0; sal_uInt16 nErr = 0; PopDoubleRef( aRange ); - ScValueIterator aValIter(pDok, aRange, glSubTotal); + ScValueIterator aValIter(pDok, aRange, mnSubTotalFlags); if (aValIter.GetFirst(fWert, nErr)) { fZaehler += fWert / pow(1.0+x,(double)nCount); @@ -1110,7 +1110,7 @@ void ScInterpreter::ScMIRR() double fPow_reinvest = 1.0; double fNPV_invest = 0.0; double fPow_invest = 1.0; - ScValueIterator aValIter( pDok, aRange, glSubTotal ); + ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags ); double fCellValue; sal_uLong nCount = 0; sal_uInt16 nIterError = 0; diff --git a/sc/source/core/tool/interpr3.cxx b/sc/source/core/tool/interpr3.cxx index f20b07f0b560..a94fe10038e9 100644 --- a/sc/source/core/tool/interpr3.cxx +++ b/sc/source/core/tool/interpr3.cxx @@ -2529,7 +2529,7 @@ void ScInterpreter::ScZTest() ScRange aRange; sal_uInt16 nErr = 0; PopDoubleRef( aRange, nParam, nRefInList); - ScValueIterator aValIter(pDok, aRange, glSubTotal); + ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags ); if (aValIter.GetFirst(fVal, nErr)) { fSum += fVal; @@ -2954,7 +2954,7 @@ void ScInterpreter::ScHarMean() sal_uInt16 nErr = 0; PopDoubleRef( aRange, nParamCount, nRefInList); double nCellVal; - ScValueIterator aValIter(pDok, aRange, glSubTotal); + ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags ); if (aValIter.GetFirst(nCellVal, nErr)) { if (nCellVal > 0.0) @@ -3077,7 +3077,7 @@ void ScInterpreter::ScGeoMean() sal_uInt16 nErr = 0; PopDoubleRef( aRange, nParamCount, nRefInList); double nCellVal; - ScValueIterator aValIter(pDok, aRange, glSubTotal); + ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags ); if (aValIter.GetFirst(nCellVal, nErr)) { if (nCellVal > 0.0) @@ -3210,7 +3210,7 @@ bool ScInterpreter::CalculateSkew(double& fSum,double& fCount,double& vSum,std:: { PopDoubleRef( aRange, nParamCount, nRefInList); sal_uInt16 nErr = 0; - ScValueIterator aValIter(pDok, aRange); + ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags ); if (aValIter.GetFirst(fVal, nErr)) { fSum += fVal; @@ -3689,7 +3689,7 @@ void ScInterpreter::GetNumberSequenceArray( sal_uInt8 nParamCount, vector<double sal_uInt16 nErr = 0; double fCellVal; - ScValueIterator aValIter(pDok, aRange); + ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags ); if (aValIter.GetFirst( fCellVal, nErr)) { rArray.push_back( fCellVal); @@ -3930,7 +3930,7 @@ void ScInterpreter::ScAveDev() sal_uInt16 nErr = 0; double nCellVal; PopDoubleRef( aRange, nParam, nRefInList); - ScValueIterator aValIter(pDok, aRange); + ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags ); if (aValIter.GetFirst(nCellVal, nErr)) { rVal += nCellVal; @@ -4010,7 +4010,7 @@ void ScInterpreter::ScAveDev() sal_uInt16 nErr = 0; double nCellVal; PopDoubleRef( aRange, nParam, nRefInList); - ScValueIterator aValIter(pDok, aRange); + ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags ); if (aValIter.GetFirst(nCellVal, nErr)) { rVal += (fabs(nCellVal - nMiddle)); diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index 3406027b7885..55b7ccb31fb2 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -3693,7 +3693,6 @@ ScInterpreter::ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc, , nCurFmtType(0) , nRetFmtType(0) , mnStringNoValueError(errNoValue) - , glSubTotal(false) , cPar(0) , bCalcAsShown(pDoc->GetDocOptions().IsCalcAsShown()) , meVolatileType(r.IsRecalcModeAlways() ? VOLATILE : NOT_VOLATILE) @@ -3795,7 +3794,7 @@ StackVar ScInterpreter::Interpret() nFuncFmtIndex = nCurFmtIndex = nRetFmtIndex = 0; xResult = NULL; pJumpMatrix = NULL; - glSubTotal = false; + mnSubTotalFlags = 0x00; ScTokenMatrixMap::const_iterator aTokenMatrixMapIter; // Once upon a time we used to have FP exceptions on, and there was a diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx index f2669c6fdfd8..9c2800900910 100644 --- a/sc/source/core/tool/interpr5.cxx +++ b/sc/source/core/tool/interpr5.cxx @@ -154,7 +154,7 @@ void ScInterpreter::ScGCD() sal_uInt16 nErr = 0; PopDoubleRef( aRange, nParamCount, nRefInList); double nCellVal; - ScValueIterator aValIter(pDok, aRange, glSubTotal); + ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags ); if (aValIter.GetFirst(nCellVal, nErr)) { do @@ -247,7 +247,7 @@ void ScInterpreter:: ScLCM() sal_uInt16 nErr = 0; PopDoubleRef( aRange, nParamCount, nRefInList); double nCellVal; - ScValueIterator aValIter(pDok, aRange, glSubTotal); + ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags ); if (aValIter.GetFirst(nCellVal, nErr)) { do diff --git a/sc/source/core/tool/interpr6.cxx b/sc/source/core/tool/interpr6.cxx index f7e8259da573..13c603f3d087 100644 --- a/sc/source/core/tool/interpr6.cxx +++ b/sc/source/core/tool/interpr6.cxx @@ -359,6 +359,7 @@ void IterateMatrix( if (!pMat) return; + // TODO fdo73148 take mnSubTotalFlags into account rFuncFmtType = NUMBERFORMAT_NUMBER; switch (eFunc) { @@ -416,7 +417,8 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) ScAddress aAdr; ScRange aRange; size_t nRefInList = 0; - if ( nGlobalError && ( eFunc == ifCOUNT2 || eFunc == ifCOUNT ) ) + if ( nGlobalError && ( eFunc == ifCOUNT2 || eFunc == ifCOUNT || + ( mnSubTotalFlags & SUBTOTAL_IGN_ERR_VAL ) ) ) nGlobalError = 0; while (nParamCount-- > 0) { @@ -488,10 +490,11 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) ScExternalRefCache::TokenRef pToken; ScExternalRefCache::CellFormat aFmt; PopExternalSingleRef(pToken, &aFmt); - if (nGlobalError && (eFunc == ifCOUNT2 || eFunc == ifCOUNT)) + if ( nGlobalError && ( eFunc == ifCOUNT2 || eFunc == ifCOUNT || + ( mnSubTotalFlags & SUBTOTAL_IGN_ERR_VAL ) ) ) { nGlobalError = 0; - if ( eFunc == ifCOUNT2 ) + if ( eFunc == ifCOUNT2 && !( mnSubTotalFlags & SUBTOTAL_IGN_ERR_VAL ) ) ++nCount; break; } @@ -502,7 +505,10 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) StackVar eType = pToken->GetType(); if (eFunc == ifCOUNT2) { - if (eType != formula::svEmptyCell) + if ( eType != formula::svEmptyCell && + ( ( pToken->GetOpCode() != ocSubTotal && + pToken->GetOpCode() != ocAggregate ) || + ( mnSubTotalFlags & SUBTOTAL_IGN_NESTED_ST_AG ) ) ) nCount++; if (nGlobalError) nGlobalError = 0; @@ -551,14 +557,16 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) case svSingleRef : { PopSingleRef( aAdr ); - if ( nGlobalError && ( eFunc == ifCOUNT2 || eFunc == ifCOUNT ) ) + if ( nGlobalError && ( eFunc == ifCOUNT2 || eFunc == ifCOUNT || + ( mnSubTotalFlags & SUBTOTAL_IGN_ERR_VAL ) ) ) { nGlobalError = 0; - if ( eFunc == ifCOUNT2 ) + if ( eFunc == ifCOUNT2 && !( mnSubTotalFlags & SUBTOTAL_IGN_ERR_VAL ) ) ++nCount; break; } - if (glSubTotal && pDok->RowFiltered( aAdr.Row(), aAdr.Tab())) + if ( ( mnSubTotalFlags & SUBTOTAL_IGN_FILTERED ) && + pDok->RowFiltered( aAdr.Row(), aAdr.Tab() ) ) { break; } @@ -569,7 +577,7 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) if( eFunc == ifCOUNT2 ) { CellType eCellType = aCell.meType; - if (eCellType != CELLTYPE_NONE) + if ( eCellType != CELLTYPE_NONE ) nCount++; if ( nGlobalError ) nGlobalError = 0; @@ -616,20 +624,24 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) case svRefList : { PopDoubleRef( aRange, nParamCount, nRefInList); - if ( nGlobalError && ( eFunc == ifCOUNT2 || eFunc == ifCOUNT ) ) + if ( nGlobalError && ( eFunc == ifCOUNT2 || eFunc == ifCOUNT || + ( mnSubTotalFlags & SUBTOTAL_IGN_ERR_VAL ) ) ) { nGlobalError = 0; - if ( eFunc == ifCOUNT2 ) + if ( eFunc == ifCOUNT2 && !( mnSubTotalFlags & SUBTOTAL_IGN_ERR_VAL ) ) ++nCount; - break; + if ( eFunc == ifCOUNT2 || eFunc == ifCOUNT ) + break; } if( eFunc == ifCOUNT2 ) { - ScCellIterator aIter( pDok, aRange, glSubTotal ); + ScCellIterator aIter( pDok, aRange, mnSubTotalFlags ); for (bool bHas = aIter.first(); bHas; bHas = aIter.next()) { - if (!aIter.hasEmptyData()) + if ( !aIter.hasEmptyData() ) + { ++nCount; + } } if ( nGlobalError ) @@ -637,7 +649,7 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) } else { - ScValueIterator aValIter( pDok, aRange, glSubTotal, bTextAsZero ); + ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags, bTextAsZero ); sal_uInt16 nErr = 0; if (aValIter.GetFirst(fVal, nErr)) { @@ -647,35 +659,76 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) { case ifAVERAGE: case ifSUM: - do + if ( mnSubTotalFlags & SUBTOTAL_IGN_ERR_VAL ) { - SetError(nErr); - if ( bNull && fVal != 0.0 ) + do { - bNull = false; - fMem = fVal; + if ( !nErr ) + { + SetError(nErr); + if ( bNull && fVal != 0.0 ) + { + bNull = false; + fMem = fVal; + } + else + fRes += fVal; + nCount++; + } } - else - fRes += fVal; - nCount++; + while (aValIter.GetNext(fVal, nErr)); + } + else + { + do + { + SetError(nErr); + if ( bNull && fVal != 0.0 ) + { + bNull = false; + fMem = fVal; + } + else + fRes += fVal; + nCount++; + } + while (aValIter.GetNext(fVal, nErr)); } - while (aValIter.GetNext(fVal, nErr)); break; case ifSUMSQ: - do + if ( mnSubTotalFlags & SUBTOTAL_IGN_ERR_VAL ) { - SetError(nErr); - fRes += fVal * fVal; - nCount++; + do + { + if ( !nErr ) + { + SetError(nErr); + fRes += fVal * fVal; + nCount++; + } + } + while (aValIter.GetNext(fVal, nErr)); + } + else + { + do + { + SetError(nErr); + fRes += fVal * fVal; + nCount++; + } + while (aValIter.GetNext(fVal, nErr)); } - while (aValIter.GetNext(fVal, nErr)); break; case ifPRODUCT: do { - SetError(nErr); - fRes *= fVal; - nCount++; + if ( !( nErr && ( mnSubTotalFlags & SUBTOTAL_IGN_ERR_VAL ) ) ) + { + SetError(nErr); + fRes *= fVal; + nCount++; + } } while (aValIter.GetNext(fVal, nErr)); break; @@ -698,7 +751,7 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) { ScMatrixRef pMat; PopExternalDoubleRef(pMat); - if (nGlobalError) + if ( nGlobalError && !( mnSubTotalFlags & SUBTOTAL_IGN_ERR_VAL ) ) break; IterateMatrix(pMat, eFunc, bTextAsZero, nCount, nFuncFmtType, fRes, fMem, bNull); @@ -713,11 +766,11 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) case svError: { PopError(); - if ( eFunc == ifCOUNT ) + if ( eFunc == ifCOUNT || ( mnSubTotalFlags & SUBTOTAL_IGN_ERR_VAL ) ) { nGlobalError = 0; } - else if ( eFunc == ifCOUNT2 ) + else if ( eFunc == ifCOUNT2 && !( mnSubTotalFlags & SUBTOTAL_IGN_ERR_VAL ) ) { nCount++; nGlobalError = 0; @@ -753,138 +806,136 @@ void ScInterpreter::ScSumSQ() void ScInterpreter::ScSum() { - short nParamCount = GetByte(); - double fRes = 0.0; - double fVal = 0.0; - ScAddress aAdr; - ScRange aRange; - size_t nRefInList = 0; - while (nParamCount-- > 0) + if ( mnSubTotalFlags ) + PushDouble( IterateParameters( ifSUM ) ); + else { - switch (GetStackType()) + short nParamCount = GetByte(); + double fRes = 0.0; + double fVal = 0.0; + ScAddress aAdr; + ScRange aRange; + size_t nRefInList = 0; + while (nParamCount-- > 0) { - case svString: + switch (GetStackType()) { - while (nParamCount-- > 0) - Pop(); - SetError( errNoValue ); - } - break; - case svDouble : - fVal = GetDouble(); - fRes += fVal; - nFuncFmtType = NUMBERFORMAT_NUMBER; + case svString: + { + while (nParamCount-- > 0) + Pop(); + SetError( errNoValue ); + } break; - case svExternalSingleRef: - { - ScExternalRefCache::TokenRef pToken; - ScExternalRefCache::CellFormat aFmt; - PopExternalSingleRef(pToken, &aFmt); - - if (!pToken) + case svDouble : + fVal = GetDouble(); + fRes += fVal; + nFuncFmtType = NUMBERFORMAT_NUMBER; break; - - StackVar eType = pToken->GetType(); - if (eType == formula::svDouble) + case svExternalSingleRef: { - fVal = pToken->GetDouble(); - if (aFmt.mbIsSet) + ScExternalRefCache::TokenRef pToken; + ScExternalRefCache::CellFormat aFmt; + PopExternalSingleRef(pToken, &aFmt); + + if (!pToken) + break; + + StackVar eType = pToken->GetType(); + if (eType == formula::svDouble) { - nFuncFmtType = aFmt.mnType; - nFuncFmtIndex = aFmt.mnIndex; - } + fVal = pToken->GetDouble(); + if (aFmt.mbIsSet) + { + nFuncFmtType = aFmt.mnType; + nFuncFmtIndex = aFmt.mnIndex; + } - fRes += fVal; + fRes += fVal; + } } - } - break; - case svSingleRef : - { - PopSingleRef( aAdr ); - - if (glSubTotal && pDok->RowFiltered( aAdr.Row(), aAdr.Tab())) + break; + case svSingleRef : { - break; + PopSingleRef( aAdr ); + + ScRefCellValue aCell; + aCell.assign(*pDok, aAdr); + if (!aCell.isEmpty()) + { + if (aCell.hasNumeric()) + { + fVal = GetCellValue(aAdr, aCell); + CurFmtToFuncFmt(); + fRes += fVal; + } + } } - ScRefCellValue aCell; - aCell.assign(*pDok, aAdr); - if (!aCell.isEmpty()) + break; + case svDoubleRef : + case svRefList : { - if (aCell.hasNumeric()) + PopDoubleRef( aRange, nParamCount, nRefInList); + + sc::ColumnSpanSet aSet(false); + aSet.set(aRange, true); + + FuncSum aAction; + aSet.executeColumnAction(*pDok, aAction); + sal_uInt16 nErr = aAction.getError(); + if (nErr) { - fVal = GetCellValue(aAdr, aCell); - CurFmtToFuncFmt(); - fRes += fVal; + SetError(nErr); + return; } - } - } - break; - case svDoubleRef : - case svRefList : - { - PopDoubleRef( aRange, nParamCount, nRefInList); + fRes += aAction.getSum(); - sc::ColumnSpanSet aSet(false); - aSet.set(aRange, true); - if (glSubTotal) - // Skip all filtered rows and subtotal formula cells. - pDok->MarkSubTotalCells(aSet, aRange, false); + // Get the number format of the last iterated cell. + nFuncFmtIndex = aAction.getNumberFormat(); + nFuncFmtType = pDok->GetFormatTable()->GetType(nFuncFmtIndex); + } + break; + case svExternalDoubleRef: + { + ScMatrixRef pMat; + PopExternalDoubleRef(pMat); + if (nGlobalError) + break; - FuncSum aAction; - aSet.executeColumnAction(*pDok, aAction); - sal_uInt16 nErr = aAction.getError(); - if (nErr) + sal_uLong nCount = 0; + double fMem = 0.0; + bool bNull = true; + IterateMatrix(pMat, ifSUM, false, nCount, nFuncFmtType, fRes, fMem, bNull); + fRes += fMem; + } + break; + case svMatrix : { - SetError(nErr); - return; + ScMatrixRef pMat = PopMatrix(); + sal_uLong nCount = 0; + double fMem = 0.0; + bool bNull = true; + IterateMatrix(pMat, ifSUM, false, nCount, nFuncFmtType, fRes, fMem, bNull); + fRes += fMem; } - fRes += aAction.getSum(); - - // Get the number format of the last iterated cell. - nFuncFmtIndex = aAction.getNumberFormat(); - nFuncFmtType = pDok->GetFormatTable()->GetType(nFuncFmtIndex); - } - break; - case svExternalDoubleRef: - { - ScMatrixRef pMat; - PopExternalDoubleRef(pMat); - if (nGlobalError) - break; - - sal_uLong nCount = 0; - double fMem = 0.0; - bool bNull = true; - IterateMatrix(pMat, ifSUM, false, nCount, nFuncFmtType, fRes, fMem, bNull); - fRes += fMem; - } - break; - case svMatrix : - { - ScMatrixRef pMat = PopMatrix(); - sal_uLong nCount = 0; - double fMem = 0.0; - bool bNull = true; - IterateMatrix(pMat, ifSUM, false, nCount, nFuncFmtType, fRes, fMem, bNull); - fRes += fMem; - } - break; - case svError: - { - PopError(); - } - break; - default : - while (nParamCount-- > 0) + break; + case svError: + { PopError(); - SetError(errIllegalParameter); + } + break; + default : + while (nParamCount-- > 0) + PopError(); + SetError(errIllegalParameter); + } } - } - if (nFuncFmtType == NUMBERFORMAT_LOGICAL) - nFuncFmtType = NUMBERFORMAT_NUMBER; + if (nFuncFmtType == NUMBERFORMAT_LOGICAL) + nFuncFmtType = NUMBERFORMAT_NUMBER; - PushDouble(fRes); + PushDouble(fRes); + } } void ScInterpreter::ScProduct() @@ -899,84 +950,60 @@ void ScInterpreter::ScAverage( bool bTextAsZero ) void ScInterpreter::ScCount() { - short nParamCount = GetByte(); - double fVal = 0.0; - sal_uLong nCount = 0; - ScAddress aAdr; - ScRange aRange; - size_t nRefInList = 0; - if (nGlobalError) - nGlobalError = 0; - - while (nParamCount-- > 0) + if ( mnSubTotalFlags ) + PushDouble( IterateParameters( ifCOUNT ) ); + else { - switch (GetRawStackType()) + short nParamCount = GetByte(); + double fVal = 0.0; + sal_uLong nCount = 0; + ScAddress aAdr; + ScRange aRange; + size_t nRefInList = 0; + if (nGlobalError) + nGlobalError = 0; + + while (nParamCount-- > 0) { - case svString: - { - OUString aStr = PopString().getString(); - sal_uInt32 nFIndex = 0; // damit default Land/Spr. - if (pFormatter->IsNumberFormat(aStr, nFIndex, fVal)) - nCount++; - } - break; - case svDouble : - GetDouble(); - nCount++; - nFuncFmtType = NUMBERFORMAT_NUMBER; - break; - case svExternalSingleRef: + switch (GetRawStackType()) { - ScExternalRefCache::TokenRef pToken; - ScExternalRefCache::CellFormat aFmt; - PopExternalSingleRef(pToken, &aFmt); - if (nGlobalError) + case svString: { - nGlobalError = 0; - break; + OUString aStr = PopString().getString(); + sal_uInt32 nFIndex = 0; // damit default Land/Spr. + if (pFormatter->IsNumberFormat(aStr, nFIndex, fVal)) + nCount++; } - - if (!pToken) + break; + case svDouble : + GetDouble(); + nCount++; + nFuncFmtType = NUMBERFORMAT_NUMBER; break; - - StackVar eType = pToken->GetType(); - if (eType == formula::svDouble) + case svExternalSingleRef: { - nCount++; - if (aFmt.mbIsSet) - { - nFuncFmtType = aFmt.mnType; - nFuncFmtIndex = aFmt.mnIndex; - } - + ScExternalRefCache::TokenRef pToken; + ScExternalRefCache::CellFormat aFmt; + PopExternalSingleRef(pToken, &aFmt); if (nGlobalError) { nGlobalError = 0; - nCount--; + break; } - } - } - break; - case svSingleRef : - { - PopSingleRef( aAdr ); - if (nGlobalError) - { - nGlobalError = 0; - break; - } - if (glSubTotal && pDok->RowFiltered( aAdr.Row(), aAdr.Tab())) - { - break; - } - ScRefCellValue aCell; - aCell.assign(*pDok, aAdr); - if (!aCell.isEmpty()) - { - if (aCell.hasNumeric()) + + if (!pToken) + break; + + StackVar eType = pToken->GetType(); + if (eType == formula::svDouble) { nCount++; - CurFmtToFuncFmt(); + if (aFmt.mbIsSet) + { + nFuncFmtType = aFmt.mnType; + nFuncFmtIndex = aFmt.mnIndex; + } + if (nGlobalError) { nGlobalError = 0; @@ -984,69 +1011,91 @@ void ScInterpreter::ScCount() } } } - } - break; - case svDoubleRef : - case svRefList : - { - PopDoubleRef( aRange, nParamCount, nRefInList); - if (nGlobalError) + break; + case svSingleRef : { - nGlobalError = 0; - break; + PopSingleRef( aAdr ); + if (nGlobalError) + { + nGlobalError = 0; + break; + } + ScRefCellValue aCell; + aCell.assign(*pDok, aAdr); + if (!aCell.isEmpty()) + { + if (aCell.hasNumeric()) + { + nCount++; + CurFmtToFuncFmt(); + if (nGlobalError) + { + nGlobalError = 0; + nCount--; + } + } + } } + break; + case svDoubleRef : + case svRefList : + { + PopDoubleRef( aRange, nParamCount, nRefInList); + if (nGlobalError) + { + nGlobalError = 0; + break; + } - sc::ColumnSpanSet aSet(false); - aSet.set(aRange, true); - if (glSubTotal) - // Skip all filtered rows and subtotal formula cells. - pDok->MarkSubTotalCells(aSet, aRange, false); + sc::ColumnSpanSet aSet(false); + aSet.set(aRange, true); - FuncCount aAction; - aSet.executeColumnAction(*pDok, aAction); - nCount += aAction.getCount(); + FuncCount aAction; + aSet.executeColumnAction(*pDok, aAction); + nCount += aAction.getCount(); - // Get the number format of the last iterated cell. - nFuncFmtIndex = aAction.getNumberFormat(); - nFuncFmtType = pDok->GetFormatTable()->GetType(nFuncFmtIndex); - } - break; - case svExternalDoubleRef: - { - ScMatrixRef pMat; - PopExternalDoubleRef(pMat); - if (nGlobalError) - break; + // Get the number format of the last iterated cell. + nFuncFmtIndex = aAction.getNumberFormat(); + nFuncFmtType = pDok->GetFormatTable()->GetType(nFuncFmtIndex); + } + break; + case svExternalDoubleRef: + { + ScMatrixRef pMat; + PopExternalDoubleRef(pMat); + if (nGlobalError) + break; - double fMem = 0.0, fRes = 0.0; - bool bNull = true; - IterateMatrix(pMat, ifCOUNT, false, nCount, nFuncFmtType, fRes, fMem, bNull); - } - break; - case svMatrix : - { - ScMatrixRef pMat = PopMatrix(); - double fMem = 0.0, fRes = 0.0; - bool bNull = true; - IterateMatrix(pMat, ifCOUNT, false, nCount, nFuncFmtType, fRes, fMem, bNull); - } - break; - case svError: - { - PopError(); - nGlobalError = 0; - } - break; - default : - while (nParamCount-- > 0) + double fMem = 0.0, fRes = 0.0; + bool bNull = true; + IterateMatrix(pMat, ifCOUNT, false, nCount, nFuncFmtType, fRes, fMem, bNull); + } + break; + case svMatrix : + { + ScMatrixRef pMat = PopMatrix(); + double fMem = 0.0, fRes = 0.0; + bool bNull = true; + IterateMatrix(pMat, ifCOUNT, false, nCount, nFuncFmtType, fRes, fMem, bNull); + } + break; + case svError: + { PopError(); - SetError(errIllegalParameter); + nGlobalError = 0; + } + break; + default : + while (nParamCount-- > 0) + PopError(); + SetError(errIllegalParameter); + } } - } - nFuncFmtType = NUMBERFORMAT_NUMBER; + nFuncFmtType = NUMBERFORMAT_NUMBER; - PushDouble(nCount); + PushDouble(nCount); + } } void ScInterpreter::ScCount2() diff --git a/sc/source/ui/src/scfuncs.src b/sc/source/ui/src/scfuncs.src index 0e55514f2a42..c34785c1bad3 100644 --- a/sc/source/ui/src/scfuncs.src +++ b/sc/source/ui/src/scfuncs.src @@ -4220,7 +4220,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS1 }; ExtraData = { - 1; + 0; ID_FUNCTION_GRP_MATH; U2S( HID_FUNC_AGGREGATE ); VAR_ARGS+3; 0; 0; 0; 1; |