[Libreoffice-commits] core.git: formula/source sc/inc sc/qa sc/source

Winfried Donkers winfrieddonkers at libreoffice.org
Tue Jul 8 03:23:30 PDT 2014


 formula/source/core/api/FormulaCompiler.cxx    |    3 
 sc/inc/dociter.hxx                             |   19 
 sc/inc/global.hxx                              |    7 
 sc/qa/unit/data/xlsx/functions-excel-2010.xlsx |binary
 sc/qa/unit/helper/shared_test_impl.hxx         |    4 
 sc/qa/unit/ucalc.cxx                           |    2 
 sc/source/core/data/dociter.cxx                |  132 +++--
 sc/source/core/data/formulacell.cxx            |    9 
 sc/source/core/inc/interpre.hxx                |    2 
 sc/source/core/tool/interpr1.cxx               |   45 -
 sc/source/core/tool/interpr2.cxx               |    6 
 sc/source/core/tool/interpr3.cxx               |   14 
 sc/source/core/tool/interpr4.cxx               |    3 
 sc/source/core/tool/interpr5.cxx               |    4 
 sc/source/core/tool/interpr6.cxx               |  573 +++++++++++++------------
 sc/source/ui/src/scfuncs.src                   |    2 
 16 files changed, 434 insertions(+), 391 deletions(-)

New commits:
commit 08e3e6c223c266874a4acf3885997ea6426aa9bd
Author: Winfried Donkers <winfrieddonkers at libreoffice.org>
Date:   Fri May 23 15:24:48 2014 +0200

    fdo#73148 add options to Calc function AGGREGATE
    
    matrix-ranges not supported
    
    Change-Id: I902c78da6d9c7a4a5f8c5e4a7e1678b69d49a6fe
    Reviewed-on: https://gerrit.libreoffice.org/9449
    Reviewed-by: Eike Rathke <erack at redhat.com>
    Tested-by: Eike Rathke <erack at redhat.com>

diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx
index 2e066af..5f63fcf 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 f0d82fe..f7f9b2b 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 0614bce..fb2e120 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
index c6d6ebb8ab..152fbbc 100644
Binary files a/sc/qa/unit/data/xlsx/functions-excel-2010.xlsx and b/sc/qa/unit/data/xlsx/functions-excel-2010.xlsx differ
diff --git a/sc/qa/unit/helper/shared_test_impl.hxx b/sc/qa/unit/helper/shared_test_impl.hxx
index c339efa..bc2ee65 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 c0e1eb9..af272a5 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 d6799d2..2c5a597 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 5e051f6..c1fbfab 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 b3b999a..eb24eb9 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 d9a7d58..b9e3d12 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 0293809..567b728 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 f20b07f..a94fe10 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 3406027..55b7ccb 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 f2669c6..9c28009 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 f7e8259..13c603f 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 0e55514..c34785c 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;


More information about the Libreoffice-commits mailing list