diff options
author | Eike Rathke <erack@redhat.com> | 2020-08-20 18:53:02 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2020-08-20 19:57:30 +0200 |
commit | 64e19525eebd0974f1609300d95a74c1e083e8e3 (patch) | |
tree | 657b8e546a8610381401d379cd88c2d5b34bc700 | |
parent | 70126c3eb7a532b5f1e852d9ac81d0ece6edf0c3 (diff) |
Follow-up: tdf#132105 COUNTBLANK() count empty strings also in array/matrix
For Excel interoperability this somewhat is a *visual* blank,
unlike ISBLANK() empty strings are counted as blanks. An empty
string in a matrix can be either a formula result transformed to
matrix, or literal input in an inline array. There's no way to
differentiate the origin.
Change-Id: Ib799e95517d95e1a7c28fc4335bd0040f3629ad1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101083
Reviewed-by: Eike Rathke <erack@redhat.com>
Tested-by: Jenkins
-rw-r--r-- | sc/inc/scmatrix.hxx | 2 | ||||
-rw-r--r-- | sc/source/core/tool/interpr1.cxx | 6 | ||||
-rw-r--r-- | sc/source/core/tool/scmatrix.cxx | 30 |
3 files changed, 29 insertions, 9 deletions
diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx index 2efa73c4a975..e9a71e82b94d 100644 --- a/sc/inc/scmatrix.hxx +++ b/sc/inc/scmatrix.hxx @@ -365,7 +365,7 @@ public: 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 Count(bool bCountStrings, bool bCountErrors, bool bIgnoreEmptyStrings = false) 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 ; diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index f0e05b08795f..e76531eb031b 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -5183,7 +5183,11 @@ void ScInterpreter::ScCountEmptyCells() SCSIZE nC, nR; xMat->GetDimensions( nC, nR); nMaxCount = nC * nR; - nCount = xMat->Count( true, true); // numbers (implicit), strings and error values + // Numbers (implicit), strings and error values, ignore empty + // strings as those if not entered in an inline array are the + // result of a formula, to be par with a reference to formula + // cell as *visual* blank, see isCellContentEmpty() above. + nCount = xMat->Count( true, true, true); } } break; diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx index 7f1d915ec6c7..e841cdfdc13d 100644 --- a/sc/source/core/tool/scmatrix.cxx +++ b/sc/source/core/tool/scmatrix.cxx @@ -311,7 +311,7 @@ public: 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 Count(bool bCountStrings, bool bCountErrors, bool bIgnoreEmptyStrings) 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; @@ -1297,9 +1297,11 @@ class CountElements size_t mnCount; bool mbCountString; bool mbCountErrors; + bool mbIgnoreEmptyStrings; public: - explicit CountElements(bool bCountString, bool bCountErrors) : - mnCount(0), mbCountString(bCountString), mbCountErrors(bCountErrors) {} + explicit CountElements(bool bCountString, bool bCountErrors, bool bIgnoreEmptyStrings) : + mnCount(0), mbCountString(bCountString), mbCountErrors(bCountErrors), + mbIgnoreEmptyStrings(bIgnoreEmptyStrings) {} size_t getCount() const { return mnCount; } @@ -1327,7 +1329,21 @@ public: break; case mdds::mtm::element_string: if (mbCountString) + { mnCount += node.size; + if (mbIgnoreEmptyStrings) + { + typedef MatrixImplType::string_block_type block_type; + + 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 (it->isEmpty()) + --mnCount; + } + } + } break; case mdds::mtm::element_empty: default: @@ -2117,9 +2133,9 @@ ScMatrix::IterateResult ScMatrixImpl::Product(bool bTextAsZero, bool bIgnoreErro return GetValueWithCount<sc::op::Product>(bTextAsZero, bIgnoreErrorValues, maMat); } -size_t ScMatrixImpl::Count(bool bCountStrings, bool bCountErrors) const +size_t ScMatrixImpl::Count(bool bCountStrings, bool bCountErrors, bool bIgnoreEmptyStrings) const { - CountElements aFunc(bCountStrings, bCountErrors); + CountElements aFunc(bCountStrings, bCountErrors, bIgnoreEmptyStrings); aFunc = maMat.walk(aFunc); return aFunc.getCount(); } @@ -3235,9 +3251,9 @@ ScMatrix::IterateResult ScMatrix::Product(bool bTextAsZero, bool bIgnoreErrorVal return pImpl->Product(bTextAsZero, bIgnoreErrorValues); } -size_t ScMatrix::Count(bool bCountStrings, bool bCountErrors) const +size_t ScMatrix::Count(bool bCountStrings, bool bCountErrors, bool bIgnoreEmptyStrings) const { - return pImpl->Count(bCountStrings, bCountErrors); + return pImpl->Count(bCountStrings, bCountErrors, bIgnoreEmptyStrings); } size_t ScMatrix::MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const |