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 12c69942fb80fcd4cd4a5a4ca4c76f1e050ca20c
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Sat Feb 10 00:38:35 2024 +0900
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Mon Feb 12 17:09:55 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 <qui...@gmail.com>
    (cherry picked from commit 9af4b5254cbe6a6770ebe78ba14074266b05471e)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163178
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

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& )
     {

Reply via email to