How we verify spreadsheet compatibility
Every Excel-for-the-web, Google Sheets and LibreOffice verdict on this site comes from actually executing the formula in a real engine and checking what came back — not from reading documentation. Desktop Microsoft Excel is the one engine we do not execute: its column is Microsoft’s documented behavior, and it is the yardstick the executed engines are measured against. Excel for the web is a separate implementation of the calculation engine, so running it tells you about the web app and not about the desktop one. This page explains the machinery, what “verified” means here, and the limits of the approach.
The execution harness
For each function we author test cases: a formula, any setup cells it needs, and the result Excel documents or produces for that input. The harness writes each case into a real .xlsx workbook with openpyxl, then runs headless LibreOffice Calc over it (soffice --convert-to xlsx), which forces a full recalculation. We reload the output and compare every result against the expected value.
The same workbooks are run through Google Sheets: uploaded to Google Drive with import-conversion on, opened as a Sheet (which recalculates every formula), then exported back to .xlsx and read with the same reader. That run is dated, not versioned — Sheets is a rolling service with no release to pin — so every Sheets result on this site is labelled with the date of the run that actually executed it (“executed <date> via Drive import”, most recently 2026-09-01) rather than given a version number. A later run that re-executes part of the corpus re-dates only the functions it covered; the rest keep the date they were executed on.
Two guards make the results trustworthy:
- Recalculation canaries. Every generated workbook contains sentinel formulas (deterministic arithmetic plus a volatile function) whose values prove the engine really recalculated rather than echoing stored results. A run that fails its canary is discarded, never published.
- The OOXML
_xlfn.storage prefix. Functions added to Excel after 2007 are not stored in.xlsxfiles under their display names — Excel silently writes_xlfn.XLOOKUP(...)and strips the prefix for display. Libraries that write raw XML don’t do this for you: write=XLOOKUP(...)verbatim with openpyxl and every engine, including ones that fully support XLOOKUP, shows#NAME?. The harness translates display formulas to correct storage form before writing, so a#NAME?in our results means the engine genuinely lacks the function — not a file-format artifact. (If you’ve ever generated a spreadsheet from Python and hit an inexplicable#NAME?on a modern function, this prefix is almost certainly why.)
Version matrix
The same corpus runs against multiple LibreOffice releases — currently 24.2.0.3, 24.8.7.2, 25.2.0.3, 25.8.7.3 — which is how function pages can state a precise “supported since” release rather than a guess. Current corpus: 586 functions live-tested across 2348 executed cases per release.
Google Sheets execution caveats
The Sheets run reuses the Excel-authored workbooks, and that round trip has one remaining artifact which is not Google Sheets behavior. Where a result is explained by it, we publish Inconclusive instead of a verdict — never a red “unsupported” badge:
- Unmapped storage prefixes (resolved for the affected functions on 2026-08-29). Excel stores post-2007 functions as
_xlfn.NAME,_xlfn._xlws.NAMEor (for LAMBDA parameters)_xlpm.NAME. Google’s importer maps some but not all of these prefixes:_xlfn.XLOOKUP,_xlfn.MAPand_xlfn.LAMBDAevaluated fine even with the prefix, while_xlfn._xlws.FILTERand_xlfn._xlws.SORTcame back#NAME?and BYROW/BYCOL/MAKEARRAY came back#ERROR!— despite Google documenting all of them. We ran a follow-up Sheets pass on 2026-08-29 that writes the same corpus with plain, unprefixed function names, which resolved all five: BYCOL, BYROW, FILTER, MAKEARRAY and SORT now carry real executed verdicts instead of Inconclusive. The two runs are merged into a single results file, with per-function provenance for which run produced which verdict recorded in that file’ssubset_runsarray. The general caveat still stands for any function or corpus we have not re-run this way: an.xlsximport can still fail to map a prefixed serialization, and a future case that hits this is reported Inconclusive rather than guessed at. - Export readback. Sheets’
.xlsxexport rounds every float to 10 significant digits (PI()comes back as 3.141592654) and writes an empty cell where a result is blank or zero-length. Where that rounding or that blank is the only disagreement with the expected value — DEGREES(1), INDIRECT to a blank cell, TRANSPOSE of a blank cell — the difference is in the export, not in the engine.
A #NAME? from Sheets on a formula with no storage prefix, or on a function Google does not document (TEXTSPLIT, TAKE, DROP, AGGREGATE…), is a real unsupported verdict and is published as one.
Coverage — and what we deliberately do not run
The catalog holds 600 functions. 586 of them (97.7%) have executed test cases in at least one engine. 16 of those are executed but carry no verdict, and 14 are not executed at all. The last two groups are not a backlog: each one is a decision that this harness cannot produce an honest verdict for that name, and the reason is published here rather than left as a blank. Every number and every row below is derived from the same results files the function pages are built from.
Executed, but no verdict drawn (16)
| Function | Engine | Why no verdict |
|---|---|---|
AI | Google Sheets | Google returned the formula’s own text: the cell came back holding the string =AI(…) rather than any generated answer. A value identical to the formula that was supposed to produce it is evidence that nothing evaluated it, not evidence about what the function does — and Google’s page gates the feature behind “an eligible Google Workspace or Google AI plan.” Treating the string as a result would publish a formula as AI’s output; treating it as a failure would blame Google for an entitlement this account does not carry. Neither is supportable, so the readback is published verbatim and no verdict is drawn. |
BYCOL | Excel for the web | Excel for the web deleted this formula instead of computing it. The uploaded workbook carries the array formula in cell A30; the downloaded package has no A30 at all, while the sheet’s arithmetic canary in Z1 came back correct — so the sheet did recalculate and the formula simply did not survive the round trip. It embeds a LAMBDA, the same construct whose storage form makes Excel for the web refuse a workbook outright. A blank left by a removed formula is not a computed result, so no verdict is drawn from it. |
BYROW | Excel for the web | Excel for the web deleted this formula instead of computing it. The uploaded workbook carries the array formula in cell A30; the downloaded package has no A30 at all, while the sheet’s arithmetic canary in Z1 came back correct — so the sheet did recalculate and the formula simply did not survive the round trip. It embeds a LAMBDA, the same construct whose storage form makes Excel for the web refuse a workbook outright. A blank left by a removed formula is not a computed result, so no verdict is drawn from it. |
DDE | LibreOffice | DDE resolves a link into another running application — LibreOffice’s own help describes the first argument as “the name of a server application”, and its worked example edits a linked Writer document to change the value. A flat .xlsx carries no such server and a headless conversion has nothing on the other end of the link, so the #N/A recorded below describes the absent server, not LibreOffice. Publishing it as a quirk would assert a defect this run never demonstrated, which is why the executed values are shown and no verdict is drawn from them — the same judgement batch G made about WEBSERVICE’s network #N/A. |
ENCODEURL | Excel for the web | Excel for the web returned #VALUE! for all four cases, including =ENCODEURL("abcXYZ123"), whose argument needs no encoding at all and has no failure mode. An argument-independent error on every case, from a name the engine clearly recognises (an unknown name returns #NAME? here, as AI does), is the web application declining to provide a function rather than computing it wrongly. Our expected values come from Microsoft’s documentation of the desktop product, so the disagreement is between two applications’ feature sets, not evidence of a defect in either. The values are published as they came back and no verdict is drawn. |
FILTERXML | Excel for the web | Excel for the web returned #VALUE! for every case — both the two that expected a parsed value and the two that expected #VALUE!. That the latter two “matched” is a coincidence of a uniform error, not a demonstration that the function works, so they cannot carry a verdict either. As with ENCODEURL, the name resolves (an unknown name is #NAME? here) and the error does not vary with the arguments, which points at a feature the web application does not ship rather than at a calculation defect. Our expected values describe the desktop product. The values are published verbatim and no verdict is drawn. |
FORECAST.ETS | Excel for the web | Excel for the web returned #N/A for every case of the FORECAST.ETS family — the existence probes, the value assertions and the cases that expected #NUM! or #VALUE! alike, all from the same 20-point timeline that FORECAST and FORECAST.LINEAR compute correctly on in this very run. A single error returned uniformly across arguments, dataset and error class is not a family of calculation defects; it is the exponential-smoothing feature being absent from this application. The name resolves (an unrecognised name is #NAME? here), and the expected values come from Microsoft’s documentation of the desktop product, so the disagreement is between what the two applications ship. The executed values are published exactly as they came back and no verdict is drawn from them. |
FORECAST.ETS.CONFINT | Excel for the web | Excel for the web returned #N/A for every case of the FORECAST.ETS family — the existence probes, the value assertions and the cases that expected #NUM! or #VALUE! alike, all from the same 20-point timeline that FORECAST and FORECAST.LINEAR compute correctly on in this very run. A single error returned uniformly across arguments, dataset and error class is not a family of calculation defects; it is the exponential-smoothing feature being absent from this application. The name resolves (an unrecognised name is #NAME? here), and the expected values come from Microsoft’s documentation of the desktop product, so the disagreement is between what the two applications ship. The executed values are published exactly as they came back and no verdict is drawn from them. |
FORECAST.ETS.SEASONALITY | Excel for the web | Excel for the web returned #N/A for every case of the FORECAST.ETS family — the existence probes, the value assertions and the cases that expected #NUM! or #VALUE! alike, all from the same 20-point timeline that FORECAST and FORECAST.LINEAR compute correctly on in this very run. A single error returned uniformly across arguments, dataset and error class is not a family of calculation defects; it is the exponential-smoothing feature being absent from this application. The name resolves (an unrecognised name is #NAME? here), and the expected values come from Microsoft’s documentation of the desktop product, so the disagreement is between what the two applications ship. The executed values are published exactly as they came back and no verdict is drawn from them. |
FORECAST.ETS.STAT | Excel for the web | Excel for the web returned #N/A for every case of the FORECAST.ETS family — the existence probes, the value assertions and the cases that expected #NUM! or #VALUE! alike, all from the same 20-point timeline that FORECAST and FORECAST.LINEAR compute correctly on in this very run. A single error returned uniformly across arguments, dataset and error class is not a family of calculation defects; it is the exponential-smoothing feature being absent from this application. The name resolves (an unrecognised name is #NAME? here), and the expected values come from Microsoft’s documentation of the desktop product, so the disagreement is between what the two applications ship. The executed values are published exactly as they came back and no verdict is drawn from them. |
IMPORTDATA | Google Sheets | Google executed the call and returned #REF!. That is not a verdict about IMPORTDATA: the URL in the corpus formula is a deliberately inert example.com address (a real one returns an unbounded array, which would spill across the per-sheet recalculation canary and mark the whole run untrusted for a reason that has nothing to do with the engine), and the workbook reached Google as an uploaded .xlsx conversion rather than as a sheet a person opened and authorised. Either of those is enough to produce this error and this run cannot tell them apart. What it cannot do either way is show what IMPORTDATA does when the fetch succeeds — and the fetch is the documented behaviour, which is why the value is published exactly as it came back and no verdict is drawn from it. |
IMPORTFEED | Google Sheets | Google executed the call and returned #REF!. That is not a verdict about IMPORTFEED: the URL in the corpus formula is a deliberately inert example.com address (a real one returns an unbounded array, which would spill across the per-sheet recalculation canary and mark the whole run untrusted for a reason that has nothing to do with the engine), and the workbook reached Google as an uploaded .xlsx conversion rather than as a sheet a person opened and authorised. Either of those is enough to produce this error and this run cannot tell them apart. What it cannot do either way is show what IMPORTFEED does when the fetch succeeds — and the fetch is the documented behaviour, which is why the value is published exactly as it came back and no verdict is drawn from it. |
IMPORTHTML | Google Sheets | Google executed the call and returned #REF!. That is not a verdict about IMPORTHTML: the URL in the corpus formula is a deliberately inert example.com address (a real one returns an unbounded array, which would spill across the per-sheet recalculation canary and mark the whole run untrusted for a reason that has nothing to do with the engine), and the workbook reached Google as an uploaded .xlsx conversion rather than as a sheet a person opened and authorised. Either of those is enough to produce this error and this run cannot tell them apart. What it cannot do either way is show what IMPORTHTML does when the fetch succeeds — and the fetch is the documented behaviour, which is why the value is published exactly as it came back and no verdict is drawn from it. |
IMPORTRANGE | Google Sheets | Google executed the call and returned #REF!, which is the documented consequence of an unauthorised link rather than a defect. Google’s own page states the gate: “Spreadsheets must be explicitly granted permission to pull data from other spreadsheets using IMPORTRANGE”, and the permission is granted by a human clicking Allow Access. Nobody clicked it — the corpus workbook was uploaded and converted, not opened and authorised — and the spreadsheet id in the formula is a placeholder naming no real document. The value is published exactly as it came back and no verdict is drawn from it. |
IMPORTXML | Google Sheets | Google executed the call and returned #REF!. That is not a verdict about IMPORTXML: the URL in the corpus formula is a deliberately inert example.com address (a real one returns an unbounded array, which would spill across the per-sheet recalculation canary and mark the whole run untrusted for a reason that has nothing to do with the engine), and the workbook reached Google as an uploaded .xlsx conversion rather than as a sheet a person opened and authorised. Either of those is enough to produce this error and this run cannot tell them apart. What it cannot do either way is show what IMPORTXML does when the fetch succeeds — and the fetch is the documented behaviour, which is why the value is published exactly as it came back and no verdict is drawn from it. |
SPARKLINE | Google Sheets | Google executed the call and the exported cell came back empty, with the reader warning that a Sparkline Group extension it does not support was present in the file. That is exactly what this function’s test file predicted before the run: SPARKLINE “Creates a miniature chart contained within a single cell”, a drawing has no cached scalar for an .xlsx export to carry, and a blank here means this cell holds a picture — not the function returned nothing. Publishing a verdict from it and publishing an empty result from it would be wrong in opposite directions, so the readback is shown as it came and no verdict is drawn. |
Not executed (14)
| Function | Why not |
|---|---|
CALL | Calls a procedure in a DLL or code resource. The first argument names external code to load and run, so no test case is authored for it in any engine. |
CUMIPMT_ADD | LibreOffice’s own .xlsx export collapses this name onto CUMIPMT, so no OOXML token reaches it — all nine candidate spellings are #NAME? on all four builds. Writing CUMIPMT would test CUMIPMT, not CUMIPMT_ADD, so the finding is recorded and the verdict declined. |
CUMPRINC_ADD | LibreOffice’s own .xlsx export collapses this name onto CUMPRINC, so no OOXML token reaches it — all nine candidate spellings are #NAME? on all four builds. Writing CUMPRINC would test CUMPRINC, not CUMPRINC_ADD, so the finding is recorded and the verdict declined. |
EFFECT_ADD | LibreOffice’s own .xlsx export collapses this name onto EFFECT, so no OOXML token reaches it — all nine candidate spellings are #NAME? on all four builds. Writing EFFECT would test EFFECT, not EFFECT_ADD, so the finding is recorded and the verdict declined. |
FORMULA | LibreOffice’s own .xlsx export collapses this name onto FORMULATEXT, so no OOXML token reaches it — all nine candidate spellings are #NAME? on all four builds. Writing FORMULATEXT would test FORMULATEXT, not FORMULA, so the finding is recorded and the verdict declined. |
GCD_EXCEL2003 | LibreOffice’s own .xlsx export collapses this name onto GCD, so no OOXML token reaches it — all nine candidate spellings are #NAME? on all four builds. Writing GCD would test GCD, not GCD_EXCEL2003, so the finding is recorded and the verdict declined. |
ISEVEN_ADD | LibreOffice’s own .xlsx export collapses this name onto ISEVEN, so no OOXML token reaches it — all nine candidate spellings are #NAME? on all four builds. Writing ISEVEN would test ISEVEN, not ISEVEN_ADD, so the finding is recorded and the verdict declined. |
ISODD_ADD | LibreOffice’s own .xlsx export collapses this name onto ISODD, so no OOXML token reaches it — all nine candidate spellings are #NAME? on all four builds. Writing ISODD would test ISODD, not ISODD_ADD, so the finding is recorded and the verdict declined. |
LCM_EXCEL2003 | LibreOffice’s own .xlsx export collapses this name onto LCM, so no OOXML token reaches it — all nine candidate spellings are #NAME? on all four builds. Writing LCM would test LCM, not LCM_EXCEL2003, so the finding is recorded and the verdict declined. |
NOMINAL_ADD | LibreOffice’s own .xlsx export collapses this name onto NOMINAL, so no OOXML token reaches it — all nine candidate spellings are #NAME? on all four builds. Writing NOMINAL would test NOMINAL, not NOMINAL_ADD, so the finding is recorded and the verdict declined. |
REGISTER.ID | Returns the register ID of a DLL procedure that has already been registered. Same external-code reason as CALL. |
SKEWP | LibreOffice’s own .xlsx export collapses this name onto SKEW.P, so no OOXML token reaches it — all nine candidate spellings are #NAME? on all four builds. Writing SKEW.P would test SKEW.P, not SKEWP, so the finding is recorded and the verdict declined. |
WEBSERVICE | Its documented behaviour IS the network round trip. LibreOffice does implement it (as _xlfn.WEBSERVICE), but the #N/A this harness sees describes the sandbox’s DNS rather than the engine, and publishing that as a quirk would assert a defect we never observed. |
WEEKNUM_EXCEL2003 | LibreOffice’s own .xlsx export collapses this name onto WEEKNUM, so no OOXML token reaches it — all nine candidate spellings are #NAME? on all four builds. Writing WEEKNUM would test WEEKNUM, not WEEKNUM_EXCEL2003, so the finding is recorded and the verdict declined. |
Per-engine coverage: Excel for the web (579 executed)
LibreOffice Calc and Google Sheets have executed every function this corpus has a test file for.
Excel for the web has not, and the shortfall is not a shortfall in Excel — it is a
limit of how we reach the web engine. We upload an .xlsx to OneDrive and let Excel for the
web recalculate it on open; for 7 functions that
upload could not be opened at all.
| Function | Why Excel for the web has no verdict |
|---|---|
ISOMITTED | Not reachable through this harness’s transport — not a statement about Excel. Excel for the web is reached by uploading an .xlsx to OneDrive and opening it, and its file-open refuses any workbook whose stored formulas carry the _xlpm./LAMBDA storage serialization (“Couldn’t Open the Workbook”, no cell-level diagnostic). Proven by bisect: the 40-function chunk carrying it was refused, the same chunk minus LAMBDA/LET/ISOMITTED opened, and those three alone were refused again. Desktop Excel implements ISOMITTED — it is Microsoft’s own function — and LibreOffice’s executed verdict for it is published below. What we cannot do is carry it into the web engine to measure, so no Excel-for-the-web verdict is drawn. The irony is the finding: Excel for the web will not open a file containing Excel’s own LAMBDA-family storage serialization. |
LAMBDA | Not reachable through this harness’s transport — not a statement about Excel. Excel for the web is reached by uploading an .xlsx to OneDrive and opening it, and its file-open refuses any workbook whose stored formulas carry the _xlpm./LAMBDA storage serialization (“Couldn’t Open the Workbook”, no cell-level diagnostic). Proven by bisect: the 40-function chunk carrying it was refused, the same chunk minus LAMBDA/LET/ISOMITTED opened, and those three alone were refused again. Desktop Excel implements LAMBDA — it is Microsoft’s own function — and LibreOffice’s executed verdict for it is published below. What we cannot do is carry it into the web engine to measure, so no Excel-for-the-web verdict is drawn. The irony is the finding: Excel for the web will not open a file containing Excel’s own LAMBDA-family storage serialization. |
LET | Not reachable through this harness’s transport — not a statement about Excel. Excel for the web is reached by uploading an .xlsx to OneDrive and opening it, and its file-open refuses any workbook whose stored formulas carry the _xlpm./LAMBDA storage serialization (“Couldn’t Open the Workbook”, no cell-level diagnostic). Proven by bisect: the 40-function chunk carrying it was refused, the same chunk minus LAMBDA/LET/ISOMITTED opened, and those three alone were refused again. Desktop Excel implements LET — it is Microsoft’s own function — and LibreOffice’s executed verdict for it is published below. What we cannot do is carry it into the web engine to measure, so no Excel-for-the-web verdict is drawn. The irony is the finding: Excel for the web will not open a file containing Excel’s own LAMBDA-family storage serialization. |
MAKEARRAY | Not reachable through this harness’s transport — not a statement about Excel. Excel for the web is reached by uploading an .xlsx to OneDrive and opening it, and its file-open refuses any workbook whose stored formulas carry the _xlpm./LAMBDA storage serialization (“Couldn’t Open the Workbook”, no cell-level diagnostic). Proven by bisect: a probe workbook containing only MAP/MAKEARRAY/REDUCE/SCAN was refused on its own. Desktop Excel implements MAKEARRAY — it is Microsoft’s own function — and LibreOffice’s executed verdict for it is published below. What we cannot do is carry it into the web engine to measure, so no Excel-for-the-web verdict is drawn. The irony is the finding: Excel for the web will not open a file containing Excel’s own LAMBDA-family storage serialization. |
MAP | Not reachable through this harness’s transport — not a statement about Excel. Excel for the web is reached by uploading an .xlsx to OneDrive and opening it, and its file-open refuses any workbook whose stored formulas carry the _xlpm./LAMBDA storage serialization (“Couldn’t Open the Workbook”, no cell-level diagnostic). Proven by bisect: a probe workbook containing only MAP/MAKEARRAY/REDUCE/SCAN was refused on its own. Desktop Excel implements MAP — it is Microsoft’s own function — and LibreOffice’s executed verdict for it is published below. What we cannot do is carry it into the web engine to measure, so no Excel-for-the-web verdict is drawn. The irony is the finding: Excel for the web will not open a file containing Excel’s own LAMBDA-family storage serialization. |
REDUCE | Not reachable through this harness’s transport — not a statement about Excel. Excel for the web is reached by uploading an .xlsx to OneDrive and opening it, and its file-open refuses any workbook whose stored formulas carry the _xlpm./LAMBDA storage serialization (“Couldn’t Open the Workbook”, no cell-level diagnostic). Proven by bisect: a probe workbook containing only MAP/MAKEARRAY/REDUCE/SCAN was refused on its own. Desktop Excel implements REDUCE — it is Microsoft’s own function — and LibreOffice’s executed verdict for it is published below. What we cannot do is carry it into the web engine to measure, so no Excel-for-the-web verdict is drawn. The irony is the finding: Excel for the web will not open a file containing Excel’s own LAMBDA-family storage serialization. |
SCAN | Not reachable through this harness’s transport — not a statement about Excel. Excel for the web is reached by uploading an .xlsx to OneDrive and opening it, and its file-open refuses any workbook whose stored formulas carry the _xlpm./LAMBDA storage serialization (“Couldn’t Open the Workbook”, no cell-level diagnostic). Proven by bisect: a probe workbook containing only MAP/MAKEARRAY/REDUCE/SCAN was refused on its own. Desktop Excel implements SCAN — it is Microsoft’s own function — and LibreOffice’s executed verdict for it is published below. What we cannot do is carry it into the web engine to measure, so no Excel-for-the-web verdict is drawn. The irony is the finding: Excel for the web will not open a file containing Excel’s own LAMBDA-family storage serialization. |
Read the table above carefully, because the obvious misreading is the opposite of the truth:
every one of these functions works in Excel. LAMBDA and LET are Microsoft’s own
headline additions to the formula language. What we are reporting is that Excel for the web refuses to
open a file whose stored formulas carry the _xlpm./LAMBDA
serialization — the serialization Excel itself invented to write those functions into
.xlsx. So the honest summary is an awkward one for the product rather than for the
function: Excel for the web will not open a workbook containing Excel’s own LAMBDA-family
storage form, and that, not any missing capability, is why these seven rows are blank.
What the verdicts mean
- Supported — every executed case matched the Excel-canonical expected result. Some functions have no result anyone can be held to: a volatile one (NOW, RAND), or one whose answer comes from a live service (GOOGLEFINANCE quotes are documented as “delayed by up to 20 minutes”; GOOGLETRANSLATE’s output is a translation service’s choice). Their cases are probes, which assert error-free execution and whatever invariant the vendor’s own documentation fixes — never an exact value. A probe-backed “Supported” therefore means this engine evaluated the call and returned a value of the documented kind, and the value itself is published without being asserted.
- Quirk found — the function exists but at least one case returned a different value or error than Excel produces; the failing case is shown on the function’s page.
- Unsupported — the engine returns
#NAME?(unrecognized function) with the storage prefix correctly applied. - Inconclusive — the run tells us nothing about the engine, so no claim is made in either direction. Two things cause it: for Google Sheets, the
.xlsxround trip described in the caveats; for either engine, a function whose documented behaviour needs something no test workbook can supply (an external data server). Those are listed under Coverage with the values the engine actually returned still on the page.
How-to recipes are verified too
Every formula on a how-to recipe page runs through the same pipeline before publishing: the exact formula shown is executed in LibreOffice 25.8.7.3 with the sample data shown, and the page displays the value it actually returned. 282 of the 282 recipes have additionally been executed in Google Sheets (2026-08-30) by the same Drive-import round-trip used for the function corpus — those pages carry a second column showing what Google actually returned, including where it disagrees with LibreOffice — 265 of them returned exactly the LibreOffice values and 17 returned something different on at least one formula. That now covers the whole recipe corpus. The recipes whose worked examples need extra worksheets — formulas that resolve a tab name out of a cell value, span a run of consecutive tabs, or exist precisely to produce an error for a wrong-syntax reference — are built one workbook per check rather than packed into a shared one, so their tab names and tab order reach Google unchanged and nothing has to be renamed or rewritten to make them fit. Where Google’s importer altered a workbook anyway, the affected check is excluded from that recipe’s Sheets verdict and the page says which check and why.
Honest limitations
- Desktop Excel is not live-executed. Its column reflects Microsoft’s official function documentation. We can’t headlessly run desktop Excel; where an executed result from any of the three engines we do run — Google Sheets, LibreOffice Calc, or Excel for the web — differs from documented Excel behavior, that is labeled a quirk of that engine, and disputed cases are re-checked by hand. (For Excel for the web that label carries the caveat in the next bullet: it is a disagreement with the desktop documentation, and we cannot say which side is wrong.)
- Excel for the web IS live-executed — and it is not desktop Excel. We upload the corpus to OneDrive, let Excel for the web recalculate it on open, and download the workbook again to read the values back. That is a real measurement, but of a different application: Microsoft ships two implementations of the calculation engine and we have run only the web one. So when an Excel-web value disagrees with the documented column, we cannot tell you which of the two explanations holds — the web engine diverging from the desktop one, or the documentation being wrong about both — and no page on this site claims to know. Seven functions (the LAMBDA family) could not be measured at all, because Excel for the web refuses to open a workbook whose stored formulas carry Excel’s own
_xlpm./LAMBDAserialization. - Google Sheets is executed but not versioned. There is nothing to pin: each verdict describes Sheets as it behaved on the date that function was executed (the most recent run was 2026-09-01). Google ships changes continuously, so an old Sheets verdict is a dated observation, not a release guarantee — unlike the LibreOffice builds, which are reproducible forever.
- Some Sheets results are inconclusive. See the Sheets execution caveats above; those cases are excluded from verdicts and quirk counts rather than guessed at.
- Coverage is partial, and the remainder is itemised. 586 of the 600 catalog functions have executed tests; the 14 that do not are listed under Coverage with the reason for each, and an untested function’s page says so explicitly rather than borrowing a verdict.
- A passing case is evidence, not proof. A function can match on our cases and still differ on inputs we haven’t authored. When you find such an edge, please report it.
Reproduce or dispute a result
The entire harness, test corpus, and raw per-version results are public in the GitHub repository. Every function page shows the exact formula, inputs, and returned value for each case, so any result can be reproduced in a few minutes — and if an engine disagrees with us on your machine, an issue with your version number is the fastest way to get it fixed.