tdf#151000: Add support for CHOOSECOLS function
Change-Id: Id183f79a148080adebe652f63e29716910c638b2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180992 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
This commit is contained in:
parent
b0a4afc58e
commit
d595e1aa41
@ -281,6 +281,7 @@ const std::pair<const char *, int> RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF[] =
|
||||
{ "COM.MICROSOFT.FILTER" , SC_OPCODE_FILTER },
|
||||
{ "COM.MICROSOFT.SORT" , SC_OPCODE_SORT },
|
||||
{ "COM.MICROSOFT.SORTBY" , SC_OPCODE_SORTBY },
|
||||
{ "COM.MICROSOFT.CHOOSECOLS" , SC_OPCODE_CHOOSECOLS },
|
||||
{ "COM.MICROSOFT.CHOOSEROWS" , SC_OPCODE_CHOOSEROWS },
|
||||
{ "COM.MICROSOFT.DROP" , SC_OPCODE_DROP },
|
||||
{ "COM.MICROSOFT.EXPAND" , SC_OPCODE_EXPAND },
|
||||
@ -746,6 +747,7 @@ const std::pair<const char *, int> RID_STRLIST_FUNCTION_NAMES_ENGLISH_OOXML[] =
|
||||
{ "_xlfn._xlws.FILTER" , SC_OPCODE_FILTER },
|
||||
{ "_xlfn._xlws.SORT" , SC_OPCODE_SORT },
|
||||
{ "_xlfn.SORTBY" , SC_OPCODE_SORTBY },
|
||||
{ "_xlfn.CHOOSECOLS" , SC_OPCODE_CHOOSECOLS },
|
||||
{ "_xlfn.CHOOSEROWS" , SC_OPCODE_CHOOSEROWS },
|
||||
{ "_xlfn.DROP" , SC_OPCODE_DROP },
|
||||
{ "_xlfn.EXPAND" , SC_OPCODE_EXPAND },
|
||||
@ -1214,6 +1216,7 @@ const std::pair<const char *, int> RID_STRLIST_FUNCTION_NAMES_ENGLISH_PODF[] =
|
||||
{ "FILTER" , SC_OPCODE_FILTER },
|
||||
{ "SORT" , SC_OPCODE_SORT },
|
||||
{ "SORTBY" , SC_OPCODE_SORTBY },
|
||||
{ "CHOOSECOLS" , SC_OPCODE_CHOOSECOLS },
|
||||
{ "CHOOSEROWS" , SC_OPCODE_CHOOSEROWS },
|
||||
{ "DROP" , SC_OPCODE_DROP },
|
||||
{ "EXPAND" , SC_OPCODE_EXPAND },
|
||||
@ -1682,6 +1685,7 @@ const std::pair<const char *, int> RID_STRLIST_FUNCTION_NAMES_ENGLISH_API[] =
|
||||
{ "FILTER" , SC_OPCODE_FILTER },
|
||||
{ "SORT" , SC_OPCODE_SORT },
|
||||
{ "SORTBY" , SC_OPCODE_SORTBY },
|
||||
{ "CHOOSECOLS" , SC_OPCODE_CHOOSECOLS },
|
||||
{ "CHOOSEROWS" , SC_OPCODE_CHOOSEROWS },
|
||||
{ "DROP" , SC_OPCODE_DROP },
|
||||
{ "EXPAND" , SC_OPCODE_EXPAND },
|
||||
@ -2148,6 +2152,7 @@ const std::pair<const char *, int> RID_STRLIST_FUNCTION_NAMES_ENGLISH[] =
|
||||
{ "FILTER" , SC_OPCODE_FILTER },
|
||||
{ "SORT" , SC_OPCODE_SORT },
|
||||
{ "SORTBY" , SC_OPCODE_SORTBY },
|
||||
{ "CHOOSECOLS" , SC_OPCODE_CHOOSECOLS },
|
||||
{ "CHOOSEROWS" , SC_OPCODE_CHOOSEROWS },
|
||||
{ "DROP" , SC_OPCODE_DROP },
|
||||
{ "EXPAND" , SC_OPCODE_EXPAND },
|
||||
@ -2595,6 +2600,7 @@ const std::pair<TranslateId, int> RID_STRLIST_FUNCTION_NAMES[] =
|
||||
{ NC_("RID_STRLIST_FUNCTION_NAMES", "FILTER") , SC_OPCODE_FILTER },
|
||||
{ NC_("RID_STRLIST_FUNCTION_NAMES", "SORT") , SC_OPCODE_SORT },
|
||||
{ NC_("RID_STRLIST_FUNCTION_NAMES", "SORTBY") , SC_OPCODE_SORTBY },
|
||||
{ NC_("RID_STRLIST_FUNCTION_NAMES", "CHOOSECOLS") , SC_OPCODE_CHOOSECOLS },
|
||||
{ NC_("RID_STRLIST_FUNCTION_NAMES", "CHOOSEROWS") , SC_OPCODE_CHOOSEROWS },
|
||||
{ NC_("RID_STRLIST_FUNCTION_NAMES", "DROP") , SC_OPCODE_DROP },
|
||||
{ NC_("RID_STRLIST_FUNCTION_NAMES", "EXPAND") , SC_OPCODE_EXPAND },
|
||||
|
@ -1279,6 +1279,7 @@ bool FormulaCompiler::IsMatrixFunction( OpCode eOpCode )
|
||||
case ocSort :
|
||||
case ocSortBy :
|
||||
case ocRandArray :
|
||||
case ocChooseCols :
|
||||
case ocChooseRows :
|
||||
case ocDrop :
|
||||
case ocExpand :
|
||||
|
@ -517,16 +517,17 @@
|
||||
#define SC_OPCODE_SORTBY 502
|
||||
#define SC_OPCODE_MAT_SEQUENCE 503
|
||||
#define SC_OPCODE_RANDARRAY 504
|
||||
#define SC_OPCODE_CHOOSEROWS 505
|
||||
#define SC_OPCODE_DROP 506
|
||||
#define SC_OPCODE_EXPAND 507
|
||||
#define SC_OPCODE_TAKE 508
|
||||
#define SC_OPCODE_TOCOL 509
|
||||
#define SC_OPCODE_TOROW 510
|
||||
#define SC_OPCODE_UNIQUE 511
|
||||
#define SC_OPCODE_WRAPCOLS 512
|
||||
#define SC_OPCODE_WRAPROWS 513
|
||||
#define SC_OPCODE_STOP_2_PAR 514 /* last function with two or more parameters' OpCode + 1 */
|
||||
#define SC_OPCODE_CHOOSECOLS 505
|
||||
#define SC_OPCODE_CHOOSEROWS 506
|
||||
#define SC_OPCODE_DROP 507
|
||||
#define SC_OPCODE_EXPAND 508
|
||||
#define SC_OPCODE_TAKE 509
|
||||
#define SC_OPCODE_TOCOL 510
|
||||
#define SC_OPCODE_TOROW 511
|
||||
#define SC_OPCODE_UNIQUE 512
|
||||
#define SC_OPCODE_WRAPCOLS 513
|
||||
#define SC_OPCODE_WRAPROWS 514
|
||||
#define SC_OPCODE_STOP_2_PAR 515 /* last function with two or more parameters' OpCode + 1 */
|
||||
|
||||
#define SC_OPCODE_STOP_FUNCTION SC_OPCODE_STOP_2_PAR /* last function's OpCode + 1 */
|
||||
#define SC_OPCODE_LAST_OPCODE_ID (SC_OPCODE_STOP_FUNCTION - 1) /* last OpCode */
|
||||
|
@ -513,6 +513,7 @@ enum OpCode : sal_uInt16
|
||||
ocSortBy = SC_OPCODE_SORTBY,
|
||||
ocMatSequence = SC_OPCODE_MAT_SEQUENCE,
|
||||
ocRandArray = SC_OPCODE_RANDARRAY,
|
||||
ocChooseCols = SC_OPCODE_CHOOSECOLS,
|
||||
ocChooseRows = SC_OPCODE_CHOOSEROWS,
|
||||
ocDrop = SC_OPCODE_DROP,
|
||||
ocExpand = SC_OPCODE_EXPAND,
|
||||
@ -1006,6 +1007,7 @@ inline std::string OpCodeEnumToString(OpCode eCode)
|
||||
case ocFilter: return "Filter";
|
||||
case ocSort: return "Sort";
|
||||
case ocSortBy: return "SortBy";
|
||||
case ocChooseCols: return "ChooseCols";
|
||||
case ocChooseRows: return "ChooseRows";
|
||||
case ocDrop: return "Drop";
|
||||
case ocExpand: return "Expand";
|
||||
|
@ -55,6 +55,7 @@ properties, see ODF v1.3 part4 3.4 Host-Defined Behaviors
|
||||
https://docs.oasis-open.org/office/OpenDocument/v1.3/os/part4-formula/OpenDocument-v1.3-os-part4-formula.html#__RefHeading__1017868_715980110
|
||||
|
||||
* Array Functions
|
||||
* CHOOSECOLS
|
||||
* CHOOSEROWS
|
||||
* DROP
|
||||
* EXPAND
|
||||
|
@ -600,6 +600,7 @@ inline constexpr OUString HID_FUNC_XMATCH_MS = u"SC_HID_FUNC_XMATCH_MS"_ustr;
|
||||
inline constexpr OUString HID_FUNC_FILTER_MS = u"SC_HID_FUNC_FILTER_MS"_ustr;
|
||||
inline constexpr OUString HID_FUNC_SORT_MS = u"SC_HID_FUNC_SORT_MS"_ustr;
|
||||
inline constexpr OUString HID_FUNC_SORTBY_MS = u"SC_HID_FUNC_SORTBY_MS"_ustr;
|
||||
inline constexpr OUString HID_FUNC_CHOOSECOLS_MS = u"SC_HID_FUNC_CHOOSECOLS_MS"_ustr;
|
||||
inline constexpr OUString HID_FUNC_CHOOSEROWS_MS = u"SC_HID_FUNC_CHOOSEROWS_MS"_ustr;
|
||||
inline constexpr OUString HID_FUNC_DROP_MS = u"SC_HID_FUNC_DROP_MS"_ustr;
|
||||
inline constexpr OUString HID_FUNC_EXPAND_MS = u"SC_HID_FUNC_EXPAND_MS"_ustr;
|
||||
|
@ -4251,6 +4251,18 @@ const TranslateId SC_OPCODE_RANDARRAY_ARY[] =
|
||||
NC_("SC_OPCODE_RANDARRAY", "Return integer (TRUE) or decimal (FALSE) values.")
|
||||
};
|
||||
|
||||
// -=*# Resource for function CHOOSECOLS #*=-
|
||||
const TranslateId SC_OPCODE_CHOOSECOLS_ARY[] =
|
||||
{
|
||||
NC_("SC_OPCODE_CHOOSECOLS", "Returns the specified columns from an array."),
|
||||
NC_("SC_OPCODE_CHOOSECOLS", "Array"),
|
||||
NC_("SC_OPCODE_CHOOSECOLS", "The array containing the rows to be returned in the new array."),
|
||||
NC_("SC_OPCODE_CHOOSECOLS", "Column 1"),
|
||||
NC_("SC_OPCODE_CHOOSECOLS", "The first column number to be returned."),
|
||||
NC_("SC_OPCODE_CHOOSECOLS", "Column 2"),
|
||||
NC_("SC_OPCODE_CHOOSECOLS", "Column 2, Column 3,... The list of column numbers to be returned.")
|
||||
};
|
||||
|
||||
// -=*# Resource for function CHOOSEROWS #*=-
|
||||
const TranslateId SC_OPCODE_CHOOSEROWS_ARY[] =
|
||||
{
|
||||
|
@ -77,7 +77,7 @@ public:
|
||||
ScFunctionListObj::ScFunctionListObj()
|
||||
: UnoApiTest(u"/sc/qa/extras/testdocuments"_ustr)
|
||||
, XElementAccess(cppu::UnoType<uno::Sequence<beans::PropertyValue>>::get())
|
||||
, XIndexAccess(412)
|
||||
, XIndexAccess(413)
|
||||
, XNameAccess(u"IF"_ustr)
|
||||
, XServiceInfo(u"stardiv.StarCalc.ScFunctionListObj"_ustr,
|
||||
u"com.sun.star.sheet.FunctionDescriptions"_ustr)
|
||||
|
6485
sc/qa/unit/data/functions/spreadsheet/fods/choosecols.fods
Normal file
6485
sc/qa/unit/data/functions/spreadsheet/fods/choosecols.fods
Normal file
File diff suppressed because it is too large
Load Diff
@ -3097,6 +3097,7 @@ CPPUNIT_TEST_FIXTURE(Test, testFunctionLists)
|
||||
"ADDRESS",
|
||||
"AREAS",
|
||||
"CHOOSE",
|
||||
"CHOOSECOLS",
|
||||
"CHOOSEROWS",
|
||||
"COLUMN",
|
||||
"COLUMNS",
|
||||
|
@ -793,6 +793,7 @@ ScFunctionList::ScFunctionList( bool bEnglishFunctionNames )
|
||||
{ SC_OPCODE_SORTBY, ENTRY(SC_OPCODE_SORTBY_ARY), 0, ID_FUNCTION_GRP_TABLE, HID_FUNC_SORTBY_MS, PAIRED_VAR_ARGS + 1, { 0, 0, 1 }, 0 },
|
||||
{ SC_OPCODE_MAT_SEQUENCE, ENTRY(SC_OPCODE_MAT_SEQUENCE_ARY), 0, ID_FUNCTION_GRP_MATRIX, HID_FUNC_MSEQUENCE_MS, 4, { 0, 1, 1, 1 }, 0 },
|
||||
{ SC_OPCODE_RANDARRAY, ENTRY(SC_OPCODE_RANDARRAY_ARY), 0, ID_FUNCTION_GRP_MATH, HID_FUNC_RANDARRAY_MS, 5, { 1, 1, 1, 1, 1 }, 0 },
|
||||
{ SC_OPCODE_CHOOSECOLS, ENTRY(SC_OPCODE_CHOOSECOLS_ARY), 0, ID_FUNCTION_GRP_TABLE, HID_FUNC_CHOOSECOLS_MS, VAR_ARGS + 2, { 0, 0, 1 }, 0 },
|
||||
{ SC_OPCODE_CHOOSEROWS, ENTRY(SC_OPCODE_CHOOSEROWS_ARY), 0, ID_FUNCTION_GRP_TABLE, HID_FUNC_CHOOSEROWS_MS, VAR_ARGS + 2, { 0, 0, 1 }, 0 },
|
||||
{ SC_OPCODE_DROP, ENTRY(SC_OPCODE_DROP_ARY), 0, ID_FUNCTION_GRP_TABLE, HID_FUNC_DROP_MS, 3, { 0, 0, 1 }, 0 },
|
||||
{ SC_OPCODE_EXPAND, ENTRY(SC_OPCODE_EXPAND_ARY), 0, ID_FUNCTION_GRP_TABLE, HID_FUNC_EXPAND_MS, 4, { 0, 0, 1, 1 }, 0 },
|
||||
|
@ -724,6 +724,7 @@ private:
|
||||
void ScFilter();
|
||||
void ScSort();
|
||||
void ScSortBy();
|
||||
void ScChooseCols();
|
||||
void ScChooseRows();
|
||||
void ScDrop();
|
||||
void ScExpand();
|
||||
@ -737,6 +738,7 @@ private:
|
||||
void ScWrapRows();
|
||||
|
||||
private:
|
||||
void ScChooseColsOrRows(bool bCols);
|
||||
void ScToColOrRow(bool bCol);
|
||||
void ScWrapColsOrRows(bool bCols);
|
||||
void ScTakeOrDrop(bool bTake);
|
||||
|
@ -8960,7 +8960,17 @@ void ScInterpreter::ScTakeOrDrop(bool bTake)
|
||||
PushMatrix(pResMat);
|
||||
}
|
||||
|
||||
void ScInterpreter::ScChooseCols()
|
||||
{
|
||||
ScChooseColsOrRows(/*bCols*/ true);
|
||||
}
|
||||
|
||||
void ScInterpreter::ScChooseRows()
|
||||
{
|
||||
ScChooseColsOrRows(/*bCols*/ false);
|
||||
}
|
||||
|
||||
void ScInterpreter::ScChooseColsOrRows(bool bCols)
|
||||
{
|
||||
sal_uInt8 nParamCount = GetByte();
|
||||
|
||||
@ -8997,7 +9007,7 @@ void ScInterpreter::ScChooseRows()
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<sal_Int32> aRowsVector;
|
||||
std::vector<sal_Int32> aParamsVector;
|
||||
while (nGlobalError == FormulaError::NONE && nParamCount-- > 1)
|
||||
{
|
||||
if (IsMissing())
|
||||
@ -9021,17 +9031,18 @@ void ScInterpreter::ScChooseRows()
|
||||
{
|
||||
if (!pRefMatrix->IsStringOrEmpty(nC, nR))
|
||||
{
|
||||
sal_Int32 nRow = double_to_int32(pRefMatrix->GetDouble(col, row));
|
||||
if (nRow < 0)
|
||||
nRow = nsR + nRow + 1;
|
||||
sal_Int32 nParam = double_to_int32(pRefMatrix->GetDouble(col, row));
|
||||
sal_Int32 nMax = bCols ? nsC : nsR;
|
||||
if (nParam < 0)
|
||||
nParam = nMax + nParam + 1;
|
||||
|
||||
if (nRow <= 0 || o3tl::make_unsigned(nRow) > nsR)
|
||||
if (nParam <= 0 || nParam > nMax)
|
||||
{
|
||||
PushIllegalParameter();
|
||||
return;
|
||||
}
|
||||
else
|
||||
aRowsVector.push_back(nRow);
|
||||
aParamsVector.push_back(nParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -9048,18 +9059,23 @@ void ScInterpreter::ScChooseRows()
|
||||
return;
|
||||
}
|
||||
|
||||
ScMatrixRef pResMat = GetNewMat(nsC, aRowsVector.size(), /*bEmpty*/true);
|
||||
SCSIZE nColumns = bCols ? aParamsVector.size() : nsC;
|
||||
SCSIZE nRows = bCols ? nsR : aParamsVector.size();
|
||||
ScMatrixRef pResMat = GetNewMat(nColumns, nRows, /*bEmpty*/true);
|
||||
if (!pResMat)
|
||||
{
|
||||
PushIllegalArgument();
|
||||
return;
|
||||
}
|
||||
|
||||
for (SCSIZE col = 0; col < nsC; ++col)
|
||||
for (SCSIZE col = 0; col < nColumns; ++col)
|
||||
{
|
||||
for(SCSIZE row = 0; row < aRowsVector.size(); ++row)
|
||||
for(SCSIZE row = 0; row < nRows; ++row)
|
||||
{
|
||||
lcl_FillCell(pMatSource, pResMat, col, aRowsVector[row] - 1, col, row);
|
||||
if (bCols)
|
||||
lcl_FillCell(pMatSource, pResMat, aParamsVector[col] - 1, row, col, row);
|
||||
else
|
||||
lcl_FillCell(pMatSource, pResMat, col, aParamsVector[row] - 1, col, row);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4129,6 +4129,7 @@ StackVar ScInterpreter::Interpret()
|
||||
case ocIfError : ScIfError( false ); break;
|
||||
case ocIfNA : ScIfError( true ); break;
|
||||
case ocChoose : ScChooseJump(); break;
|
||||
case ocChooseCols : ScChooseCols(); break;
|
||||
case ocChooseRows : ScChooseRows(); break;
|
||||
case ocAdd : ScAdd(); break;
|
||||
case ocSub : ScSub(); break;
|
||||
|
@ -57,6 +57,7 @@ const ScParameterClassification::RawData ScParameterClassification::pRawData[] =
|
||||
{ ocIfError, {{ Array, Reference }, 0, Value }},
|
||||
{ ocIfNA, {{ Array, Reference }, 0, Value }},
|
||||
{ ocChoose, {{ Array, Reference }, 1, Value }},
|
||||
{ ocChooseCols, {{ ReferenceOrRefArray, ReferenceOrRefArray, ReferenceOrRefArray, }, 2, ForceArrayReturn }},
|
||||
{ ocChooseRows, {{ ReferenceOrRefArray, ReferenceOrRefArray, ReferenceOrRefArray, }, 2, ForceArrayReturn }},
|
||||
{ ocLet, {{ Value, ReferenceOrRefArray, ReferenceOrRefArray, }, 2, ForceArrayReturn } },
|
||||
// Other specials.
|
||||
|
@ -1591,6 +1591,7 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
|
||||
case ocAveDev:
|
||||
case ocMatSequence:
|
||||
case ocRandArray:
|
||||
case ocChooseCols:
|
||||
case ocChooseRows:
|
||||
case ocDrop:
|
||||
case ocExpand:
|
||||
|
@ -619,6 +619,7 @@ const XclFunctionInfo saFuncTable_2021[] =
|
||||
*/
|
||||
const XclFunctionInfo saFuncTable_2024[] =
|
||||
{
|
||||
EXC_FUNCENTRY_V_VR( ocChooseCols, 2, MX, 0, "CHOOSECOLS" ),
|
||||
EXC_FUNCENTRY_V_VR( ocChooseRows, 2, MX, 0, "CHOOSEROWS" ),
|
||||
EXC_FUNCENTRY_V_VR( ocDrop, 1, 3, 0, "DROP" ),
|
||||
EXC_FUNCENTRY_V_VR( ocExpand, 2, 4, 0, "EXPAND" ),
|
||||
|
@ -894,6 +894,7 @@ const FunctionData saFuncTable2021[] =
|
||||
/* FIXME: BIFF?? function identifiers available? Where to obtain? */
|
||||
const FunctionData saFuncTable2024[] =
|
||||
{
|
||||
{ "COM.MICROSOFT.CHOOSECOLS", "CHOOSECOLS", NOID, NOID, 2, MX, A, { VO }, FuncFlags::MACROCALL_NEW },
|
||||
{ "COM.MICROSOFT.CHOOSEROWS", "CHOOSEROWS", NOID, NOID, 2, MX, A, { VO }, FuncFlags::MACROCALL_NEW },
|
||||
{ "COM.MICROSOFT.DROP", "DROP", NOID, NOID, 1, 3, A, { VO }, FuncFlags::MACROCALL_NEW },
|
||||
{ "COM.MICROSOFT.EXPAND", "EXPAND", NOID, NOID, 2, 4, A, { VO }, FuncFlags::MACROCALL_NEW },
|
||||
|
Loading…
x
Reference in New Issue
Block a user