- restore closing braces the line-level merges of side-by-side tests dropped
- new ChartData literals carry the palette field
- the filter-menu shortcut passes the row with the column
- #688's tab tests account for #851's All Sheets button
- Serbian margins for the ruler-margin labels
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A formula such as =A1+A2+…+A500 nests one level per operator, and the
evaluator recursed once per level, so past its depth limit (about 400
operators) the result was #CALC!. Excel allows such formulas up to its
8,192-character limit. Chains of arithmetic, comparison and & operators
are now folded in a loop.
A formula under a criteria label that names no field is evaluated for each record: its relative references move from the first record to that record, and the database labels name the record's fields, as in Excel. The calc evaluator passes the criteria reference to the database functions through Ctx::computed_criterion.
The parser stripped _xludf. like _xlfn., but the two mean opposite things:
_xludf. marks a name Excel must not treat as a built-in. Keeping it in the
call name makes the call an unknown function (#NAME?, as in Excel) and the
writer emits it unchanged, so _xludf.EOMONTH() no longer saves as an
EOMONTH() call Excel repairs away.
Excel lets a worksheet function be passed by name where a function is
expected. In GridCraft GROUPBY(A2:A9,B2:B9,SUM) and PIVOTBY gave #NAME?
(their documented form), and BYROW, BYCOL, MAP, REDUCE, SCAN and
MAKEARRAY gave #VALUE!. A name that is a worksheet function, and not a
LET/LAMBDA variable or a defined name, now works as a function there.
Reading a file, the _xleta. prefix Excel writes for these names is
removed.
XLOOKUP returned only values, so it couldn't end a range or feed
functions that need a reference: SUM(XLOOKUP("b",A1:A4,B1:B4):
XLOOKUP("d",A1:A4,B1:B4)) and SUM(B1:XLOOKUP(…)) gave #VALUE!, and so
did CELL("address",XLOOKUP(…)). A match on an empty cell gave 0, so
ISBLANK(XLOOKUP(…)) was FALSE and "x"&XLOOKUP(…) gave "x0" (#374). In
Excel XLOOKUP returns a reference to the matching row (or column) of
its result range. The evaluator now does so, finding the position with
XMATCH; arrays of lookup values, array arguments and errors still go
through the library function.
A name whose references have no $ was evaluated as if they were
absolute. In Excel such references are relative: defined from B2,
=Sheet1!A2 means "the cell to the left", and the file stores it
relative to A1 (Sheet1!XFD1, wrapping around the sheet's edge).
Name formulas with relative references are now moved by the using
cell's offset from A1, wrapping at the edges, and formulas.defineName
takes relative references as relative to the active cell, as Excel's
Name Manager does, and stores them relative to A1.
INDEX took one row and one column number, so INDEX(A1:C3,{1;3},{1,3})
gave a single value and SUM(INDEX(A1:C3,{1,2,3},2)) summed one cell.
In Excel, arrays of positions return an array of the values at each
(broadcast) position. A position that picks a whole row or column gives
#CALC! there, as arrays can't nest.