diff options
author | Eike Rathke <erack@redhat.com> | 2020-01-08 01:23:45 +0100 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2020-01-08 11:32:39 +0100 |
commit | 78d4e78c43f688a3617d659774d985d466bb39dc (patch) | |
tree | dd23b0723068c8fda8ffbb95304f4aa6d1f2c2e1 /sc | |
parent | 8faa519ad22db9d9db8bcf6d37dda1c7a7d7c850 (diff) |
Resolves: tdf#129681 Handle array/matrix in AGGREGATE() with ignore errors
This also changes AGGREGATE() 3rd and subsequent parameters'
classification from ReferenceOrRefArray to ReferenceOrForceArray
to force the expected array mode on inline calculations.
Change-Id: I53a5591e46bfbabbfa6a273f5b9590a69fad87a0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86388
Reviewed-by: Eike Rathke <erack@redhat.com>
Tested-by: Jenkins
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/scmatrix.hxx | 10 | ||||
-rw-r--r-- | sc/source/core/tool/interpr1.cxx | 22 | ||||
-rw-r--r-- | sc/source/core/tool/interpr3.cxx | 90 | ||||
-rw-r--r-- | sc/source/core/tool/interpr4.cxx | 1 | ||||
-rw-r--r-- | sc/source/core/tool/interpr6.cxx | 15 | ||||
-rw-r--r-- | sc/source/core/tool/parclass.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/tool/scmatrix.cxx | 88 |
7 files changed, 166 insertions, 62 deletions
diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx index ca9d3496be7a..2efa73c4a975 100644 --- a/sc/inc/scmatrix.hxx +++ b/sc/inc/scmatrix.hxx @@ -362,15 +362,15 @@ public: double Or() const ; // logical OR of all matrix values, or NAN double Xor() const ; // logical XOR of all matrix values, or NAN - IterateResult Sum(bool bTextAsZero) const ; - IterateResult SumSquare(bool bTextAsZero) const ; - IterateResult Product(bool bTextAsZero) const ; + IterateResult Sum( bool bTextAsZero, bool bIgnoreErrorValues = false ) const ; + IterateResult SumSquare( bool bTextAsZero, bool bIgnoreErrorValues = false ) const ; + IterateResult Product( bool bTextAsZero, bool bIgnoreErrorValues = false ) const ; size_t Count(bool bCountStrings, bool bCountErrors) const ; size_t MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const ; size_t MatchStringInColumns(const svl::SharedString& rStr, size_t nCol1, size_t nCol2) const ; - double GetMaxValue( bool bTextAsZero ) const ; - double GetMinValue( bool bTextAsZero ) const ; + double GetMaxValue( bool bTextAsZero, bool bIgnoreErrorValues = false ) const ; + double GetMinValue( bool bTextAsZero, bool bIgnoreErrorValues = false ) const ; double GetGcd() const ; double GetLcm() const ; diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index 175228ccb104..b6fa53b43528 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -3721,7 +3721,7 @@ void ScInterpreter::ScMin( bool bTextAsZero ) if (pMat) { nFuncFmtType = SvNumFormatType::NUMBER; - nVal = pMat->GetMinValue(bTextAsZero); + nVal = pMat->GetMinValue(bTextAsZero, bool(mnSubTotalFlags & SubtotalFlags::IgnoreErrVal)); if (nMin > nVal) nMin = nVal; } @@ -3879,7 +3879,7 @@ void ScInterpreter::ScMax( bool bTextAsZero ) if (pMat) { nFuncFmtType = SvNumFormatType::NUMBER; - nVal = pMat->GetMaxValue(bTextAsZero); + nVal = pMat->GetMaxValue(bTextAsZero, bool(mnSubTotalFlags & SubtotalFlags::IgnoreErrVal)); if (nMax < nVal) nMax = nVal; } @@ -4069,6 +4069,7 @@ void ScInterpreter::GetStVarParams( bool bTextAsZero, double(*VarResult)( double ScMatrixRef pMat = GetMatrix(); if (pMat) { + const bool bIgnoreErrVal = bool(mnSubTotalFlags & SubtotalFlags::IgnoreErrVal); SCSIZE nC, nR; pMat->GetDimensions(nC, nR); for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++) @@ -4083,6 +4084,8 @@ void ScInterpreter::GetStVarParams( bool bTextAsZero, double(*VarResult)( double values.push_back(fVal); fSum += fVal; } + else if (bIgnoreErrVal) + nGlobalError = FormulaError::NONE; } else if ( bTextAsZero ) { @@ -7565,6 +7568,9 @@ void ScInterpreter::ScAggregate() sal_uInt8 nParamCount = GetByte(); if ( MustHaveParamCountMin( nParamCount, 3 ) ) { + const FormulaError nErr = nGlobalError; + nGlobalError = FormulaError::NONE; + // fish the 1st parameter from the stack and push it on top. const FormulaToken* p = pStack[ sp - nParamCount ]; PushWithoutError( *p ); @@ -7575,7 +7581,10 @@ void ScInterpreter::ScAggregate() sal_Int32 nOption = GetInt32(); if ( nGlobalError != FormulaError::NONE || nFunc < 1 || nFunc > 19 ) + { + nGlobalError = nErr; PushIllegalArgument(); + } else { switch ( nOption) @@ -7605,10 +7614,14 @@ void ScInterpreter::ScAggregate() mnSubTotalFlags = SubtotalFlags::IgnoreHidden | SubtotalFlags::IgnoreErrVal ; break; default : + nGlobalError = nErr; PushIllegalArgument(); return; } + if ((mnSubTotalFlags & SubtotalFlags::IgnoreErrVal) == SubtotalFlags::NONE) + nGlobalError = nErr; + cPar = nParamCount - 2; switch ( nFunc ) { @@ -7631,7 +7644,10 @@ void ScInterpreter::ScAggregate() case AGGREGATE_FUNC_QRTINC : ScQuartile( true ); break; case AGGREGATE_FUNC_PERCEXC : ScPercentile( false ); break; case AGGREGATE_FUNC_QRTEXC : ScQuartile( false ); break; - default : PushIllegalArgument(); break; + default: + nGlobalError = nErr; + PushIllegalArgument(); + break; } mnSubTotalFlags = SubtotalFlags::NONE; } diff --git a/sc/source/core/tool/interpr3.cxx b/sc/source/core/tool/interpr3.cxx index 31dee4ce707e..ad9db97873bc 100644 --- a/sc/source/core/tool/interpr3.cxx +++ b/sc/source/core/tool/interpr3.cxx @@ -3943,6 +3943,7 @@ void ScInterpreter::GetNumberSequenceArray( sal_uInt8 nParamCount, vector<double { ScAddress aAdr; ScRange aRange; + const bool bIgnoreErrVal = bool(mnSubTotalFlags & SubtotalFlags::IgnoreErrVal); short nParam = nParamCount; size_t nRefInList = 0; ReverseStack( nParamCount ); @@ -3958,7 +3959,9 @@ void ScInterpreter::GetNumberSequenceArray( sal_uInt8 nParamCount, vector<double { PopSingleRef( aAdr ); ScRefCellValue aCell(*pDok, aAdr); - if (aCell.hasNumeric()) + if (bIgnoreErrVal && aCell.hasError()) + ; // nothing + else if (aCell.hasNumeric()) rArray.push_back(GetCellValue(aAdr, aCell)); } break; @@ -3979,11 +3982,24 @@ void ScInterpreter::GetNumberSequenceArray( sal_uInt8 nParamCount, vector<double ScValueIterator aValIter( pDok, aRange, mnSubTotalFlags ); if (aValIter.GetFirst( fCellVal, nErr)) { - rArray.push_back( fCellVal); - SetError(nErr); - while ((nErr == FormulaError::NONE) && aValIter.GetNext( fCellVal, nErr)) + if (bIgnoreErrVal) + { + if (nErr == FormulaError::NONE) + rArray.push_back( fCellVal); + while (aValIter.GetNext( fCellVal, nErr)) + { + if (nErr == FormulaError::NONE) + rArray.push_back( fCellVal); + } + } + else + { rArray.push_back( fCellVal); - SetError(nErr); + SetError(nErr); + while ((nErr == FormulaError::NONE) && aValIter.GetNext( fCellVal, nErr)) + rArray.push_back( fCellVal); + SetError(nErr); + } } } break; @@ -3999,15 +4015,40 @@ void ScInterpreter::GetNumberSequenceArray( sal_uInt8 nParamCount, vector<double rArray.reserve( rArray.size() + nCount); if (pMat->IsNumeric()) { - for (SCSIZE i = 0; i < nCount; ++i) - rArray.push_back( pMat->GetDouble(i)); + if (bIgnoreErrVal) + { + for (SCSIZE i = 0; i < nCount; ++i) + { + const double fVal = pMat->GetDouble(i); + if (nGlobalError == FormulaError::NONE) + rArray.push_back( fVal); + else + nGlobalError = FormulaError::NONE; + } + } + else + { + for (SCSIZE i = 0; i < nCount; ++i) + rArray.push_back( pMat->GetDouble(i)); + } } else if (bConvertTextInArray && eStackType == svMatrix) { for (SCSIZE i = 0; i < nCount; ++i) { if ( pMat->IsValue( i ) ) - rArray.push_back( pMat->GetDouble(i)); + { + if (bIgnoreErrVal) + { + const double fVal = pMat->GetDouble(i); + if (nGlobalError == FormulaError::NONE) + rArray.push_back( fVal); + else + nGlobalError = FormulaError::NONE; + } + else + rArray.push_back( pMat->GetDouble(i)); + } else { // tdf#88547 try to convert string to (date)value @@ -4024,13 +4065,17 @@ void ScInterpreter::GetNumberSequenceArray( sal_uInt8 nParamCount, vector<double } else { - rArray.push_back( CreateDoubleError( FormulaError::NoValue)); + if (!bIgnoreErrVal) + rArray.push_back( CreateDoubleError( FormulaError::NoValue)); // Propagate previous error if any, else - // the current #VALUE! error. + // the current #VALUE! error, unless + // ignoring error values. if (nErr != FormulaError::NONE) nGlobalError = nErr; - else + else if (!bIgnoreErrVal) nGlobalError = FormulaError::NoValue; + else + nGlobalError = FormulaError::NONE; } } } @@ -4038,10 +4083,27 @@ void ScInterpreter::GetNumberSequenceArray( sal_uInt8 nParamCount, vector<double } else { - for (SCSIZE i = 0; i < nCount; ++i) + if (bIgnoreErrVal) { - if ( pMat->IsValue( i ) ) - rArray.push_back( pMat->GetDouble(i)); + for (SCSIZE i = 0; i < nCount; ++i) + { + if (pMat->IsValue(i)) + { + const double fVal = pMat->GetDouble(i); + if (nGlobalError == FormulaError::NONE) + rArray.push_back( fVal); + else + nGlobalError = FormulaError::NONE; + } + } + } + else + { + for (SCSIZE i = 0; i < nCount; ++i) + { + if (pMat->IsValue(i)) + rArray.push_back( pMat->GetDouble(i)); + } } } } diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index 78a2bf59f7f2..b1a3658961ce 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -3926,6 +3926,7 @@ bool IsErrFunc(OpCode oc) case ocIfError : case ocIfNA : case ocErrorType_ODF : + case ocAggregate: // may ignore errors depending on option case ocIfs_MS: case ocSwitch_MS: return true; diff --git a/sc/source/core/tool/interpr6.cxx b/sc/source/core/tool/interpr6.cxx index 7038e4de1f81..327fff5b0e68 100644 --- a/sc/source/core/tool/interpr6.cxx +++ b/sc/source/core/tool/interpr6.cxx @@ -404,20 +404,20 @@ public: } static void IterateMatrix( - const ScMatrixRef& pMat, ScIterFunc eFunc, bool bTextAsZero, + const ScMatrixRef& pMat, ScIterFunc eFunc, bool bTextAsZero, SubtotalFlags nSubTotalFlags, sal_uLong& rCount, SvNumFormatType& rFuncFmtType, double& fRes, double& fMem ) { if (!pMat) return; - // TODO fdo73148 take mnSubTotalFlags into account + const bool bIgnoreErrVal = bool(nSubTotalFlags & SubtotalFlags::IgnoreErrVal); rFuncFmtType = SvNumFormatType::NUMBER; switch (eFunc) { case ifAVERAGE: case ifSUM: { - ScMatrix::IterateResult aRes = pMat->Sum(bTextAsZero); + ScMatrix::IterateResult aRes = pMat->Sum(bTextAsZero, bIgnoreErrVal); // If the first value is a NaN, it probably means it was an empty cell, // and should be treated as zero. if ( !rtl::math::isFinite(aRes.mfFirst) ) @@ -442,11 +442,12 @@ static void IterateMatrix( rCount += pMat->Count(bTextAsZero, false); // do not count error values break; case ifCOUNT2: + /* TODO: what is this supposed to be with bIgnoreErrVal? */ rCount += pMat->Count(true, true); // do count error values break; case ifPRODUCT: { - ScMatrix::IterateResult aRes = pMat->Product(bTextAsZero); + ScMatrix::IterateResult aRes = pMat->Product(bTextAsZero, bIgnoreErrVal); fRes *= aRes.mfFirst; fRes *= aRes.mfRest; rCount += aRes.mnCount; @@ -454,7 +455,7 @@ static void IterateMatrix( break; case ifSUMSQ: { - ScMatrix::IterateResult aRes = pMat->SumSquare(bTextAsZero); + ScMatrix::IterateResult aRes = pMat->SumSquare(bTextAsZero, bIgnoreErrVal); fRes += aRes.mfFirst; fRes += aRes.mfRest; rCount += aRes.mnCount; @@ -979,14 +980,14 @@ void ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) if ( nGlobalError != FormulaError::NONE && !( mnSubTotalFlags & SubtotalFlags::IgnoreErrVal ) ) break; - IterateMatrix( pMat, eFunc, bTextAsZero, nCount, nFuncFmtType, fRes, fMem ); + IterateMatrix( pMat, eFunc, bTextAsZero, mnSubTotalFlags, nCount, nFuncFmtType, fRes, fMem ); } break; case svMatrix : { ScMatrixRef pMat = PopMatrix(); - IterateMatrix( pMat, eFunc, bTextAsZero, nCount, nFuncFmtType, fRes, fMem ); + IterateMatrix( pMat, eFunc, bTextAsZero, mnSubTotalFlags, nCount, nFuncFmtType, fRes, fMem ); } break; case svError: diff --git a/sc/source/core/tool/parclass.cxx b/sc/source/core/tool/parclass.cxx index e05b48e0436d..f285df49b632 100644 --- a/sc/source/core/tool/parclass.cxx +++ b/sc/source/core/tool/parclass.cxx @@ -99,7 +99,7 @@ const ScParameterClassification::RawData ScParameterClassification::pRawData[] = { ocTableOp, {{ Value, Value, Value, Value, Value }, 0, Value }}, // Operators and functions. { ocAdd, {{ Array, Array }, 0, Value }}, - { ocAggregate, {{ Value, Value, ReferenceOrRefArray }, 1, Value }}, + { ocAggregate, {{ Value, Value, ReferenceOrForceArray }, 1, Value }}, { ocAmpersand, {{ Array, Array }, 0, Value }}, { ocAnd, {{ Reference }, 1, Value }}, { ocAreas, {{ Reference }, 0, Value }}, diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx index 934c14d3159a..869a91406d56 100644 --- a/sc/source/core/tool/scmatrix.cxx +++ b/sc/source/core/tool/scmatrix.cxx @@ -308,15 +308,15 @@ public: double Or() const; double Xor() const; - ScMatrix::IterateResult Sum(bool bTextAsZero) const; - ScMatrix::IterateResult SumSquare(bool bTextAsZero) const; - ScMatrix::IterateResult Product(bool bTextAsZero) const; + ScMatrix::IterateResult Sum( bool bTextAsZero, bool bIgnoreErrorValues ) const; + ScMatrix::IterateResult SumSquare( bool bTextAsZero, bool bIgnoreErrorValues ) const; + ScMatrix::IterateResult Product( bool bTextAsZero, bool bIgnoreErrorValues ) const; size_t Count(bool bCountStrings, bool bCountErrors) const; size_t MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const; size_t MatchStringInColumns(const svl::SharedString& rStr, size_t nCol1, size_t nCol2) const; - double GetMaxValue( bool bTextAsZero ) const; - double GetMinValue( bool bTextAsZero ) const; + double GetMaxValue( bool bTextAsZero, bool bIgnoreErrorValues ) const; + double GetMinValue( bool bTextAsZero, bool bIgnoreErrorValues ) const; double GetGcd() const; double GetLcm() const; @@ -1120,8 +1120,12 @@ class WalkElementBlocks ScMatrix::IterateResult maRes; bool mbFirst:1; bool mbTextAsZero:1; + bool mbIgnoreErrorValues:1; public: - WalkElementBlocks(bool bTextAsZero) : maRes(Op::InitVal, Op::InitVal, 0), mbFirst(true), mbTextAsZero(bTextAsZero) {} + WalkElementBlocks(bool bTextAsZero, bool bIgnoreErrorValues) : + maRes(Op::InitVal, Op::InitVal, 0), mbFirst(true), + mbTextAsZero(bTextAsZero), mbIgnoreErrorValues(bIgnoreErrorValues) + {} const ScMatrix::IterateResult& getResult() const { return maRes; } @@ -1133,10 +1137,17 @@ public: { typedef MatrixImplType::numeric_block_type block_type; + size_t nIgnored = 0; block_type::const_iterator it = block_type::begin(*node.data); block_type::const_iterator itEnd = block_type::end(*node.data); for (; it != itEnd; ++it) { + if (mbIgnoreErrorValues && !rtl::math::isFinite(*it)) + { + ++nIgnored; + continue; + } + if (mbFirst) { maOp(maRes.mfFirst, *it); @@ -1147,7 +1158,7 @@ public: maOp(maRes.mfRest, *it); } } - maRes.mnCount += node.size; + maRes.mnCount += node.size - nIgnored; } break; case mdds::mtm::element_boolean: @@ -1535,11 +1546,13 @@ class CalcMaxMinValue { double mfVal; bool mbTextAsZero; + bool mbIgnoreErrorValues; bool mbHasValue; public: - CalcMaxMinValue( bool bTextAsZero ) : + CalcMaxMinValue( bool bTextAsZero, bool bIgnoreErrorValues ) : mfVal(Op::init()), mbTextAsZero(bTextAsZero), + mbIgnoreErrorValues(bIgnoreErrorValues), mbHasValue(false) {} double getValue() const { return mbHasValue ? mfVal : 0.0; } @@ -1555,8 +1568,19 @@ public: block_type::const_iterator it = block_type::begin(*node.data); block_type::const_iterator itEnd = block_type::end(*node.data); - for (; it != itEnd; ++it) - mfVal = Op::compare(mfVal, *it); + if (mbIgnoreErrorValues) + { + for (; it != itEnd; ++it) + { + if (rtl::math::isFinite(*it)) + mfVal = Op::compare(mfVal, *it); + } + } + else + { + for (; it != itEnd; ++it) + mfVal = Op::compare(mfVal, *it); + } mbHasValue = true; } @@ -2069,28 +2093,28 @@ public: namespace { template<typename TOp> -ScMatrix::IterateResult GetValueWithCount(bool bTextAsZero, const MatrixImplType& maMat) +ScMatrix::IterateResult GetValueWithCount(bool bTextAsZero, bool bIgnoreErrorValues, const MatrixImplType& maMat) { - WalkElementBlocks<TOp> aFunc(bTextAsZero); + WalkElementBlocks<TOp> aFunc(bTextAsZero, bIgnoreErrorValues); aFunc = maMat.walk(aFunc); return aFunc.getResult(); } } -ScMatrix::IterateResult ScMatrixImpl::Sum(bool bTextAsZero) const +ScMatrix::IterateResult ScMatrixImpl::Sum(bool bTextAsZero, bool bIgnoreErrorValues) const { - return GetValueWithCount<sc::op::Sum>(bTextAsZero, maMat); + return GetValueWithCount<sc::op::Sum>(bTextAsZero, bIgnoreErrorValues, maMat); } -ScMatrix::IterateResult ScMatrixImpl::SumSquare(bool bTextAsZero) const +ScMatrix::IterateResult ScMatrixImpl::SumSquare(bool bTextAsZero, bool bIgnoreErrorValues) const { - return GetValueWithCount<sc::op::SumSquare>(bTextAsZero, maMat); + return GetValueWithCount<sc::op::SumSquare>(bTextAsZero, bIgnoreErrorValues, maMat); } -ScMatrix::IterateResult ScMatrixImpl::Product(bool bTextAsZero) const +ScMatrix::IterateResult ScMatrixImpl::Product(bool bTextAsZero, bool bIgnoreErrorValues) const { - return GetValueWithCount<sc::op::Product>(bTextAsZero, maMat); + return GetValueWithCount<sc::op::Product>(bTextAsZero, bIgnoreErrorValues, maMat); } size_t ScMatrixImpl::Count(bool bCountStrings, bool bCountErrors) const @@ -2114,16 +2138,16 @@ size_t ScMatrixImpl::MatchStringInColumns(const svl::SharedString& rStr, size_t return aFunc.getMatching(); } -double ScMatrixImpl::GetMaxValue( bool bTextAsZero ) const +double ScMatrixImpl::GetMaxValue( bool bTextAsZero, bool bIgnoreErrorValues ) const { - CalcMaxMinValue<MaxOp> aFunc(bTextAsZero); + CalcMaxMinValue<MaxOp> aFunc(bTextAsZero, bIgnoreErrorValues); aFunc = maMat.walk(aFunc); return aFunc.getValue(); } -double ScMatrixImpl::GetMinValue( bool bTextAsZero ) const +double ScMatrixImpl::GetMinValue( bool bTextAsZero, bool bIgnoreErrorValues ) const { - CalcMaxMinValue<MinOp> aFunc(bTextAsZero); + CalcMaxMinValue<MinOp> aFunc(bTextAsZero, bIgnoreErrorValues); aFunc = maMat.walk(aFunc); return aFunc.getValue(); } @@ -3194,19 +3218,19 @@ double ScMatrix::Xor() const return pImpl->Xor(); } -ScMatrix::IterateResult ScMatrix::Sum(bool bTextAsZero) const +ScMatrix::IterateResult ScMatrix::Sum(bool bTextAsZero, bool bIgnoreErrorValues) const { - return pImpl->Sum(bTextAsZero); + return pImpl->Sum(bTextAsZero, bIgnoreErrorValues); } -ScMatrix::IterateResult ScMatrix::SumSquare(bool bTextAsZero) const +ScMatrix::IterateResult ScMatrix::SumSquare(bool bTextAsZero, bool bIgnoreErrorValues) const { - return pImpl->SumSquare(bTextAsZero); + return pImpl->SumSquare(bTextAsZero, bIgnoreErrorValues); } -ScMatrix::IterateResult ScMatrix::Product(bool bTextAsZero) const +ScMatrix::IterateResult ScMatrix::Product(bool bTextAsZero, bool bIgnoreErrorValues) const { - return pImpl->Product(bTextAsZero); + return pImpl->Product(bTextAsZero, bIgnoreErrorValues); } size_t ScMatrix::Count(bool bCountStrings, bool bCountErrors) const @@ -3224,14 +3248,14 @@ size_t ScMatrix::MatchStringInColumns(const svl::SharedString& rStr, size_t nCol return pImpl->MatchStringInColumns(rStr, nCol1, nCol2); } -double ScMatrix::GetMaxValue( bool bTextAsZero ) const +double ScMatrix::GetMaxValue( bool bTextAsZero, bool bIgnoreErrorValues ) const { - return pImpl->GetMaxValue(bTextAsZero); + return pImpl->GetMaxValue(bTextAsZero, bIgnoreErrorValues); } -double ScMatrix::GetMinValue( bool bTextAsZero ) const +double ScMatrix::GetMinValue( bool bTextAsZero, bool bIgnoreErrorValues ) const { - return pImpl->GetMinValue(bTextAsZero); + return pImpl->GetMinValue(bTextAsZero, bIgnoreErrorValues); } double ScMatrix::GetGcd() const |