sc: ignore the dynamic-array master flag when @ ends the RPN
An @-prefixed formula opts out of dynamic-array spilling, but the OOXML import still arrives with cm="1" on such cells. The cell then turned into #SPILL! because the spill check ran against the 1x1 declared range. Reject the dynamic-array master request when the RPN ends with @. The @ collapses the array at interpret time. testAtFormulaIgnoresDynamicArrayMasterFlag checks that SetDynamicArrayMaster has no effect on an @-prefixed cell. Signed-off-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> Change-Id: I33322626a32893287c8859580a719dbeb9b915b4 Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/5490 Reviewed-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.com> Tested-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.com> (cherry picked from commit 02c7d85b6a0aa6269582072642501148da2d092d) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207867 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
This commit is contained in:
committed by
Xisco Fauli
parent
5663da9fa7
commit
ee4bd7f201
@@ -6468,6 +6468,32 @@ CPPUNIT_TEST_FIXTURE(TestFormula2, testCallableWhereNumberExpected)
|
||||
m_pDoc->DeleteTab(0);
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(TestFormula2, testAtFormulaIgnoresDynamicArrayMasterFlag)
|
||||
{
|
||||
// An @-prefixed formula opts out of dynamic-array spilling.
|
||||
// SetDynamicArrayMaster ignores a request to enable the flag on
|
||||
// such a cell, so an OOXML cm="1" arriving on an @-cell does not
|
||||
// turn into a #SPILL! at interpret time.
|
||||
|
||||
sc::AutoCalcSwitch aACSwitch(*m_pDoc, true);
|
||||
m_pDoc->InsertTab(0, u"Sheet1"_ustr);
|
||||
|
||||
m_pDoc->SetValue(ScAddress(0, 0, 0), 1.0);
|
||||
m_pDoc->SetValue(ScAddress(0, 1, 0), 2.0);
|
||||
m_pDoc->SetValue(ScAddress(0, 2, 0), 3.0);
|
||||
|
||||
m_pDoc->SetFormula(ScAddress(1, 0, 0), u"=@(A1:A3+0)"_ustr,
|
||||
formula::FormulaGrammar::GRAM_NATIVE);
|
||||
ScFormulaCell* pCell = m_pDoc->GetFormulaCell(ScAddress(1, 0, 0));
|
||||
CPPUNIT_ASSERT(pCell);
|
||||
|
||||
pCell->SetDynamicArrayMaster(true);
|
||||
CPPUNIT_ASSERT(!pCell->IsDynamicArrayMaster());
|
||||
CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(ScAddress(1, 0, 0)));
|
||||
|
||||
m_pDoc->DeleteTab(0);
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(TestFormula2, testMatrixConcatRendersBooleansAsTrueFalse)
|
||||
{
|
||||
// A boolean value pulled into a string context renders as the
|
||||
|
||||
@@ -2731,6 +2731,13 @@ void ScFormulaCell::SetCompile( bool bVal )
|
||||
|
||||
void ScFormulaCell::SetDynamicArrayMaster(bool bDynamic)
|
||||
{
|
||||
// A formula with @ on top of its RPN opts out of dynamic-array
|
||||
// spilling: the operator collapses any array operand to a single
|
||||
// value, so there is nothing to spill. XLSX still emits the cm="1"
|
||||
// marker on such cells, so reject the request rather than letting
|
||||
// the spill check fire against a 1x1 declared matrix.
|
||||
if (bDynamic && pCode && rpnTopIsImplicitIntersection(*pCode))
|
||||
return;
|
||||
mbDynamicArrayMaster = bDynamic;
|
||||
// A plain single-cell formula that opts into the dynamic-array flag
|
||||
// becomes a 1x1 matrix master so the first interpret can expand it
|
||||
|
||||
Reference in New Issue
Block a user