sc/qa/unit/data/xlsx/PivotTable_CachedDefinitionAndDataInSync.xlsx
|binary
sc/qa/unit/data/xlsx/PivotTable_CachedDefinitionAndDataNotInSync_SheetColumnsRemoved_WithCacheData.xlsx
|binary
sc/qa/unit/data/xlsx/PivotTable_CachedDefinitionAndDataNotInSync_SheetColumnsRemoved_WithoutCacheData.xlsx
|binary
sc/qa/unit/pivottable_filters_test.cxx
| 63 ++++++++++
sc/source/filter/oox/pivottablebuffer.cxx
| 18 ++
5 files changed, 78 insertions(+), 3 deletions(-)
New commits:
commit 9af4b5254cbe6a6770ebe78ba14074266b05471e
Author: Tomaž Vajngerl <[email protected]>
AuthorDate: Sat Feb 10 00:38:35 2024 +0900
Commit: Tomaž Vajngerl <[email protected]>
CommitDate: Sat Feb 10 01:11:44 2024 +0100
sc: pivot table not correct when data and PT cache is not in sync
It can happen that the pivot table is not updated and the sheet
data is changed so much that it doesn't match the pivot table
cached definitions. This is a perfectly valid scenario and
nothing should be wrong (the pivot table can just be updated
once loaded).
At XLSX import we should always check the cached definitions,
because the pivot table description is made using the cached data,
not the actual data.
The issue can occur when looking up the name of a PT field we
however didn't check the cached definition but checked the
sheet data, so because the indices changed so much (many columns
were removed in the sheet data) we can not find the actual field
name. The solution is simple - get the field name from the cached
pivot table definition.
Change-Id: I3b5b33f33f3c484f0b66b97ac97200d9913edcfe
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163197
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <[email protected]>
diff --git a/sc/qa/unit/data/xlsx/PivotTable_CachedDefinitionAndDataInSync.xlsx
b/sc/qa/unit/data/xlsx/PivotTable_CachedDefinitionAndDataInSync.xlsx
new file mode 100644
index 000000000000..f425f978cb50
Binary files /dev/null and
b/sc/qa/unit/data/xlsx/PivotTable_CachedDefinitionAndDataInSync.xlsx differ
diff --git
a/sc/qa/unit/data/xlsx/PivotTable_CachedDefinitionAndDataNotInSync_SheetColumnsRemoved_WithCacheData.xlsx
b/sc/qa/unit/data/xlsx/PivotTable_CachedDefinitionAndDataNotInSync_SheetColumnsRemoved_WithCacheData.xlsx
new file mode 100644
index 000000000000..0cb21cd3259c
Binary files /dev/null and
b/sc/qa/unit/data/xlsx/PivotTable_CachedDefinitionAndDataNotInSync_SheetColumnsRemoved_WithCacheData.xlsx
differ
diff --git
a/sc/qa/unit/data/xlsx/PivotTable_CachedDefinitionAndDataNotInSync_SheetColumnsRemoved_WithoutCacheData.xlsx
b/sc/qa/unit/data/xlsx/PivotTable_CachedDefinitionAndDataNotInSync_SheetColumnsRemoved_WithoutCacheData.xlsx
new file mode 100644
index 000000000000..91297320b985
Binary files /dev/null and
b/sc/qa/unit/data/xlsx/PivotTable_CachedDefinitionAndDataNotInSync_SheetColumnsRemoved_WithoutCacheData.xlsx
differ
diff --git a/sc/qa/unit/pivottable_filters_test.cxx
b/sc/qa/unit/pivottable_filters_test.cxx
index 8d6b1ad5d39e..31fb49351c8c 100644
--- a/sc/qa/unit/pivottable_filters_test.cxx
+++ b/sc/qa/unit/pivottable_filters_test.cxx
@@ -2647,6 +2647,69 @@ CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest,
testPivotTableCompactLayoutXLSX)
testThis(*getScDoc());
}
+CPPUNIT_TEST_FIXTURE(ScPivotTableFiltersTest,
+
testPivotTableXLSX_OutOfSyncPivotTableCachedDefinitionImport)
+{
+ // This tests that a out-of-sync sheet data and pivot table cached
definitions
+ // still get imported correctly as expected.
+
+ // It is perfectly valid that the sheet data and pivot table are
out-of-sync,
+ // but even if the sheet data is heavily modified, the pivot table should
still
+ // be imported.
+
+ // The test document has columns named A-K where only A and K are used in
the
+ // pivot table. The columns B-J were removed in the sheet data, but the
pivot table
+ // was not updated, so the cached data still has those and the pivot table
+ // description still relies on those columns to be present.
+
+ auto testThis = [](ScDocument& rDocument) {
+ ScDPCollection* pDPs = rDocument.GetDPCollection();
+ CPPUNIT_ASSERT_MESSAGE("Failed to get a live ScDPCollection
instance.", pDPs);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be exactly one pivot table
instance.", size_t(1),
+ pDPs->GetCount());
+
+ const ScDPObject* pDPObj = &(*pDPs)[0];
+ CPPUNIT_ASSERT(pDPObj);
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ CPPUNIT_ASSERT(pSaveData);
+
+ // Do we have a dim named "A"
+ ScDPSaveDimension* pSaveDimA =
pSaveData->GetExistingDimensionByName(u"A");
+ CPPUNIT_ASSERT(pSaveDimA);
+
+ // Do we have a dim named "K"
+ ScDPSaveDimension* pSaveDimK =
pSaveData->GetExistingDimensionByName(u"K");
+ CPPUNIT_ASSERT(pSaveDimK);
+
+ // Check the headers
+ CPPUNIT_ASSERT_EQUAL(OUString("K"), rDocument.GetString(ScAddress(0,
2, 0))); // A3
+ CPPUNIT_ASSERT_EQUAL(OUString("Sum of A"),
rDocument.GetString(ScAddress(1, 2, 0))); //B3
+
+ // Check the values
+ CPPUNIT_ASSERT_EQUAL(OUString("1"), rDocument.GetString(ScAddress(0,
3, 0))); //A4
+ CPPUNIT_ASSERT_EQUAL(OUString("2"), rDocument.GetString(ScAddress(0,
4, 0))); //A5
+ CPPUNIT_ASSERT_EQUAL(OUString("5"), rDocument.GetString(ScAddress(1,
3, 0))); //B4
+ CPPUNIT_ASSERT_EQUAL(OUString("5"), rDocument.GetString(ScAddress(1,
4, 0))); //B5
+ };
+
+ // test document with sheet data and pivot table in sync
+ createScDoc("xlsx/PivotTable_CachedDefinitionAndDataInSync.xlsx");
+ testThis(*getScDoc());
+
+ // test document with sheet data and pivot table in out-of-sync - B-J
columns removed,
+ // but the pivot table cache still hass all the data
+ createScDoc(
+
"xlsx/PivotTable_CachedDefinitionAndDataNotInSync_SheetColumnsRemoved_WithCacheData.xlsx");
+ testThis(*getScDoc());
+
+ // test document with sheet data and pivot table in out-of-sync - B-J
columns removed,
+ // but the pivot table cache is not saved, only the cached definitions are
available
+ createScDoc("xlsx/"
+
"PivotTable_CachedDefinitionAndDataNotInSync_SheetColumnsRemoved_WithoutCacheData."
+ "xlsx");
+ testThis(*getScDoc());
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/oox/pivottablebuffer.cxx
b/sc/source/filter/oox/pivottablebuffer.cxx
index 252b4773ccf2..f434780d2756 100644
--- a/sc/source/filter/oox/pivottablebuffer.cxx
+++ b/sc/source/filter/oox/pivottablebuffer.cxx
@@ -396,13 +396,18 @@ void PivotTableField::finalizeImport( const Reference<
XDataPilotDescriptor >& r
// try to get the source field and its name from passed DataPilot
descriptor
Reference< XIndexAccess > xDPFieldsIA( rxDPDesc->getDataPilotFields(),
UNO_SET_THROW );
xDPField.set( xDPFieldsIA->getByIndex( nDatabaseIdx ), UNO_QUERY_THROW
);
- Reference< XNamed > xDPFieldName( xDPField, UNO_QUERY_THROW );
- maDPFieldName = xDPFieldName->getName();
- OSL_ENSURE( !maDPFieldName.isEmpty(), "PivotTableField::finalizeImport
- no field name in source data found" );
+ }
+ catch( Exception& )
+ {
+ }
+ try
+ {
// try to convert grouping settings
if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField(
mnFieldIndex ) )
{
+ maDPFieldName = pCacheField->getName();
+
// numeric grouping is done inplace, no nested group fields will
appear
if( pCacheField->hasNumericGrouping() )
{
@@ -428,6 +433,13 @@ void PivotTableField::finalizeImport( const Reference<
XDataPilotDescriptor >& r
mrPivotTable.finalizeParentGroupingImport( xDPField,
*pCacheField, aItemNames );
}
}
+ else
+ {
+ // No choice - check the sheet for field name
+ Reference< XNamed > xDPFieldName( xDPField, UNO_QUERY_THROW );
+ maDPFieldName = xDPFieldName->getName();
+ OSL_ENSURE( !maDPFieldName.isEmpty(),
"PivotTableField::finalizeImport - no field name in source data found" );
+ }
}
catch( Exception& )
{