diff options
author | Eike Rathke <erack@redhat.com> | 2016-06-07 16:10:30 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2016-06-07 16:16:53 +0200 |
commit | 1bcfa6212553b1d130036f0d1e5bc0dc0692b706 (patch) | |
tree | b7ebf75268b4d852153966eac7202f2f98488f26 | |
parent | ec2425ad5fb39df5ad952b27d49e172fdd7ff00d (diff) |
attempt to obtain numeric constraint values for GETPIVOTDATA(), tdf#35247
This helps for a very basic
GETPIVOTDATA(A1,A1,"fieldname",DATE(1999,12,23))
to recognize the date value, but still fails for not so simple
expressions or if there are more than one constraints, as we don't
transport type information in tokens yet.
Change-Id: I3dba8959b580e823af2b1352adb147ca9e4b9285
-rw-r--r-- | sc/source/core/inc/interpre.hxx | 2 | ||||
-rw-r--r-- | sc/source/core/tool/interpr2.cxx | 62 | ||||
-rw-r--r-- | sc/source/core/tool/interpr4.cxx | 60 |
3 files changed, 114 insertions, 10 deletions
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index a01b60bcb937..5b1c2fe9ca18 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -388,6 +388,8 @@ double GetDouble(); double GetDoubleWithDefault(double nDefault); bool IsMissing(); bool GetBool() { return GetDouble() != 0.0; } +/// returns TRUE if double (or error, check nGlobalError), else FALSE +bool GetDoubleOrString( double& rValue, svl::SharedString& rString ); svl::SharedString GetString(); svl::SharedString GetStringFromMatrix(const ScMatrixRef& pMat); // pop matrix and obtain one element, upper left or according to jump matrix diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx index f82756543a27..343f57134f57 100644 --- a/sc/source/core/tool/interpr2.cxx +++ b/sc/source/core/tool/interpr2.cxx @@ -3307,22 +3307,57 @@ void ScInterpreter::ScGetPivotData() sal_uInt16 i = nFilterCount; while (i-- > 0) { - /* TODO: should allow numeric constraint values. */ - /* TODO: also, in case of numeric the entire filter match should * not be on a (even if locale independent) formatted string down * below in pDPObj->GetPivotData(). */ - aFilters[i].MatchValueName = GetString().getString(); + /* TODO: obtaining the current format before a double is popped + * works only by chance, e.g. if the very recent function call was + * DATE() or some such. We really need to transport format/type + * information in tokens. */ + short nThisFmtType = nCurFmtType; + sal_uInt32 nThisFmtIndex = nCurFmtIndex; + + double fDouble; + svl::SharedString aSharedString; + bool bDouble = GetDoubleOrString( fDouble, aSharedString); + if (nGlobalError) + { + PushError( nGlobalError); + return; + } - // Parse possible number from MatchValueName and format - // locale independent as MatchValue. - sal_uInt32 nNumFormat; - double fValue; - if (pFormatter->IsNumberFormat( aFilters[i].MatchValueName, nNumFormat, fValue)) - aFilters[i].MatchValue = ScDPCache::GetLocaleIndependentFormattedString( fValue, *pFormatter, nNumFormat); + if (bDouble) + { + sal_uInt32 nNumFormat; + if (nThisFmtIndex) + nNumFormat = nThisFmtIndex; + else + { + if (nThisFmtType == css::util::NumberFormat::UNDEFINED) + nNumFormat = 0; + else + nNumFormat = pFormatter->GetStandardFormat( nThisFmtType, ScGlobal::eLnge); + } + Color* pColor; + pFormatter->GetOutputString( fDouble, nNumFormat, aFilters[i].MatchValueName, &pColor); + aFilters[i].MatchValue = ScDPCache::GetLocaleIndependentFormattedString( + fDouble, *pFormatter, nNumFormat); + } else - aFilters[i].MatchValue = aFilters[i].MatchValueName; + { + aFilters[i].MatchValueName = aSharedString.getString(); + + // Parse possible number from MatchValueName and format + // locale independent as MatchValue. + sal_uInt32 nNumFormat; + double fValue; + if (pFormatter->IsNumberFormat( aFilters[i].MatchValueName, nNumFormat, fValue)) + aFilters[i].MatchValue = ScDPCache::GetLocaleIndependentFormattedString( + fValue, *pFormatter, nNumFormat); + else + aFilters[i].MatchValue = aFilters[i].MatchValueName; + } aFilters[i].FieldName = GetString().getString(); } @@ -3347,6 +3382,13 @@ void ScInterpreter::ScGetPivotData() aDataFieldName = GetString().getString(); // First parameter is data field name. } + // Early bail-out, don't grind through data pilot cache and all. + if (nGlobalError) + { + PushError( nGlobalError); + return; + } + // NOTE : MS Excel docs claim to use the 'most recent' which is not // exactly the same as what we do in ScDocument::GetDPAtBlock // However we do need to use GetDPABlock diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index 2e9fe7c12496..a9363a72930f 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -2061,6 +2061,66 @@ double ScInterpreter::GetDoubleWithDefault(double nDefault) return nResultVal; } +bool ScInterpreter::GetDoubleOrString( double& rDouble, svl::SharedString& rString ) +{ + bool bDouble = true; + switch( GetRawStackType() ) + { + case svDouble: + rDouble = PopDouble(); + break; + case svString: + rString = PopString(); + bDouble = false; + break; + case svDoubleRef : + case svSingleRef : + { + ScAddress aAdr; + if (!PopDoubleRefOrSingleRef( aAdr)) + { + rDouble = 0.0; + return true; // caller needs to check nGlobalError + } + ScRefCellValue aCell( *pDok, aAdr); + if (aCell.hasNumeric()) + { + rDouble = GetCellValue( aAdr, aCell); + } + else + { + GetCellString( rString, aCell); + bDouble = false; + } + } + break; + case svExternalSingleRef: + case svExternalDoubleRef: + case svMatrix: + { + ScMatValType nType = GetDoubleOrStringFromMatrix( rDouble, rString); + bDouble = ScMatrix::IsValueType( nType); + } + break; + case svError: + PopError(); + rDouble = 0.0; + break; + case svEmptyCell: + case svMissing: + Pop(); + rDouble = 0.0; + break; + default: + PopError(); + SetError( errIllegalParameter); + rDouble = 0.0; + } + if ( nFuncFmtType == nCurFmtType ) + nFuncFmtIndex = nCurFmtIndex; + return bDouble; +} + svl::SharedString ScInterpreter::GetString() { switch (GetRawStackType()) |