summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--formula/source/core/api/FormulaCompiler.cxx3
-rw-r--r--sc/inc/dociter.hxx19
-rw-r--r--sc/inc/global.hxx7
-rw-r--r--sc/qa/unit/data/xlsx/functions-excel-2010.xlsxbin16074 -> 21127 bytes
-rw-r--r--sc/qa/unit/helper/shared_test_impl.hxx4
-rw-r--r--sc/qa/unit/ucalc.cxx2
-rw-r--r--sc/source/core/data/dociter.cxx132
-rw-r--r--sc/source/core/data/formulacell.cxx9
-rw-r--r--sc/source/core/inc/interpre.hxx2
-rw-r--r--sc/source/core/tool/interpr1.cxx45
-rw-r--r--sc/source/core/tool/interpr2.cxx6
-rw-r--r--sc/source/core/tool/interpr3.cxx14
-rw-r--r--sc/source/core/tool/interpr4.cxx3
-rw-r--r--sc/source/core/tool/interpr5.cxx4
-rw-r--r--sc/source/core/tool/interpr6.cxx573
-rw-r--r--sc/source/ui/src/scfuncs.src2
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
index c6d6ebb8abcc..152fbbc45a9f 100644
--- a/sc/qa/unit/data/xlsx/functions-excel-2010.xlsx
+++ b/sc/qa/unit/data/xlsx/functions-excel-2010.xlsx
Binary files differ
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;