Related: tdf#122301 FREQUENCY() with ForceArrayReturn on caller

FREQUENCY() forces its direct caller into array mode, but only for
the immediate subexpression and not for further operators of the
same parameter.

This weird Excel behaviour is stated in

ECMA-376-1:2016 OOXML 18.17.7.127 FREQUENCY
"A call to FREQUENCY shall be an array formula."

somewhat unclear what it actually applies to, but it turned out
that "a call" is indeed *only* THE direct call, see
https://bugs.documentfoundation.org/show_bug.cgi?id=122301#c19

Change-Id: I145d8fe26d75d5af25b987e190bf35f2d2c03ec6
Reviewed-on: https://gerrit.libreoffice.org/66407
Reviewed-by: Eike Rathke <erack@redhat.com>
Tested-by: Jenkins
This commit is contained in:
Eike Rathke 2019-01-15 19:59:53 +01:00
parent d08425c14b
commit d0ded163d8
5 changed files with 16 additions and 3 deletions

View File

@ -2746,6 +2746,13 @@ void FormulaCompiler::ForceArrayOperator( FormulaTokenRef const & rCurr )
else
rCurr->SetInForceArray( formula::ParamClass::SuppressedReferenceOrForceArray);
}
// Propagate a ForceArrayReturn to caller if the called function
// returns one and the caller so far does not have a stronger array
// mode set.
if (pCurrentFactorToken->GetInForceArray() == ParamClass::Unknown
&& GetForceArrayParameter( rCurr.get(), SAL_MAX_UINT16) == ParamClass::ForceArrayReturn)
pCurrentFactorToken->SetInForceArray( ParamClass::ForceArrayReturn);
}
}

View File

@ -151,7 +151,7 @@ bool FormulaToken::IsInForceArray() const
{
ParamClass eParam = GetInForceArray();
return eParam == ParamClass::ForceArray || eParam == ParamClass::ReferenceOrForceArray
|| eParam == ParamClass::ReferenceOrRefArray;
|| eParam == ParamClass::ReferenceOrRefArray || eParam == ParamClass::ForceArrayReturn;
}
bool FormulaToken::operator==( const FormulaToken& rToken ) const

View File

@ -757,6 +757,7 @@ void FormulaDlg_Impl::MakeTree( StructPage* _pTree, SvTreeListEntry* pParent, co
case ParamClass::ForceArray:
case ParamClass::ReferenceOrForceArray:
case ParamClass::SuppressedReferenceOrForceArray:
case ParamClass::ForceArrayReturn:
; // nothing, only as array/matrix
// no default to get compiler warning
}

View File

@ -67,7 +67,12 @@ namespace formula
Reference in JumpMatrix context should use the result matrix
instead of the array of references. Never used as initial parameter
classification. */
SuppressedReferenceOrForceArray
SuppressedReferenceOrForceArray,
/** A function return forces the caller into array mode for this one
call, making it behave like it had ForceArray but not propagated to
any further operators in the same parameter. */
ForceArrayReturn
};
}

View File

@ -146,7 +146,7 @@ const ScParameterClassification::RawData ScParameterClassification::pRawData[] =
{ ocForecast_ETS_STA, {{ ForceArray, ForceArray, ForceArray, Value, Value, Value }, 0, Value }},
{ ocForecast_ETS_STM, {{ ForceArray, ForceArray, ForceArray, Value, Value, Value }, 0, Value }},
{ ocFormula, {{ Reference }, 0, Value }},
{ ocFrequency, {{ ReferenceOrForceArray, ReferenceOrForceArray }, 0, Value }},
{ ocFrequency, {{ ReferenceOrForceArray, ReferenceOrForceArray }, 0, ForceArrayReturn }},
{ ocGCD, {{ Reference }, 1, Value }},
{ ocGeoMean, {{ Reference }, 1, Value }},
{ ocGreater, {{ Array, Array }, 0, Value }},