Kaydet (Commit) 0637ca0a authored tarafından Kohei Yoshida's avatar Kohei Yoshida

Populate group dimensions directly to the cache.

This is to avoid populating them twice in case the same cache is
referenced by multiple pivot tables.
üst 593f6ac1
...@@ -52,13 +52,14 @@ class ScDPSaveGroupDimension; ...@@ -52,13 +52,14 @@ class ScDPSaveGroupDimension;
class SC_DLLPUBLIC ScDPSaveGroupItem class SC_DLLPUBLIC ScDPSaveGroupItem
{ {
rtl::OUString aGroupName; // name of group rtl::OUString aGroupName; // name of group
::std::vector<rtl::OUString> aElements; // names of items in original dimension std::vector<rtl::OUString> aElements; // names of items in original dimension
mutable std::vector<ScDPItemData> maItems; // items converted from the strings.
public: public:
ScDPSaveGroupItem( const rtl::OUString& rName ); ScDPSaveGroupItem( const rtl::OUString& rName );
~ScDPSaveGroupItem(); ~ScDPSaveGroupItem();
void AddToData( ScDPGroupDimension& rDataDim, SvNumberFormatter* pFormatter ) const; void AddToData(ScDPGroupDimension& rDataDim) const;
void AddElement( const rtl::OUString& rName ); void AddElement( const rtl::OUString& rName );
void AddElementsFromGroup( const ScDPSaveGroupItem& rGroup ); void AddElementsFromGroup( const ScDPSaveGroupItem& rGroup );
...@@ -74,6 +75,9 @@ public: ...@@ -74,6 +75,9 @@ public:
// remove this group's elements from their groups in rDimension // remove this group's elements from their groups in rDimension
// (rDimension must be a different dimension from the one which contains this) // (rDimension must be a different dimension from the one which contains this)
void RemoveElementsFromGroups( ScDPSaveGroupDimension& rDimension ) const; void RemoveElementsFromGroups( ScDPSaveGroupDimension& rDimension ) const;
void ConvertElementsToItems(SvNumberFormatter* pFormatter) const;
bool HasInGroup(const ScDPItemData& rItem) const;
}; };
typedef ::std::vector<ScDPSaveGroupItem> ScDPSaveGroupItemVec; typedef ::std::vector<ScDPSaveGroupItem> ScDPSaveGroupItemVec;
...@@ -87,7 +91,7 @@ class SC_DLLPUBLIC ScDPSaveGroupDimension ...@@ -87,7 +91,7 @@ class SC_DLLPUBLIC ScDPSaveGroupDimension
rtl::OUString aSourceDim; // always the real source from the original data rtl::OUString aSourceDim; // always the real source from the original data
rtl::OUString aGroupDimName; rtl::OUString aGroupDimName;
ScDPSaveGroupItemVec aGroups; ScDPSaveGroupItemVec aGroups;
ScDPNumGroupInfo aDateInfo; mutable ScDPNumGroupInfo aDateInfo;
sal_Int32 nDatePart; sal_Int32 nDatePart;
public: public:
...@@ -96,7 +100,7 @@ public: ...@@ -96,7 +100,7 @@ public:
~ScDPSaveGroupDimension(); ~ScDPSaveGroupDimension();
void AddToData( ScDPGroupTableData& rData ) const; void AddToData( ScDPGroupTableData& rData ) const;
void AddToCache(ScDPCache& rCache) const;
void SetDateInfo( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart ); void SetDateInfo( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart );
void AddGroupItem( const ScDPSaveGroupItem& rItem ); void AddGroupItem( const ScDPSaveGroupItem& rItem );
...@@ -119,18 +123,21 @@ public: ...@@ -119,18 +123,21 @@ public:
ScDPSaveGroupItem* GetGroupAccByIndex( long nIndex ); ScDPSaveGroupItem* GetGroupAccByIndex( long nIndex );
void Rename( const rtl::OUString& rNewName ); void Rename( const rtl::OUString& rNewName );
private:
bool IsInGroup(const ScDPItemData& rItem) const;
}; };
/** /**
* Represents a group dimension that introduces a new hierarchy for an * Represents a group dimension that introduces a new hierarchy for an
* existing dimension. Unlike the ScDPSaveGroupDimension counterpart, it * existing dimension. Unlike the ScDPSaveGroupDimension counterpart, it
* re-uses the source dimension. * re-uses the source dimension name and ID.
*/ */
class SC_DLLPUBLIC ScDPSaveNumGroupDimension class SC_DLLPUBLIC ScDPSaveNumGroupDimension
{ {
rtl::OUString aDimensionName; rtl::OUString aDimensionName;
ScDPNumGroupInfo aGroupInfo; mutable ScDPNumGroupInfo aGroupInfo;
ScDPNumGroupInfo aDateInfo; mutable ScDPNumGroupInfo aDateInfo;
sal_Int32 nDatePart; sal_Int32 nDatePart;
public: public:
...@@ -139,6 +146,7 @@ public: ...@@ -139,6 +146,7 @@ public:
~ScDPSaveNumGroupDimension(); ~ScDPSaveNumGroupDimension();
void AddToData( ScDPGroupTableData& rData ) const; void AddToData( ScDPGroupTableData& rData ) const;
void AddToCache(ScDPCache& rCache) const;
const rtl::OUString& GetDimensionName() const { return aDimensionName; } const rtl::OUString& GetDimensionName() const { return aDimensionName; }
const ScDPNumGroupInfo& GetInfo() const { return aGroupInfo; } const ScDPNumGroupInfo& GetInfo() const { return aGroupInfo; }
......
...@@ -60,9 +60,7 @@ public: ...@@ -60,9 +60,7 @@ public:
sal_Int32 GetDatePart() const { return nDatePart; } sal_Int32 GetDatePart() const { return nDatePart; }
const ScDPNumGroupInfo& GetNumInfo() const { return aNumInfo; } const ScDPNumGroupInfo& GetNumInfo() const { return aNumInfo; }
void FillColumnEntries( void FillColumnEntries(const ScDPCache* pCache, std::vector<SCROW>& rEntries) const;
SCCOL nSourceDim, ScDPCache* pCahe , std::vector<SCROW>& rEntries,
const std::vector<SCROW>& rOriginal) const;
}; };
typedef ::std::vector<ScDPItemData> ScDPItemDataVec; typedef ::std::vector<ScDPItemData> ScDPItemDataVec;
...@@ -143,8 +141,7 @@ public: ...@@ -143,8 +141,7 @@ public:
const ScDPDateGroupHelper* GetDateHelper() const { return pDateHelper; } const ScDPDateGroupHelper* GetDateHelper() const { return pDateHelper; }
const std::vector<SCROW>& GetNumEntries( const std::vector<SCROW>& GetNumEntries(SCCOL nSourceDim, const ScDPCache* pCache) const;
SCCOL nSourceDim, ScDPCache* pCache, const std::vector<SCROW>& rOriginal) const;
void MakeDateHelper( const ScDPNumGroupInfo& rInfo, long nDim, sal_Int32 nPart ); void MakeDateHelper( const ScDPNumGroupInfo& rInfo, long nDim, sal_Int32 nPart );
......
...@@ -131,15 +131,16 @@ public: ...@@ -131,15 +131,16 @@ public:
SCROW GetIdByItemData(long nDim, const rtl::OUString& sItemData) const; SCROW GetIdByItemData(long nDim, const rtl::OUString& sItemData) const;
SCROW GetIdByItemData(long nDim, const ScDPItemData& rItem) const; SCROW GetIdByItemData(long nDim, const ScDPItemData& rItem) const;
rtl::OUString GetFormattedString(long nDim, const ScDPItemData& rItem) const; rtl::OUString GetFormattedString(long nDim, const ScDPItemData& rItem) const;
void AppendGroupField(); long AppendGroupField();
void ResetGroupItems(long nDim, const ScDPNumGroupInfo& rNumInfo); void ResetGroupItems(long nDim, const ScDPNumGroupInfo& rNumInfo);
SCROW SetGroupItem(long nDim, const ScDPItemData& rData); SCROW SetGroupItem(long nDim, const ScDPItemData& rData);
const DataListType* GetGroupDimMemberValues(long nDim) const;
void GetGroupDimMemberIds(long nDim, std::vector<SCROW>& rIds) const;
void ClearGroupFields(); void ClearGroupFields();
SCROW GetAdditionalItemID( const ScDPItemData& rData ) const; SCROW GetAdditionalItemID( const ScDPItemData& rData ) const;
SCCOL GetDimensionIndex(const rtl::OUString& sName) const; SCCOL GetDimensionIndex(const rtl::OUString& sName) const;
sal_uLong GetNumType ( sal_uLong nFormat ) const;
sal_uLong GetNumberFormat( long nDim ) const; sal_uLong GetNumberFormat( long nDim ) const;
bool IsDateDimension( long nDim ) const ; bool IsDateDimension( long nDim ) const ;
SCROW GetDimMemberCount( SCCOL nDim ) const; SCROW GetDimMemberCount( SCCOL nDim ) const;
...@@ -151,12 +152,12 @@ public: ...@@ -151,12 +152,12 @@ public:
SCROW GetRowCount() const; SCROW GetRowCount() const;
SCROW GetItemDataId( sal_uInt16 nDim, SCROW nRow, bool bRepeatIfEmpty ) const; SCROW GetItemDataId( sal_uInt16 nDim, SCROW nRow, bool bRepeatIfEmpty ) const;
rtl::OUString GetDimensionName( sal_uInt16 nColumn ) const; rtl::OUString GetDimensionName(long nDim) const;
bool IsRowEmpty( SCROW nRow ) const; bool IsRowEmpty( SCROW nRow ) const;
bool IsValid() const; bool IsValid() const;
bool ValidQuery(SCROW nRow, const ScQueryParam& rQueryParam) const; bool ValidQuery(SCROW nRow, const ScQueryParam& rQueryParam) const;
ScDocument* GetDoc() const;//ms-cache-core ScDocument* GetDoc() const;
long GetColumnCount() const; long GetColumnCount() const;
long GetGroupFieldCount() const; long GetGroupFieldCount() const;
......
...@@ -51,7 +51,12 @@ public: ...@@ -51,7 +51,12 @@ public:
static double getNumGroupStartValue(double fValue, const ScDPNumGroupInfo& rInfo); static double getNumGroupStartValue(double fValue, const ScDPNumGroupInfo& rInfo);
static rtl::OUString getNumGroupName( static rtl::OUString getNumGroupName(
double fValue, const ScDPNumGroupInfo& rInfo, sal_Unicode cDecSep, SvNumberFormatter* pFormatter); double fValue, const ScDPNumGroupInfo& rInfo, sal_Unicode cDecSep,
SvNumberFormatter* pFormatter);
static sal_Int32 getDatePartValue(
double fValue, const ScDPNumGroupInfo& rInfo, sal_Int32 nDatePart,
SvNumberFormatter* pFormatter);
}; };
#endif #endif
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "dpdimsave.hxx" #include "dpdimsave.hxx"
#include "dpgroup.hxx" #include "dpgroup.hxx"
#include "dpobject.hxx" #include "dpobject.hxx"
#include "dputil.hxx"
#include "document.hxx" #include "document.hxx"
#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp> #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
...@@ -38,6 +39,8 @@ ...@@ -38,6 +39,8 @@
#include <rtl/math.hxx> #include <rtl/math.hxx>
#include <algorithm> #include <algorithm>
using namespace com::sun::star;
#include <stdio.h> #include <stdio.h>
#include <string> #include <string>
#include <sys/time.h> #include <sys/time.h>
...@@ -142,25 +145,37 @@ void ScDPSaveGroupItem::RemoveElementsFromGroups( ScDPSaveGroupDimension& rDimen ...@@ -142,25 +145,37 @@ void ScDPSaveGroupItem::RemoveElementsFromGroups( ScDPSaveGroupDimension& rDimen
rDimension.RemoveFromGroups( *aIter ); rDimension.RemoveFromGroups( *aIter );
} }
void ScDPSaveGroupItem::AddToData( ScDPGroupDimension& rDataDim, SvNumberFormatter* pFormatter ) const void ScDPSaveGroupItem::ConvertElementsToItems(SvNumberFormatter* pFormatter) const
{ {
ScDPGroupItem aGroup(aGroupName); maItems.reserve(aElements.size());
ScDPItemData aData; std::vector<rtl::OUString>::const_iterator it = aElements.begin(), itEnd = aElements.end();
for (; it != itEnd; ++it)
for ( std::vector<rtl::OUString>::const_iterator aIter(aElements.begin()); aIter != aElements.end(); aIter++ )
{ {
sal_uInt32 nFormat = 0; //! ... sal_uInt32 nFormat = 0;
double fValue; double fValue;
if ( pFormatter->IsNumberFormat( *aIter, nFormat, fValue ) ) ScDPItemData aData;
if (pFormatter->IsNumberFormat(*it, nFormat, fValue))
aData.SetValue(fValue); aData.SetValue(fValue);
else else
aData.SetString( *aIter ); aData.SetString(*it);
aGroup.AddElement( aData ); maItems.push_back(aData);
//! for numeric data, look at source members?
} }
}
rDataDim.AddItem( aGroup ); bool ScDPSaveGroupItem::HasInGroup(const ScDPItemData& rItem) const
{
return std::find(maItems.begin(), maItems.end(), rItem) != maItems.end();
}
void ScDPSaveGroupItem::AddToData(ScDPGroupDimension& rDataDim) const
{
ScDPGroupItem aGroup(aGroupName);
std::vector<ScDPItemData>::const_iterator it = maItems.begin(), itEnd = maItems.end();
for (; it != itEnd; ++it)
aGroup.AddElement(*it);
rDataDim.AddItem(aGroup);
} }
// ============================================================================ // ============================================================================
...@@ -303,6 +318,99 @@ void ScDPSaveGroupDimension::Rename( const rtl::OUString& rNewName ) ...@@ -303,6 +318,99 @@ void ScDPSaveGroupDimension::Rename( const rtl::OUString& rNewName )
aGroupDimName = rNewName; aGroupDimName = rNewName;
} }
bool ScDPSaveGroupDimension::IsInGroup(const ScDPItemData& rItem) const
{
ScDPSaveGroupItemVec::const_iterator it = aGroups.begin(), itEnd = aGroups.end();
for (; it != itEnd; ++it)
{
if (it->HasInGroup(rItem))
return true;
}
return false;
}
namespace {
inline bool isInteger(double fValue)
{
return rtl::math::approxEqual(fValue, rtl::math::approxFloor(fValue));
}
void fillDateGroupDimension(
ScDPCache& rCache, ScDPNumGroupInfo& rDateInfo, long nSourceDim, long nGroupDim,
sal_Int32 nDatePart, SvNumberFormatter* pFormatter)
{
// Auto min/max is only used for "Years" part, but the loop is always
// needed.
double fSourceMin = 0.0;
double fSourceMax = 0.0;
bool bFirst = true;
const ScDPCache::DataListType& rItems = rCache.GetDimMemberValues(nSourceDim);
ScDPCache::DataListType::const_iterator it = rItems.begin(), itEnd = rItems.end();
for (; it != itEnd; ++it)
{
const ScDPItemData& rItem = *it;
if (rItem.GetType() != ScDPItemData::Value)
continue;
double fVal = rItem.GetValue();
if (bFirst)
{
fSourceMin = fSourceMax = fVal;
bFirst = false;
}
else
{
if (fVal < fSourceMin)
fSourceMin = fVal;
if ( fVal > fSourceMax )
fSourceMax = fVal;
}
}
// For the start/end values, use the same date rounding as in
// ScDPNumGroupDimension::GetNumEntries (but not for the list of
// available years).
if (rDateInfo.mbAutoStart)
rDateInfo.mfStart = rtl::math::approxFloor(fSourceMin);
if (rDateInfo.mbAutoEnd)
rDateInfo.mfEnd = rtl::math::approxFloor(fSourceMax) + 1;
//! if not automatic, limit fSourceMin/fSourceMax for list of year values?
long nStart = 0, nEnd = 0; // end is inclusive
switch (nDatePart)
{
case sheet::DataPilotFieldGroupBy::YEARS:
nStart = ScDPUtil::getDatePartValue(
fSourceMin, rDateInfo, sheet::DataPilotFieldGroupBy::YEARS, pFormatter);
nEnd = ScDPUtil::getDatePartValue(fSourceMax, rDateInfo, sheet::DataPilotFieldGroupBy::YEARS, pFormatter);
break;
case sheet::DataPilotFieldGroupBy::QUARTERS: nStart = 1; nEnd = 4; break;
case sheet::DataPilotFieldGroupBy::MONTHS: nStart = 1; nEnd = 12; break;
case sheet::DataPilotFieldGroupBy::DAYS: nStart = 1; nEnd = 366; break;
case sheet::DataPilotFieldGroupBy::HOURS: nStart = 0; nEnd = 23; break;
case sheet::DataPilotFieldGroupBy::MINUTES: nStart = 0; nEnd = 59; break;
case sheet::DataPilotFieldGroupBy::SECONDS: nStart = 0; nEnd = 59; break;
default:
OSL_FAIL("invalid date part");
}
// Now, populate the group items in the cache.
rCache.ResetGroupItems(nGroupDim, rDateInfo);
for (sal_Int32 nValue = nStart; nValue <= nEnd; ++nValue)
rCache.SetGroupItem(nGroupDim, ScDPItemData(nDatePart, nValue));
// add first/last entry (min/max)
rCache.SetGroupItem(nGroupDim, ScDPItemData(nDatePart, ScDPItemData::DateFirst));
rCache.SetGroupItem(nGroupDim, ScDPItemData(nDatePart, ScDPItemData::DateLast));
}
}
void ScDPSaveGroupDimension::AddToData( ScDPGroupTableData& rData ) const void ScDPSaveGroupDimension::AddToData( ScDPGroupTableData& rData ) const
{ {
long nSourceIndex = rData.GetDimensionIndex( aSourceDim ); long nSourceIndex = rData.GetDimensionIndex( aSourceDim );
...@@ -319,16 +427,51 @@ void ScDPSaveGroupDimension::AddToData( ScDPGroupTableData& rData ) const ...@@ -319,16 +427,51 @@ void ScDPSaveGroupDimension::AddToData( ScDPGroupTableData& rData ) const
{ {
// normal (manual) grouping // normal (manual) grouping
SvNumberFormatter* pFormatter = rData.GetDocument()->GetFormatTable(); for (ScDPSaveGroupItemVec::const_iterator aIter(aGroups.begin()); aIter != aGroups.end(); ++aIter)
aIter->AddToData(aDim);
for ( ScDPSaveGroupItemVec::const_iterator aIter(aGroups.begin()); aIter != aGroups.end(); aIter++ )
aIter->AddToData( aDim, pFormatter );
} }
rData.AddGroupDimension( aDim ); rData.AddGroupDimension( aDim );
} }
} }
void ScDPSaveGroupDimension::AddToCache(ScDPCache& rCache) const
{
long nDim = rCache.AppendGroupField();
SvNumberFormatter* pFormatter = rCache.GetDoc()->GetFormatTable();
if (nDatePart)
{
long nSourceDim = rCache.GetDimensionIndex(aSourceDim);
fillDateGroupDimension(rCache, aDateInfo, nSourceDim, nDim, nDatePart, pFormatter);
return;
}
rCache.ResetGroupItems(nDim, aDateInfo);
{
ScDPSaveGroupItemVec::const_iterator it = aGroups.begin(), itEnd = aGroups.end();
for (; it != itEnd; ++it)
{
const ScDPSaveGroupItem& rGI = *it;
rGI.ConvertElementsToItems(pFormatter);
rCache.SetGroupItem(nDim, ScDPItemData(rGI.GetGroupName()));
}
}
long nSourceDim = rCache.GetDimensionIndex(aSourceDim);
const ScDPCache::DataListType& rItems = rCache.GetDimMemberValues(nSourceDim);
{
ScDPCache::DataListType::const_iterator it = rItems.begin(), itEnd = rItems.end();
for (; it != itEnd; ++it)
{
const ScDPItemData& rItem = *it;
if (!IsInGroup(rItem))
// Not in any group. Add as its own group.
rCache.SetGroupItem(nDim, rItem);
}
}
}
// ============================================================================ // ============================================================================
ScDPSaveNumGroupDimension::ScDPSaveNumGroupDimension( const rtl::OUString& rName, const ScDPNumGroupInfo& rInfo ) : ScDPSaveNumGroupDimension::ScDPSaveNumGroupDimension( const rtl::OUString& rName, const ScDPNumGroupInfo& rInfo ) :
...@@ -362,6 +505,109 @@ void ScDPSaveNumGroupDimension::AddToData( ScDPGroupTableData& rData ) const ...@@ -362,6 +505,109 @@ void ScDPSaveNumGroupDimension::AddToData( ScDPGroupTableData& rData ) const
} }
} }
void ScDPSaveNumGroupDimension::AddToCache(ScDPCache& rCache) const
{
long nDim = rCache.GetDimensionIndex(aDimensionName);
if (aGroupInfo.mbEnable)
{
// Number-range grouping
// Look through the source entries for non-integer numbers, minimum
// and maximum.
// non-integer GroupInfo values count, too
aGroupInfo.mbIntegerOnly =
(aGroupInfo.mbAutoStart || isInteger(aGroupInfo.mfStart)) &&
(aGroupInfo.mbAutoEnd || isInteger(aGroupInfo.mfEnd)) &&
isInteger(aGroupInfo.mfStep);
double fSourceMin = 0.0;
double fSourceMax = 0.0;
bool bFirst = true;
const ScDPCache::DataListType& rItems = rCache.GetDimMemberValues(nDim);
ScDPCache::DataListType::const_iterator it = rItems.begin(), itEnd = rItems.end();
for (; it != itEnd; ++it)
{
const ScDPItemData& rItem = *it;
if (rItem.GetType() != ScDPItemData::Value)
continue;
double fValue = rItem.GetValue();
if (bFirst)
{
fSourceMin = fSourceMax = fValue;
bFirst = false;
continue;
}
if (fValue < fSourceMin)
fSourceMin = fValue;
if (fValue > fSourceMax)
fSourceMax = fValue;
if (aGroupInfo.mbIntegerOnly && !isInteger(fValue))
{
// If any non-integer numbers are involved, the group labels
// are shown including their upper limit.
aGroupInfo.mbIntegerOnly = false;
}
}
if (aGroupInfo.mbDateValues)
{
// special handling for dates: always integer, round down limits
aGroupInfo.mbIntegerOnly = true;
fSourceMin = rtl::math::approxFloor(fSourceMin);
fSourceMax = rtl::math::approxFloor(fSourceMax) + 1;
}
if (aGroupInfo.mbAutoStart)
aGroupInfo.mfStart = fSourceMin;
if (aGroupInfo.mbAutoEnd)
aGroupInfo.mfEnd = fSourceMax;
//! limit number of entries?
long nLoopCount = 0;
double fLoop = aGroupInfo.mfStart;
rCache.ResetGroupItems(nDim, aGroupInfo);
// Use "less than" instead of "less or equal" for the loop - don't
// create a group that consists only of the end value. Instead, the
// end value is then included in the last group (last group is bigger
// than the others). The first group has to be created nonetheless.
// GetNumGroupForValue has corresponding logic.
bool bFirstGroup = true;
while (bFirstGroup || (fLoop < aGroupInfo.mfEnd && !rtl::math::approxEqual(fLoop, aGroupInfo.mfEnd)))
{
ScDPItemData aItem;
aItem.SetRangeStart(fLoop);
rCache.SetGroupItem(nDim, aItem);
++nLoopCount;
fLoop = aGroupInfo.mfStart + nLoopCount * aGroupInfo.mfStep;
bFirstGroup = false;
// ScDPItemData values are compared with approxEqual
}
ScDPItemData aItem;
aItem.SetRangeFirst();
rCache.SetGroupItem(nDim, aItem);
aItem.SetRangeLast();
rCache.SetGroupItem(nDim, aItem);
}
else if (aDateInfo.mbEnable)
{
// Date grouping
SvNumberFormatter* pFormatter = rCache.GetDoc()->GetFormatTable();
fillDateGroupDimension(rCache, aDateInfo, nDim, nDim, nDatePart, pFormatter);
}
}
void ScDPSaveNumGroupDimension::SetGroupInfo( const ScDPNumGroupInfo& rNew ) void ScDPSaveNumGroupDimension::SetGroupInfo( const ScDPNumGroupInfo& rNew )
{ {
aGroupInfo = rNew; aGroupInfo = rNew;
...@@ -468,8 +714,27 @@ void ScDPDimensionSaveData::WriteToData( ScDPGroupTableData& rData ) const ...@@ -468,8 +714,27 @@ void ScDPDimensionSaveData::WriteToData( ScDPGroupTableData& rData ) const
aIt->second.AddToData( rData ); aIt->second.AddToData( rData );
} }
namespace {
class AddGroupDimToCache : std::unary_function<ScDPSaveGroupDimension, void>
{
ScDPCache& mrCache;
public:
AddGroupDimToCache(ScDPCache& rCache) : mrCache(rCache) {}
void operator() (const ScDPSaveGroupDimension& rDim)
{
rDim.AddToCache(mrCache);
}
};
}
void ScDPDimensionSaveData::WriteToCache(ScDPCache& rCache) const void ScDPDimensionSaveData::WriteToCache(ScDPCache& rCache) const
{ {
std::for_each(maGroupDims.begin(), maGroupDims.end(), AddGroupDimToCache(rCache));
ScDPSaveNumGroupDimMap::const_iterator it = maNumGroupDims.begin(), itEnd = maNumGroupDims.end();
for (; it != itEnd; ++it)
it->second.AddToCache(rCache);
} }
const ScDPSaveGroupDimension* ScDPDimensionSaveData::GetGroupDimForBase( const rtl::OUString& rBaseDimName ) const const ScDPSaveGroupDimension* ScDPDimensionSaveData::GetGroupDimForBase( const rtl::OUString& rBaseDimName ) const
......
...@@ -384,79 +384,9 @@ void ScDPDateGroupHelper::SetGroupDim(long nDim) ...@@ -384,79 +384,9 @@ void ScDPDateGroupHelper::SetGroupDim(long nDim)
mnGroupDim = nDim; mnGroupDim = nDim;
} }
void ScDPDateGroupHelper::FillColumnEntries( void ScDPDateGroupHelper::FillColumnEntries(const ScDPCache* pCache, std::vector<SCROW>& rEntries) const
SCCOL nSourceDim, ScDPCache* pCache, std::vector<SCROW>& rEntries, const std::vector<SCROW>& rOriginal) const
{ {
// auto min/max is only used for "Years" part, but the loop is always needed pCache->GetGroupDimMemberIds(mnGroupDim, rEntries);
double fSourceMin = 0.0;
double fSourceMax = 0.0;
bool bFirst = true;
size_t nOriginalCount = rOriginal.size();
for (size_t nOriginalPos=0; nOriginalPos<nOriginalCount; nOriginalPos++)
{
const ScDPItemData* pItemData = pCache->GetItemDataById( nSourceDim, rOriginal[nOriginalPos] );
if (pItemData->GetType() == ScDPItemData::Value)
{
double fSourceValue = pItemData->GetValue();
if ( bFirst )
{
fSourceMin = fSourceMax = fSourceValue;
bFirst = false;
}
else
{
if ( fSourceValue < fSourceMin )
fSourceMin = fSourceValue;
if ( fSourceValue > fSourceMax )
fSourceMax = fSourceValue;
}
}
}
// For the start/end values, use the same date rounding as in ScDPNumGroupDimension::GetNumEntries
// (but not for the list of available years):
if ( aNumInfo.mbAutoStart )
const_cast<ScDPDateGroupHelper*>(this)->aNumInfo.mfStart = rtl::math::approxFloor( fSourceMin );
if ( aNumInfo.mbAutoEnd )
const_cast<ScDPDateGroupHelper*>(this)->aNumInfo.mfEnd = rtl::math::approxFloor( fSourceMax ) + 1;
//! if not automatic, limit fSourceMin/fSourceMax for list of year values?
SvNumberFormatter* pFormatter = pCache->GetDoc()->GetFormatTable();
long nStart = 0;
long nEnd = 0; // including
switch ( nDatePart )
{
case com::sun::star::sheet::DataPilotFieldGroupBy::YEARS:
nStart = lcl_GetDatePartValue( fSourceMin, com::sun::star::sheet::DataPilotFieldGroupBy::YEARS, pFormatter, NULL );
nEnd = lcl_GetDatePartValue( fSourceMax, com::sun::star::sheet::DataPilotFieldGroupBy::YEARS, pFormatter, NULL );
break;
case com::sun::star::sheet::DataPilotFieldGroupBy::QUARTERS: nStart = 1; nEnd = 4; break;
case com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS: nStart = 1; nEnd = 12; break;
case com::sun::star::sheet::DataPilotFieldGroupBy::DAYS: nStart = 1; nEnd = 366; break;
case com::sun::star::sheet::DataPilotFieldGroupBy::HOURS: nStart = 0; nEnd = 23; break;
case com::sun::star::sheet::DataPilotFieldGroupBy::MINUTES: nStart = 0; nEnd = 59; break;
case com::sun::star::sheet::DataPilotFieldGroupBy::SECONDS: nStart = 0; nEnd = 59; break;
default:
OSL_FAIL("invalid date part");
}
pCache->ResetGroupItems(mnGroupDim, aNumInfo);
for ( sal_Int32 nValue = nStart; nValue <= nEnd; nValue++ )
{
SCROW nId = pCache->SetGroupItem(mnGroupDim, ScDPItemData(nDatePart, nValue));
rEntries.push_back(nId);
}
// add first/last entry (min/max)
SCROW nId = pCache->SetGroupItem(mnGroupDim, ScDPItemData(nDatePart, ScDPItemData::DateFirst));
rEntries.push_back(nId);
nId = pCache->SetGroupItem(mnGroupDim, ScDPItemData(nDatePart, ScDPItemData::DateLast));
rEntries.push_back(nId);
} }
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
...@@ -569,33 +499,11 @@ const std::vector<SCROW>& ScDPGroupDimension::GetColumnEntries( ...@@ -569,33 +499,11 @@ const std::vector<SCROW>& ScDPGroupDimension::GetColumnEntries(
if (pDateHelper) if (pDateHelper)
{ {
pDateHelper->FillColumnEntries( pDateHelper->FillColumnEntries(rCacheTable.getCache(), maMemberEntries);
GetSourceDim(), const_cast<ScDPCache*>(rCacheTable.getCache()), maMemberEntries, rOriginal);
return maMemberEntries; return maMemberEntries;
} }
ScDPCache* pCache = const_cast<ScDPCache*>(rCacheTable.getCache()); rCacheTable.getCache()->GetGroupDimMemberIds(nGroupDim, maMemberEntries);
for (size_t i = 0, n = rOriginal.size(); i < n; ++i)
{
const ScDPItemData* pItemData = pCache->GetItemDataById(nSourceDim, rOriginal[i]);
if (!pItemData)
// This shouldn't happen. Something is terribly wrong.
continue;
if (!GetGroupForData(*pItemData))
{
// not in any group -> add as its own group
SCROW nId = pCache->SetGroupItem(nGroupDim, *pItemData);
maMemberEntries.push_back(nId);
}
}
for (size_t i = 0, n = aItems.size(); i < n; ++i)
{
SCROW nId = pCache->SetGroupItem(nGroupDim, aItems[i].GetName());
maMemberEntries.push_back(nId);
}
return maMemberEntries; return maMemberEntries;
} }
...@@ -681,7 +589,7 @@ void ScDPNumGroupDimension::MakeDateHelper( const ScDPNumGroupInfo& rInfo, long ...@@ -681,7 +589,7 @@ void ScDPNumGroupDimension::MakeDateHelper( const ScDPNumGroupInfo& rInfo, long
} }
const std::vector<SCROW>& ScDPNumGroupDimension::GetNumEntries( const std::vector<SCROW>& ScDPNumGroupDimension::GetNumEntries(
SCCOL nSourceDim, ScDPCache* pCache, const std::vector<SCROW>& rOriginal) const SCCOL nSourceDim, const ScDPCache* pCache) const
{ {
if (!maMemberEntries.empty()) if (!maMemberEntries.empty())
return maMemberEntries; return maMemberEntries;
...@@ -689,102 +597,11 @@ const std::vector<SCROW>& ScDPNumGroupDimension::GetNumEntries( ...@@ -689,102 +597,11 @@ const std::vector<SCROW>& ScDPNumGroupDimension::GetNumEntries(
if (pDateHelper) if (pDateHelper)
{ {
// Grouped by dates. // Grouped by dates.
pDateHelper->FillColumnEntries( pDateHelper->FillColumnEntries(pCache, maMemberEntries);
nSourceDim, const_cast<ScDPCache*>(pCache), maMemberEntries, rOriginal);
return maMemberEntries; return maMemberEntries;
} }
// Copy textual entries. pCache->GetGroupDimMemberIds(nSourceDim, maMemberEntries);
// Also look through the source entries for non-integer numbers, minimum and maximum.
// GetNumEntries (GetColumnEntries) must be called before accessing the groups
// (this in ensured by calling ScDPLevel::GetMembersObject for all column/row/page
// dimensions before iterating over the values).
// non-integer GroupInfo values count, too
bool bHasNonInteger = ( !aGroupInfo.mbAutoStart && !IsInteger( aGroupInfo.mfStart ) ) ||
( !aGroupInfo.mbAutoEnd && !IsInteger( aGroupInfo.mfEnd ) ) ||
!IsInteger( aGroupInfo.mfStep );
aGroupInfo.mbIntegerOnly = !bHasNonInteger;
double fSourceMin = 0.0;
double fSourceMax = 0.0;
bool bFirst = true;
for (size_t i = 0, n = rOriginal.size(); i < n; ++i)
{
const ScDPItemData* pItemData = pCache->GetItemDataById(nSourceDim, rOriginal[i]);
if (pItemData->GetType() != ScDPItemData::Value)
continue;
double fSourceValue = pItemData->GetValue();
if (bFirst)
{
fSourceMin = fSourceMax = fSourceValue;
bFirst = false;
continue;
}
if (fSourceValue < fSourceMin)
fSourceMin = fSourceValue;
if (fSourceValue > fSourceMax)
fSourceMax = fSourceValue;
if (aGroupInfo.mbIntegerOnly && !IsInteger(fSourceValue))
{
// if any non-integer numbers are involved, the group labels are
// shown including their upper limit
aGroupInfo.mbIntegerOnly = false;
}
}
if (aGroupInfo.mbDateValues)
{
// special handling for dates: always integer, round down limits
aGroupInfo.mbIntegerOnly = true;
fSourceMin = rtl::math::approxFloor( fSourceMin );
fSourceMax = rtl::math::approxFloor( fSourceMax ) + 1;
}
if (aGroupInfo.mbAutoStart)
aGroupInfo.mfStart = fSourceMin;
if (aGroupInfo.mbAutoEnd)
aGroupInfo.mfEnd = fSourceMax;
//! limit number of entries?
long nLoopCount = 0;
double fLoop = aGroupInfo.mfStart;
// Num group always share the same dimension ID as the source dimension.
pCache->ResetGroupItems(nSourceDim, aGroupInfo);
// Use "less than" instead of "less or equal" for the loop - don't create a group
// that consists only of the end value. Instead, the end value is then included
// in the last group (last group is bigger than the others).
// The first group has to be created nonetheless. GetNumGroupForValue has corresponding logic.
bool bFirstGroup = true;
while (bFirstGroup || (fLoop < aGroupInfo.mfEnd && !rtl::math::approxEqual(fLoop, aGroupInfo.mfEnd)))
{
ScDPItemData aItem;
aItem.SetRangeStart(fLoop);
SCROW nId = pCache->SetGroupItem(nSourceDim, aItem);
maMemberEntries.push_back(nId);
++nLoopCount;
fLoop = aGroupInfo.mfStart + nLoopCount * aGroupInfo.mfStep;
bFirstGroup = false;
// ScDPItemData values are compared with approxEqual
}
ScDPItemData aItem;
aItem.SetRangeFirst();
SCROW nId = pCache->SetGroupItem(nSourceDim, aItem);
maMemberEntries.push_back(nId);
aItem.SetRangeLast();
nId = pCache->SetGroupItem(nSourceDim, aItem);
maMemberEntries.push_back(nId);
return maMemberEntries; return maMemberEntries;
} }
...@@ -811,8 +628,6 @@ void ScDPGroupTableData::AddGroupDimension( const ScDPGroupDimension& rGroup ) ...@@ -811,8 +628,6 @@ void ScDPGroupTableData::AddGroupDimension( const ScDPGroupDimension& rGroup )
aNewGroup.SetGroupDim( GetColumnCount() ); // new dimension will be at the end aNewGroup.SetGroupDim( GetColumnCount() ); // new dimension will be at the end
aGroups.push_back( aNewGroup ); aGroups.push_back( aNewGroup );
aGroupNames.insert(aNewGroup.GetName()); aGroupNames.insert(aNewGroup.GetName());
ScDPCache* pCache = const_cast<ScDPCache*>(GetCacheTable().getCache());
pCache->AppendGroupField();
} }
void ScDPGroupTableData::SetNumGroupDimension( long nIndex, const ScDPNumGroupDimension& rGroup ) void ScDPGroupTableData::SetNumGroupDimension( long nIndex, const ScDPNumGroupDimension& rGroup )
...@@ -872,10 +687,8 @@ const std::vector< SCROW >& ScDPGroupTableData::GetColumnEntries( long nColumn ...@@ -872,10 +687,8 @@ const std::vector< SCROW >& ScDPGroupTableData::GetColumnEntries( long nColumn
if ( IsNumGroupDimension( nColumn ) ) if ( IsNumGroupDimension( nColumn ) )
{ {
// dimension number is unchanged for numerical groups // dimension number is unchanged for numerical groups
const std::vector< SCROW >& rOriginal = pSourceData->GetColumnEntries( nColumn );
return pNumGroups[nColumn].GetNumEntries( return pNumGroups[nColumn].GetNumEntries(
static_cast<SCCOL>(nColumn), static_cast<SCCOL>(nColumn), GetCacheTable().getCache());
const_cast<ScDPCache*>(GetCacheTable().getCache()), rOriginal);
} }
return pSourceData->GetColumnEntries( nColumn ); return pSourceData->GetColumnEntries( nColumn );
......
...@@ -386,7 +386,7 @@ bool ScDPCache::InitFromDoc(ScDocument* pDoc, const ScRange& rRange) ...@@ -386,7 +386,7 @@ bool ScDPCache::InitFromDoc(ScDocument* pDoc, const ScRange& rRange)
for (size_t i = 0; i < static_cast<size_t>(mnColumnCount); ++i) for (size_t i = 0; i < static_cast<size_t>(mnColumnCount); ++i)
maFields.push_back(new Field); maFields.push_back(new Field);
maLabelNames.reserve(mnColumnCount); maLabelNames.reserve(mnColumnCount+1);
for (sal_uInt16 nCol = nStartCol; nCol <= nEndCol; ++nCol) for (sal_uInt16 nCol = nStartCol; nCol <= nEndCol; ++nCol)
{ {
...@@ -423,7 +423,7 @@ bool ScDPCache::InitFromDataBase (const Reference<sdbc::XRowSet>& xRowSet, const ...@@ -423,7 +423,7 @@ bool ScDPCache::InitFromDataBase (const Reference<sdbc::XRowSet>& xRowSet, const
// Get column titles and types. // Get column titles and types.
maLabelNames.clear(); maLabelNames.clear();
maLabelNames.reserve(mnColumnCount); maLabelNames.reserve(mnColumnCount+1);
std::vector<sal_Int32> aColTypes(mnColumnCount); std::vector<sal_Int32> aColTypes(mnColumnCount);
...@@ -713,14 +713,14 @@ const ScDPCache::GroupItems* ScDPCache::GetGroupItems(long nDim) const ...@@ -713,14 +713,14 @@ const ScDPCache::GroupItems* ScDPCache::GetGroupItems(long nDim) const
return NULL; return NULL;
} }
rtl::OUString ScDPCache::GetDimensionName( sal_uInt16 nColumn ) const rtl::OUString ScDPCache::GetDimensionName(long nDim) const
{ {
OSL_ENSURE(nColumn < maLabelNames.size()-1 , "ScDPTableDataCache::GetDimensionName"); OSL_ENSURE(nDim < maLabelNames.size()-1 , "ScDPTableDataCache::GetDimensionName");
OSL_ENSURE(maLabelNames.size() == static_cast <sal_uInt16> (mnColumnCount+1), "ScDPTableDataCache::GetDimensionName"); OSL_ENSURE(maLabelNames.size() == static_cast <sal_uInt16> (mnColumnCount+1), "ScDPTableDataCache::GetDimensionName");
if ( static_cast<size_t>(nColumn+1) < maLabelNames.size() ) if ( static_cast<size_t>(nDim+1) < maLabelNames.size() )
{ {
return maLabelNames[nColumn+1]; return maLabelNames[nDim+1];
} }
else else
return rtl::OUString(); return rtl::OUString();
...@@ -844,15 +844,6 @@ const ScDPCache::DataListType& ScDPCache::GetDimMemberValues(SCCOL nDim) const ...@@ -844,15 +844,6 @@ const ScDPCache::DataListType& ScDPCache::GetDimMemberValues(SCCOL nDim) const
return maFields[nDim].maItems; return maFields[nDim].maItems;
} }
sal_uLong ScDPCache::GetNumType(sal_uLong nFormat) const
{
SvNumberFormatter* pFormatter = mpDoc->GetFormatTable();
sal_uLong nType = NUMBERFORMAT_NUMBER;
if ( pFormatter )
nType = pFormatter->GetType( nFormat );
return nType;
}
sal_uLong ScDPCache::GetNumberFormat( long nDim ) const sal_uLong ScDPCache::GetNumberFormat( long nDim ) const
{ {
if ( nDim >= mnColumnCount ) if ( nDim >= mnColumnCount )
...@@ -895,7 +886,7 @@ SCCOL ScDPCache::GetDimensionIndex(const rtl::OUString& sName) const ...@@ -895,7 +886,7 @@ SCCOL ScDPCache::GetDimensionIndex(const rtl::OUString& sName) const
for (size_t i = 1; i < maLabelNames.size(); ++i) for (size_t i = 1; i < maLabelNames.size(); ++i)
{ {
if (maLabelNames[i].equals(sName)) if (maLabelNames[i].equals(sName))
return (SCCOL)(i-1); return static_cast<SCCOL>(i-1);
} }
return -1; return -1;
} }
...@@ -1055,10 +1046,10 @@ rtl::OUString ScDPCache::GetFormattedString(long nDim, const ScDPItemData& rItem ...@@ -1055,10 +1046,10 @@ rtl::OUString ScDPCache::GetFormattedString(long nDim, const ScDPItemData& rItem
return rItem.GetString(); return rItem.GetString();
} }
void ScDPCache::AppendGroupField() long ScDPCache::AppendGroupField()
{ {
maGroupFields.push_back(new GroupItems); maGroupFields.push_back(new GroupItems);
fprintf(stdout, "ScDPCache::AppendGroupField: added; new count = %d\n", maGroupFields.size()); return static_cast<long>(maFields.size() + maGroupFields.size() - 1);
} }
void ScDPCache::ResetGroupItems(long nDim, const ScDPNumGroupInfo& rNumInfo) void ScDPCache::ResetGroupItems(long nDim, const ScDPNumGroupInfo& rNumInfo)
...@@ -1107,6 +1098,55 @@ SCROW ScDPCache::SetGroupItem(long nDim, const ScDPItemData& rData) ...@@ -1107,6 +1098,55 @@ SCROW ScDPCache::SetGroupItem(long nDim, const ScDPItemData& rData)
return -1; return -1;
} }
const ScDPCache::DataListType* ScDPCache::GetGroupDimMemberValues(long nDim) const
{
if (nDim < 0)
return NULL;
long nSourceCount = static_cast<long>(maFields.size());
if (nDim < nSourceCount)
{
if (!maFields.at(nDim).mpGroup)
return NULL;
return &maFields[nDim].mpGroup->maItems;
}
nDim -= nSourceCount;
if (nDim < static_cast<long>(maGroupFields.size()))
return &maGroupFields.at(nDim).maItems;
return NULL;
}
void ScDPCache::GetGroupDimMemberIds(long nDim, std::vector<SCROW>& rIds) const
{
if (nDim < 0)
return;
long nSourceCount = static_cast<long>(maFields.size());
if (nDim < nSourceCount)
{
if (!maFields.at(nDim).mpGroup)
return;
size_t nOffset = maFields[nDim].maItems.size();
const DataListType& rGI = maFields[nDim].mpGroup->maItems;
for (size_t i = 0, n = rGI.size(); i < n; ++i)
rIds.push_back(static_cast<SCROW>(i + nOffset));
return;
}
nDim -= nSourceCount;
if (nDim < static_cast<long>(maGroupFields.size()))
{
const DataListType& rGI = maGroupFields.at(nDim).maItems;
for (size_t i = 0, n = rGI.size(); i < n; ++i)
rIds.push_back(static_cast<SCROW>(i));
}
}
namespace { namespace {
struct ClearGroupItems : std::unary_function<ScDPCache::Field, void> struct ClearGroupItems : std::unary_function<ScDPCache::Field, void>
......
...@@ -40,6 +40,8 @@ ...@@ -40,6 +40,8 @@
#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp> #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
#include <com/sun/star/i18n/CalendarDisplayIndex.hpp> #include <com/sun/star/i18n/CalendarDisplayIndex.hpp>
#define D_TIMEFACTOR 86400.0
using namespace com::sun::star; using namespace com::sun::star;
namespace { namespace {
...@@ -290,4 +292,76 @@ rtl::OUString ScDPUtil::getNumGroupName( ...@@ -290,4 +292,76 @@ rtl::OUString ScDPUtil::getNumGroupName(
return lcl_GetNumGroupName(fGroupStart, rInfo, cDecSep, pFormatter); return lcl_GetNumGroupName(fGroupStart, rInfo, cDecSep, pFormatter);
} }
sal_Int32 ScDPUtil::getDatePartValue(
double fValue, const ScDPNumGroupInfo& rInfo, sal_Int32 nDatePart,
SvNumberFormatter* pFormatter)
{
// Start and end are inclusive
// (End date without a time value is included, with a time value it's not)
if (fValue < rInfo.mfStart && !rtl::math::approxEqual(fValue, rInfo.mfStart))
return ScDPItemData::DateFirst;
if (fValue > rInfo.mfEnd && !rtl::math::approxEqual(fValue, rInfo.mfEnd))
return ScDPItemData::DateLast;
sal_Int32 nResult = 0;
if (nDatePart == sheet::DataPilotFieldGroupBy::HOURS ||
nDatePart == sheet::DataPilotFieldGroupBy::MINUTES ||
nDatePart == sheet::DataPilotFieldGroupBy::SECONDS)
{
// handle time
// (as in the cell functions, ScInterpreter::ScGetHour etc.: seconds are rounded)
double fTime = fValue - rtl::math::approxFloor(fValue);
long nSeconds = (long)rtl::math::approxFloor(fTime*D_TIMEFACTOR+0.5);
switch (nDatePart)
{
case sheet::DataPilotFieldGroupBy::HOURS:
nResult = nSeconds / 3600;
break;
case sheet::DataPilotFieldGroupBy::MINUTES:
nResult = ( nSeconds % 3600 ) / 60;
break;
case sheet::DataPilotFieldGroupBy::SECONDS:
nResult = nSeconds % 60;
break;
}
}
else
{
Date aDate = *(pFormatter->GetNullDate());
aDate += (long)::rtl::math::approxFloor(fValue);
switch ( nDatePart )
{
case com::sun::star::sheet::DataPilotFieldGroupBy::YEARS:
nResult = aDate.GetYear();
break;
case com::sun::star::sheet::DataPilotFieldGroupBy::QUARTERS:
nResult = 1 + (aDate.GetMonth() - 1) / 3; // 1..4
break;
case com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS:
nResult = aDate.GetMonth(); // 1..12
break;
case com::sun::star::sheet::DataPilotFieldGroupBy::DAYS:
{
Date aYearStart(1, 1, aDate.GetYear());
nResult = (aDate - aYearStart) + 1; // Jan 01 has value 1
if (nResult >= 60 && !aDate.IsLeapYear())
{
// days are counted from 1 to 366 - if not from a leap year, adjust
++nResult;
}
}
break;
default:
OSL_FAIL("invalid date part");
}
}
return nResult;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -554,8 +554,7 @@ void XclExpPCField::InsertNumDateGroupItems( const ScDPObject& rDPObj, const ScD ...@@ -554,8 +554,7 @@ void XclExpPCField::InsertNumDateGroupItems( const ScDPObject& rDPObj, const ScD
if( nDatePart != 0 ) if( nDatePart != 0 )
aTmpDim.MakeDateHelper( rNumInfo, mnFieldIdx, nDatePart ); aTmpDim.MakeDateHelper( rNumInfo, mnFieldIdx, nDatePart );
const std::vector<SCROW>& aMemberIds = aTmpDim.GetNumEntries( const std::vector<SCROW>& aMemberIds = aTmpDim.GetNumEntries(
static_cast<SCCOL>(GetBaseFieldIndex()), static_cast<SCCOL>(GetBaseFieldIndex()), aDPData.GetCacheTable().getCache());
const_cast<ScDPCache*>(aDPData.GetCacheTable().getCache()), aOrignial);
for ( size_t nIdx = 0 ; nIdx < aMemberIds.size(); nIdx++ ) for ( size_t nIdx = 0 ; nIdx < aMemberIds.size(); nIdx++ )
{ {
const ScDPItemData* pData = aDPData.GetMemberById( static_cast< long >( GetBaseFieldIndex() ) , aMemberIds[ nIdx] ); const ScDPItemData* pData = aDPData.GetMemberById( static_cast< long >( GetBaseFieldIndex() ) , aMemberIds[ nIdx] );
......
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