XLSX: Skip export of Data Validations with invalid formulas
bug-document: forum-mso-en4-83006.xls Change-Id: I92f0f4c374bf86ef5a8b5897777f377282352a0e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/201130 Reviewed-by: Michael Stahl <michael.stahl@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/204180 Tested-by: Jenkins
This commit is contained in:
committed by
Xisco Fauli
parent
e9f276ebd8
commit
a70e3dbfc6
@@ -265,7 +265,7 @@ public:
|
||||
bool MarkUsedExternalReferences();
|
||||
// Returns true if the cell was interpreted as part of the formula group.
|
||||
// The parameters may limit which subset of the formula group should be interpreted, if possible.
|
||||
bool Interpret(SCROW nStartOffset = -1, SCROW nEndOffset = -1);
|
||||
SC_DLLPUBLIC bool Interpret(SCROW nStartOffset = -1, SCROW nEndOffset = -1);
|
||||
bool IsIterCell() const { return bIsIterCell; }
|
||||
sal_uInt16 GetSeenInIteration() const { return nSeenInIteration; }
|
||||
|
||||
|
||||
@@ -1227,7 +1227,7 @@ CPPUNIT_TEST_FIXTURE(ScExportTest2, testValidationCopyPaste)
|
||||
|
||||
// Copy B1 from src doc to clip
|
||||
ScDocument aClipDoc(SCDOCMODE_CLIP);
|
||||
ScRange aSrcRange(1, 0, 1);
|
||||
ScRange aSrcRange(1, 0, 0);
|
||||
ScClipParam aClipParam(aSrcRange, false);
|
||||
ScMarkData aMark(pDoc->GetSheetLimits());
|
||||
aMark.SetMarkArea(aSrcRange);
|
||||
@@ -1249,7 +1249,7 @@ CPPUNIT_TEST_FIXTURE(ScExportTest2, testValidationCopyPaste)
|
||||
xmlDocUniquePtr pDocXml = parseExport(u"xl/worksheets/sheet1.xml"_ustr);
|
||||
CPPUNIT_ASSERT(pDocXml);
|
||||
assertXPathContent(pDocXml, "/x:worksheet/x:dataValidations/x:dataValidation/x:formula1",
|
||||
u"#REF!");
|
||||
u"Sheet1!$A$1:$A$3");
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(ScExportTest2, testTdf115159)
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <editeng/flditem.hxx>
|
||||
#include <document.hxx>
|
||||
#include <docsh.hxx>
|
||||
#include <formulacell.hxx>
|
||||
#include <validat.hxx>
|
||||
#include <unonames.hxx>
|
||||
#include <convuno.hxx>
|
||||
@@ -1699,7 +1700,8 @@ XclExpDV::XclExpDV( const XclExpRoot& rRoot, sal_uInt32 nScHandle ) :
|
||||
XclExpRecord( EXC_ID_DV ),
|
||||
XclExpRoot( rRoot ),
|
||||
mnFlags( 0 ),
|
||||
mnScHandle( nScHandle )
|
||||
mnScHandle( nScHandle ),
|
||||
mbValidFormula( true )
|
||||
{
|
||||
if( const ScValidationData* pValData = GetDoc().GetValidationEntry( mnScHandle ) )
|
||||
{
|
||||
@@ -1762,6 +1764,20 @@ XclExpDV::XclExpDV( const XclExpRoot& rRoot, sal_uInt32 nScHandle ) :
|
||||
// formulas
|
||||
XclExpFormulaCompiler& rFmlaComp = GetFormulaCompiler();
|
||||
|
||||
auto checkFormula = [&](std::unique_ptr<ScTokenArray> pTokArr)
|
||||
{
|
||||
ScFormulaCell aCell(GetDoc(), pValData->GetSrcPos(), std::move(pTokArr));
|
||||
aCell.SetFreeFlying(true);
|
||||
aCell.Interpret();
|
||||
sc::FormulaResultValue aResult = aCell.GetResult();
|
||||
if (aResult.meType == sc::FormulaResultValue::Error
|
||||
&& (aResult.mnError == FormulaError::NoValue
|
||||
|| aResult.mnError == FormulaError::NoRef))
|
||||
{
|
||||
mbValidFormula = false;
|
||||
}
|
||||
};
|
||||
|
||||
// first formula
|
||||
std::unique_ptr< ScTokenArray > xScTokArr = pValData->CreateFlatCopiedTokenArray( 0 );
|
||||
if (xScTokArr)
|
||||
@@ -1839,19 +1855,24 @@ XclExpDV::XclExpDV( const XclExpRoot& rRoot, sal_uInt32 nScHandle ) :
|
||||
Formula compiler supports this by offering two different functions
|
||||
CreateDataValFormula() and CreateListValFormula(). */
|
||||
mxTokArr1 = rFmlaComp.CreateFormula(EXC_FMLATYPE_LISTVAL, *xScTokArr);
|
||||
checkFormula(std::move(xScTokArr));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no list validation -> convert the formula
|
||||
mxTokArr1 = rFmlaComp.CreateFormula(EXC_FMLATYPE_DATAVAL, *xScTokArr);
|
||||
checkFormula(std::move(xScTokArr));
|
||||
}
|
||||
}
|
||||
|
||||
// second formula
|
||||
xScTokArr = pValData->CreateFlatCopiedTokenArray( 1 );
|
||||
if (xScTokArr)
|
||||
{
|
||||
mxTokArr2 = rFmlaComp.CreateFormula(EXC_FMLATYPE_DATAVAL, *xScTokArr);
|
||||
checkFormula(std::move(xScTokArr));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1891,6 +1912,9 @@ void XclExpDV::WriteBody( XclExpStream& rStrm )
|
||||
|
||||
void XclExpDV::SaveXml( XclExpXmlStream& rStrm )
|
||||
{
|
||||
if (!mbValidFormula)
|
||||
return;
|
||||
|
||||
sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
|
||||
rWorksheet->startElement( XML_dataValidation,
|
||||
XML_allowBlank, ToPsz( ::get_flag( mnFlags, EXC_DV_IGNOREBLANK ) ),
|
||||
@@ -1964,7 +1988,8 @@ void XclExpDV::SaveXml( XclExpXmlStream& rStrm )
|
||||
|
||||
XclExpDval::XclExpDval( const XclExpRoot& rRoot ) :
|
||||
XclExpRecord( EXC_ID_DVAL, 18 ),
|
||||
XclExpRoot( rRoot )
|
||||
XclExpRoot( rRoot ),
|
||||
mnDVCount( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -2003,12 +2028,12 @@ void XclExpDval::Save( XclExpStream& rStrm )
|
||||
|
||||
void XclExpDval::SaveXml( XclExpXmlStream& rStrm )
|
||||
{
|
||||
if( maDVList.IsEmpty() )
|
||||
if( !mnDVCount)
|
||||
return;
|
||||
|
||||
sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
|
||||
rWorksheet->startElement( XML_dataValidations,
|
||||
XML_count, OString::number(maDVList.GetSize())
|
||||
XML_count, OString::number(mnDVCount)
|
||||
// OOXTODO: XML_disablePrompts,
|
||||
// OOXTODO: XML_xWindow,
|
||||
// OOXTODO: XML_yWindow
|
||||
@@ -2053,6 +2078,8 @@ XclExpDV& XclExpDval::SearchOrCreateDv( sal_uInt32 nScHandle )
|
||||
|
||||
// create new DV record
|
||||
mxLastFoundDV = new XclExpDV( *this, nScHandle );
|
||||
if (mxLastFoundDV->ContainsValidFormula())
|
||||
mnDVCount++;
|
||||
maDVList.InsertRecord( mxLastFoundDV, nCurrPos );
|
||||
return *mxLastFoundDV;
|
||||
}
|
||||
|
||||
@@ -328,6 +328,8 @@ public:
|
||||
|
||||
virtual void SaveXml( XclExpXmlStream& rStrm ) override;
|
||||
|
||||
bool ContainsValidFormula() const { return mbValidFormula; }
|
||||
|
||||
private:
|
||||
/** Writes the body of the DV record. */
|
||||
virtual void WriteBody( XclExpStream& rStrm ) override;
|
||||
@@ -347,6 +349,7 @@ private:
|
||||
OUString msFormula2; /// OOXML Formula for second condition.
|
||||
sal_uInt32 mnFlags; /// Miscellaneous flags.
|
||||
sal_uInt32 mnScHandle; /// The core handle for quick list search.
|
||||
bool mbValidFormula; /// Formula valid for export
|
||||
};
|
||||
|
||||
/** This class contains the DV record list following the DVAL record. */
|
||||
@@ -376,6 +379,7 @@ private:
|
||||
|
||||
XclExpDVList maDVList; /// List of DV records
|
||||
XclExpDVRef mxLastFoundDV; /// For search optimization.
|
||||
sal_uInt16 mnDVCount; /// Count of Valid DV
|
||||
};
|
||||
|
||||
// Web Queries ================================================================
|
||||
|
||||
Reference in New Issue
Block a user