summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2016-06-07 16:10:30 +0200
committerEike Rathke <erack@redhat.com>2016-06-07 16:16:53 +0200
commit1bcfa6212553b1d130036f0d1e5bc0dc0692b706 (patch)
treeb7ebf75268b4d852153966eac7202f2f98488f26
parentec2425ad5fb39df5ad952b27d49e172fdd7ff00d (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.hxx2
-rw-r--r--sc/source/core/tool/interpr2.cxx62
-rw-r--r--sc/source/core/tool/interpr4.cxx60
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())