Kaydet (Commit) 1bcfa621 authored tarafından Eike Rathke's avatar Eike Rathke

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
üst ec2425ad
...@@ -388,6 +388,8 @@ double GetDouble(); ...@@ -388,6 +388,8 @@ double GetDouble();
double GetDoubleWithDefault(double nDefault); double GetDoubleWithDefault(double nDefault);
bool IsMissing(); bool IsMissing();
bool GetBool() { return GetDouble() != 0.0; } 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 GetString();
svl::SharedString GetStringFromMatrix(const ScMatrixRef& pMat); svl::SharedString GetStringFromMatrix(const ScMatrixRef& pMat);
// pop matrix and obtain one element, upper left or according to jump matrix // pop matrix and obtain one element, upper left or according to jump matrix
......
...@@ -3307,22 +3307,57 @@ void ScInterpreter::ScGetPivotData() ...@@ -3307,22 +3307,57 @@ void ScInterpreter::ScGetPivotData()
sal_uInt16 i = nFilterCount; sal_uInt16 i = nFilterCount;
while (i-- > 0) while (i-- > 0)
{ {
/* TODO: should allow numeric constraint values. */
/* TODO: also, in case of numeric the entire filter match should /* TODO: also, in case of numeric the entire filter match should
* not be on a (even if locale independent) formatted string down * not be on a (even if locale independent) formatted string down
* below in pDPObj->GetPivotData(). */ * 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 if (bDouble)
// locale independent as MatchValue. {
sal_uInt32 nNumFormat; sal_uInt32 nNumFormat;
double fValue; if (nThisFmtIndex)
if (pFormatter->IsNumberFormat( aFilters[i].MatchValueName, nNumFormat, fValue)) nNumFormat = nThisFmtIndex;
aFilters[i].MatchValue = ScDPCache::GetLocaleIndependentFormattedString( fValue, *pFormatter, nNumFormat); 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 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(); aFilters[i].FieldName = GetString().getString();
} }
...@@ -3347,6 +3382,13 @@ void ScInterpreter::ScGetPivotData() ...@@ -3347,6 +3382,13 @@ void ScInterpreter::ScGetPivotData()
aDataFieldName = GetString().getString(); // First parameter is data field name. 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 // NOTE : MS Excel docs claim to use the 'most recent' which is not
// exactly the same as what we do in ScDocument::GetDPAtBlock // exactly the same as what we do in ScDocument::GetDPAtBlock
// However we do need to use GetDPABlock // However we do need to use GetDPABlock
......
...@@ -2061,6 +2061,66 @@ double ScInterpreter::GetDoubleWithDefault(double nDefault) ...@@ -2061,6 +2061,66 @@ double ScInterpreter::GetDoubleWithDefault(double nDefault)
return nResultVal; 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() svl::SharedString ScInterpreter::GetString()
{ {
switch (GetRawStackType()) switch (GetRawStackType())
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment