← All guides

Google-only functions and portability: what survives an export, and what has to be rewritten

Google Sheets has a large private function library. Some of it is famous — QUERY, ARRAYFORMULA, IMPORTRANGE — and some of it is quietly everywhere, like the operator functions ADD, MINUS and DIVIDE that Sheets writes when it converts certain imported formulas. None of it is in Excel’s documentation, and none of it is in LibreOffice’s.

The catalog behind this site holds 47 functions that Google documents and neither Microsoft nor The Document Foundation does. We executed all 47: 189 test cases, in Google Sheets by Drive import and in LibreOffice Calc on four pinned builds. In LibreOffice, 183 of the 189 cases returned #NAME? outright, and the six that did not are wrapper artefacts rather than partial support (section 2 below). In Google Sheets, 179 of the 180 assertable cases matched, nine more are deliberate probes with nothing to assert, and the single miss is a defect in Google’s own documentation rather than in its engine.

The surprise

The absence is not a version gap that a newer LibreOffice will close — it is total, and it was measured rather than assumed. Each of these functions was written into a workbook under every spelling LibreOffice could plausibly accept, on all four builds, before any verdict was published. For the Google service-bound set that meant nine spellings × four builds = 36 combinations, every one of them #NAME?. LibreOffice’s parser also writes the name back into the converted file lower-cased=googlefinance("NASDAQ:GOOG","price") — which is what it does with an identifier it does not recognise as a function at all.

1. What is actually missing

The Excel column throughout is Microsoft’s documented behaviour as recorded in our test corpus — for these functions there is no Microsoft page at all, so the column simply records that, and we do not run Excel. The Google Sheets column is executed output from the dated Drive-import run of 2026-09-01 unless a row says otherwise. The LibreOffice column is Calc 25.8.7.3, with the same result on 24.2.0.3, 24.8.7.2 and 25.2.0.3 everywhere except the one row that says otherwise.

FormulaExcelGoogle Sheets (executed 2026-09-01)LibreOffice Calc 25.8.7.3 (executed)
=QUERY(A1:E6,"select A where C > 700",0)not documentedJohn, Mike#NAME?
=SUM(QUERY(A1:E6,"select max(C) group by B",0))not documented2200#NAME?
=ARRAYFORMULA(A1:C1+A2:C2)not documented11, 22, 33#NAME?
=SUM(ARRAYFORMULA(LEN(A1:A3)))not documented6#NAME?
=SPLIT("Alas, poor Yorick"," ")not documentedAlas,  poor  Yorick#NAME?
=JOIN(" and-a ",{1,2,"1 2 3 4"})not documented1 and-a 2 and-a 1 2 3 4#NAME?
=FLATTEN(B1:B2, A1:A2)not documented2, 4, 1, 3#NAME?
=SORTN(A2:C6)not documentedAlice, 100, 90#NAME?
=COUNTUNIQUE(1,1,2,3,5,8,13)not documented6#NAME?
=ISBETWEEN(7.9, 1.2, 12.45)not documentedTRUE#NAME?
=ISEMAIL("noreply@google.com")not documentedTRUE#NAME?
=ISURL("mailto:someone@example.com")not documentedTRUE#NAME?
=TEXT(EPOCHTODATE(1655906710,1),"yyyy-mm-dd hh:mm:ss")not documented2022-06-22 14:05:10#NAME?
=ROUND(MARGINOFERROR(A1:A4,0.95),6)not documented3.528308#NAME?
=ROUND(AVERAGE.WEIGHTED(2,10,4,15),10)not documented3.2#NAME?
=ARRAY_CONSTRAIN(A1:C10, 2, 3)not documented1, 2, 3 / 4, 5, 6#NAME?
=ARRAY_CONSTRAIN(SORT(A1:C10,1,FALSE),2,3)not documented28, 29, 30 / 25, 26, 27#VALUE! on 24.8.7.2, 25.2.0.3, 25.8.7.3; #NAME? on 24.2.0.3

That last row is the only place in the whole 189 where the four builds disagree, and it is a useful illustration of how misleading an error code can be. In 24.2 the inner SORT is also unrecognised, so the whole expression is #NAME?. From 24.8 onward SORT resolves and produces an array, which the still-unrecognised ARRAY_CONSTRAIN then turns into #VALUE!. Nothing about ARRAY_CONSTRAIN changed between the builds; the error code moved because its neighbour got better.

The absence evidence is recorded per function in the test corpus, in one sentence: probed on all four pinned builds in five storage spellings — plain, _xlfn., COM.MICROSOFT., ORG.OPENOFFICE. and _xlfn.ORG.OPENOFFICE. — and #NAME? under every one of them. That matters because a #NAME? under the wrong spelling proves nothing at all; our guide to storage tokens is about the eight functions where exactly that mistake would have published a false verdict.

2. The six cases that are not #NAME?, and why they are not support

Five of the 189 cases wrap the Google function in ISNUMBER or ISTEXT, because the property under test is the result’s type rather than its value. Those wrappers do not propagate an error — ISNUMBER(#NAME?) is simply FALSE:

FormulaGoogle Sheets (executed 2026-09-01)LibreOffice Calc 25.8.7.3 (executed)What the LibreOffice cell means
=ISNUMBER(TO_PERCENT(0.5))TRUEFALSEwrapper over an unrecognised name
=ISTEXT(TO_TEXT(24))TRUEFALSEwrapper over an unrecognised name
=ISNUMBER(TO_DOLLARS(5))TRUEFALSEwrapper over an unrecognised name
=ISTEXT(TO_PURE_NUMBER("abc"))TRUEFALSEwrapper over an unrecognised name
=ISTEXT(DOLLAR(5))TRUETRUEa control — DOLLAR is a LibreOffice function

We flag this rather than quietly counting the FALSEs, because it is exactly the shape of mistake that produces confident wrong compatibility data. A cell that says FALSE looks like an answer. It is the absence of one.

The TO_* group carries a second caveat of its own that no execution can lift. Google describes these as formatting functions — TO_PERCENT’s page says the operation is “equivalent to clicking Format Number Percent from the menu bar” — so what changes is the cell’s number format, not the number. Our harness reads the computed value back out of a recalculated .xlsx, which means the formatting half of the documented behaviour is invisible to it and is asserted nowhere in this corpus.

3. The operator functions: absent, and trivially replaceable

Fourteen of the 47 are function spellings of ordinary operators: ADD, MINUS, MULTIPLY, DIVIDE, POW, EQ, NE, GT, GTE, LT, LTE, UMINUS, UPLUS and UNARY_PERCENT. Every one of their 59 cases is #NAME? in LibreOffice on all four builds, and every one of them matched in Google Sheets.

They are also the easiest thing on this page to port, because Google’s own pages define them as equivalences and our corpus asserts the equivalence rather than the value. ADD’s page says it is “Equivalent to the + operator”, so the case that runs is =ADD(A2,A3)-(A2+A3), which must be exactly 0 whatever the engine computes — and in Sheets it is. Likewise =POW(2,5)-POWER(2,5) is 0, =MULTIPLY(A2,B2)-(A2*B2) is 0, and the six comparison functions are each asserted only against the operator they are documented to be equivalent to. Rewriting =ADD(a,b) as =a+b is therefore not a guess; it is what the function is documented to be.

One trap inside that group is Google’s own doing. DIVIDE’s Notes section says flatly “DIVIDE is equivalent to QUOTIENT”, which contradicts the same page’s headline definition (DIVIDE = /). They cannot both hold: our executed case =DIVIDE(7,2)-QUOTIENT(7,2) returned 0.5 in Google Sheets, not 0. If you port DIVIDE to QUOTIENT on the strength of that sentence you will silently drop every remainder in the column. Port it to /.

4. Three regex families, three flavours, three sets of names

This is the messiest corner of cross-engine portability and it is worth laying out flat, because the names collide in a way that makes a formula look portable when it is not.

NameWhose function it isGoogle Sheets (executed)LibreOffice Calc 25.8.7.3 (executed)
REGEXMATCH(text, regex)Googleworks (2026-09-01)#NAME? on all four builds
REGEXEXTRACT(text, regex)Google — and, under the same name and a different argument shape, Microsoftworks (2026-08-31)#NAME? on all four builds
REGEXREPLACE(text, regex, replacement)Google — same collisionworks (2026-08-31)#NAME? on all four builds
REGEXTEST(text, regex)Microsoft only#NAME? (2026-08-31)#NAME? on all four builds
REGEX(text, expression, [replacement], [flags|occurrence])LibreOffice only#NAME? (2026-09-01)works — =REGEX("123456ABCDEF","[:digit:]","Z","g") returns ZZZZZZABCDEF

Microsoft’s REGEXEXTRACT and REGEXREPLACE take extra arguments that Google’s same-named functions do not. Our corpus executed the Microsoft forms in Sheets and the first two arguments carried over — =REGEXEXTRACT(A2,"[A-Z][a-z]+") over DylanWilliams returned Dylan in Sheets — while the documented third and fourth arguments did not: =REGEXEXTRACT("2024-08-31","-([0-9]{2})-",2) and =REGEXREPLACE("a1b2c3","[0-9]","#",-1) both came back #N/A. That is the worst possible failure mode for a migration: the simple calls survive and look like proof that the whole family ported, and the calls with options break.

And the dialects differ. Google’s REGEXMATCH page says “Google products use RE2 for regular expressions. Google Sheets supports RE2 except Unicode character class matching”. Microsoft’s three pages each say “All regular expressions for this function… use the PCRE2 ‘flavor’ of regex”. LibreOffice’s REGEX page says its expression argument uses “ICU regular expressions”. Our patterns stay inside character classes, quantifiers and anchors, which mean the same thing in all three, precisely so that a difference we report is a difference about the function and not about dialect corners — but your patterns almost certainly do not stay inside that fence.

So: a workbook using REGEXTEST or the option arguments of REGEXEXTRACT does not open and run in LibreOffice. It has to be rewritten to REGEX, which has a different name, a different argument shape and a different flavour.

5. The service-bound set: nine functions no offline engine can have

GOOGLEFINANCE, GOOGLETRANSLATE, IMPORTDATA, IMPORTFEED, IMPORTHTML, IMPORTRANGE, IMPORTXML, SPARKLINE and AI are a category of their own, and the honest handling of them is different at each end.

In LibreOffice the verdict is ordinary and publishable. All nine were probed with nine storage spellings on all four builds — 36 combinations per function — and every one returned #NAME?, with the lower-casing tell described above confirming the parser does not know the name. “Unsupported in LibreOffice” is a real executed verdict here even though the returned value is not something any test could assert.

In Google Sheets, seven of the nine carry no verdict at all, by design. They ran, we publish what came back, and we draw no conclusion:

FormulaGoogle Sheets returned (executed 2026-09-01)Why no verdict
=GOOGLEFINANCE("NASDAQ:GOOG","price")335.41documented as “delayed by up to 20 minutes” — a quote no test can be held to
=GOOGLETRANSLATE("Hello World","en","es")Hola Mundoa service’s choice among several correct renderings
=IMPORTDATA("https://example.com/data.csv")#REF!the call is well formed; only the host is inert
=IMPORTFEED("https://example.com/feed.xml")#REF!a feed exists in order to change
=IMPORTHTML("https://example.com/page.html","table",1)#REF!a slice of somebody else’s page
=IMPORTRANGE("https://docs.google.com/…","Sheet1!A1")#REF!documented as requiring a human to click Allow Access
=IMPORTXML("https://example.com/page.html","//a/@href")#REF!a document this project does not control
=SPARKLINE(A1:A5)an empty cell“Creates a miniature chart contained within a single cell” — a picture, not a value
=AI("Generate slogan for event in 10 words or less", A2)its own formula text, returned verbatimgenerated text, gated by plan and rationed by quota

GOOGLEFINANCE and GOOGLETRANSLATE keep an ordinary executed “supported” verdict — they evaluated and returned a value of the documented kind — with the values themselves published but not asserted. The other seven are declared unverdictable and appear in the Executed, but no verdict drawn table with the reason. The SPARKLINE blank is the one to be most careful with, and our test file said so in writing before the run: a chart-in-cell has no cached scalar, so a successful evaluation may read back as an empty cell, and that blank means “this cell holds a picture” — it must never be reported as “SPARKLINE returned an empty result”. The AI cell coming back holding its own formula text is evidence that nothing evaluated it on this account, which is evidence about the account and not about the function.

What survives, what rewrites, what does not port

Survives with an exact, vendor-documented replacement. The fourteen operator functions, replaced by their operators. MARGINOFERROR, which our corpus checks against CONFIDENCE.T directly: =ROUND(MARGINOFERROR(A1:A4,0.95)-CONFIDENCE.T(1-0.95, STDEV(A1:A4), COUNT(A1:A4)),12) returned 0 in Google Sheets on 2026-09-01, and CONFIDENCE.T is executed and supported in both engines. TO_PURE_NUMBER and TO_DATE against N, and TO_DOLLARS against DOLLAR, in each case with the difference Google’s own Notes state — DOLLAR outputs text where TO_DOLLARS applies a format to a number.

Rewrites, with an equivalent that exists but is not the same function. SPLIT has no counterpart in the corpus that is documented as its equal, but TEXTSPLIT occupies the same ground and we have executed it: it works in LibreOffice 25.8.7.3 only (#NAME? on 24.2.0.3, 24.8.7.2 and 25.2.0.3, executed 2026-07-29) and is #NAME? in Google Sheets (2026-08-29), so it is a target for a Sheets→LibreOffice move and a dead end in the other direction. JOIN maps onto TEXTJOIN, which is the healthiest option on this page: executed in both engines and matching on every case, on all four LibreOffice builds. FLATTEN maps onto TOCOL, executed and working in Google Sheets and in LibreOffice 25.8.7.3, and #NAME? on the three older builds. Those three mappings are our authorship, offered as suggested shapes from the executed availability data above — no vendor documents any of them as an equivalence, and our corpus asserts none.

Does not port. QUERY is the big one: it embeds a whole separate query language (the Google Visualization API Query Language, a separate document with its own versioning) and nothing in Excel or LibreOffice parses it. ARRAYFORMULA is a close second, but for the opposite reason — it is not a function so much as an evaluation mode, and its work is done in the other engines by their own implicit array rules, which is a rewrite of the surrounding formula rather than a substitution. SORTN, ARRAY_CONSTRAIN, ISEMAIL, ISURL, ISDATE, EPOCHTODATE and COUNTUNIQUE are all expressible in other functions, but each as a small formula rather than a rename. And the nine service-bound functions do not port at all in any meaningful sense: an offline engine cannot fetch a quote, and an engine that produced “es” from a local language table would not thereby be compatible with the documented service.

One more reason to test rather than read

The single Google Sheets miss in all 189 cases is =ISDATE("1969-20-07"). Google’s own Formula/Result table publishes TRUE for it, which is only consistent with a year-day-month reading, and the page says nothing about locale. The live engine returned FALSE on 2026-09-01. Our test file predicted the shape of this in writing before the run — if the engine returns FALSE, the page is what will be wrong — and it did. That, and the DIVIDE/QUOTIENT contradiction in section 3, and EPOCHTODATE’s off-by-one epoch constant, are collected with their derivations in when the documentation is wrong.

Honest limits

The Excel column throughout says “not documented”, which is a statement about Microsoft’s function documentation and nothing more. We do not run Excel, and nothing on this page is a measurement of it.

The Google Sheets column is executed output from dated runs, because Sheets has no version number to pin: a formula-only .xlsx carrying no cached results goes to Google Drive, is recalculated by Google’s engine, and comes back as .xlsx for readback, with a deterministic =1111+2222 canary in every sheet proving the recalculation happened. Most cases here ran on 2026-09-01; the Microsoft REGEX* trio, IMAGE and DETECTLANGUAGE ran on 2026-08-31; TEXTSPLIT, TEXTJOIN and TOCOL ran on 2026-08-29. Sheets’ .xlsx export rounds floats to ten significant digits, so a full-precision comparison can differ in the readback rather than in the engine.

The LibreOffice column is executed output from Calc 25.8.7.3, and every case here returned identical results on 24.2.0.3, 24.8.7.2 and 25.2.0.3 except the ARRAY_CONSTRAIN-over-SORT row and the TEXTSPLIT/TOCOL availability noted above. Those four builds are the only ones we tested, so “absent in LibreOffice” means absent in those four and does not predict a future release.

The spelling probes — five spellings for the Google-documented set, nine for the service-bound set, on every build — are measurements recorded in the test corpus rather than published test cases with verdicts of their own.

Scope. 47 functions and 189 cases is the whole Google-only set as our catalog defines it: documented by Google, not by Microsoft, not by The Document Foundation. Functions all three vendors document, and the Excel-only set, are elsewhere on this site. Untested here: QUERY’s error behaviour (Google’s pages name no error value for it at all, so we assert none), whether a QUERY result carries a header row (neither page states it), locale-dependent parsing in ISDATE and TO_DATE, and the formatting half of every TO_* function. See our methodology for how recalculation is proven rather than assumed, and the function pages for QUERY, ARRAYFORMULA, SPLIT and REGEXMATCH for the per-engine support matrices.

Check before you migrate