← All guides

SORT means two different things: Excel's sort_order vs Google Sheets' is_ascending

Two spreadsheet vendors gave the third argument of SORT two different jobs, and the argument accepts the other one’s value without complaining. Excel’s third argument is a signed sort_order: 1 ascending, -1 descending. Google Sheets’ third argument is a boolean is_ascending: TRUE ascending, FALSE descending. Hand Sheets the Excel value -1 and you do not get an error — you get the list sorted the wrong way up.

We executed it. Our how-to corpus’s =SORT(A2:A4,1,-1) over A2:A4 = 20, 50, 10 returned 50, 20, 10 in LibreOffice Calc 25.8.7.3 and 10, 20, 50 in the Google Sheets run of 2026-08-30. Same formula, opposite order, no error message on either side.

The surprise

This breaks in exactly one direction, which is what makes it hard to spot. A formula that sorts ascending travels fine: Excel writes 1 for ascending, and 1 is also truthy, so Sheets reads it as is_ascending = TRUE and agrees by accident. Our =SORT(A1:B3,2,1) case matched in both engines for exactly that reason. Only the descending formulas invert — because -1, the Excel value that means “descending”, is a nonzero number and therefore reads as “true”, which in Sheets means ascending. Half your sorts survive the trip and half of them silently reverse, and nothing anywhere says so.

What each vendor documents the third argument to be

Neither engine is misbehaving. Both are doing precisely what their own help page says, and the help pages disagree. We fetched both on 2026-08-30.

Google Sheets. The SORT function help article gives the signature as SORT(range, sort_column, is_ascending, [sort_column2, is_ascending2, ...]) and describes the third argument as “TRUE or FALSE indicating whether to sort sort_column in ascending order. FALSE sorts in descending order.” Its sample usage is SORT(A2:B26, 1, TRUE). There is no mention of 1 or -1 anywhere on the page, and no note about what happens if you pass a number.

Microsoft Excel. The SORT function page gives the signature as =SORT(array,[sort_index],[sort_order],[by_col]) and describes the third argument as “A number indicating the desired sort order; 1 for ascending order (default), -1 for descending order.” The fourth argument, [by_col], is the boolean one there: “A logical value indicating the desired sort direction; FALSE to sort by row (default), TRUE to sort by column.”

So the two signatures put a number and a boolean in the same slot, and Excel’s boolean sits one position further right, where Sheets expects sort_column2. We have executed cases for the three-argument form only; the four-argument collision is what the two documented signatures imply, not something we measured, and we are not claiming a result for it.

Executed: the SORT function corpus across four LibreOffice builds and Google Sheets

These are the four SORT cases in our function corpus, run as written. Inputs: the first two cases read A1:A5 = 3, 1, 4, 1, 5; the third reads A1:B3 = x/30, y/10, z/20; the fourth has no setup cells at all, so A1 is blank. The Excel column is Microsoft’s documented behaviour and is the value every case is measured against — we do not run Excel. Because these formulas spill, each executed cell shows the anchor value followed by the read-back of the whole recorded check range.

CaseFormulaExcel (documented)Google Sheets (Drive import, 2026-08-29)LibreOffice 24.2.0.3 (executed)LibreOffice 24.8.7.2, 25.2.0.3 & 25.8.7.3 (executed)
SORT_default_ascending =SORT(A1:A5) 1, 1, 3, 4, 5 1 — read-back 1, 1, 3, 4, 5 (matches) #NAME? 1 — read-back 1, 1, 3, 4, 5 (matches)
SORT_descending =SORT(A1:A5,1,-1) 5, 4, 3, 1, 1 1 — read-back 1, 1, 3, 4, 5 (ascending; does not match) #NAME? 5 — read-back 5, 4, 3, 1, 1 (matches)
SORT_by_second_column =SORT(A1:B3,2,1) y, 10 / z, 20 / x, 30 y — read-back y, 10, z, 20, x, 30 (matches) #NAME? y — read-back y, 10, z, 20, x, 30 (matches)
SORT_empty_range_error =SORT(A1:A1) 0 (a blank cell sorts as 0 in numeric context; no error documented) blank — the exported cell carried no value and no error #NAME? 0 (24.8.7.2) → #VALUE! (25.2.0.3) → 0 (25.8.7.3)

Row two is the whole page in one line. The Excel column and the LibreOffice column both read 5, 4, 3, 1, 1; the Google Sheets column reads 1, 1, 3, 4, 5 — the identical output the ascending case produced one row above. Sheets did not refuse the -1, did not warn about it, and did not return a partial result. It sorted ascending.

Row three is the accidental agreement. =SORT(A1:B3,2,1) asks for “sort by the second column, ascending” in Excel’s dialect, and the same 1 is a truthy is_ascending in Sheets’ dialect, so both engines return y, 10 / z, 20 / x, 30. It is the same coincidence that makes the divergence hard to find: a workbook full of ascending sorts imports perfectly and tells you nothing about the descending ones.

Reading “-1 is nonzero, therefore truthy, therefore TRUE, therefore ascending” is our explanation of the measurement, not itself a measurement. What we executed is the value: 1, 1, 3, 4, 5, where 5, 4, 3, 1, 1 was asked for.

The #NAME? column is a separate story: SORT does not exist in LibreOffice 24.2.0.3 at all, and arrives in 24.8.7.2. That version map, for SORT and the rest of the dynamic-array family, is in which LibreOffice version you need for VSTACK, HSTACK, TEXTSPLIT, TAKE and DROP.

Executed: the same collision in two how-to recipes

Our how-to corpus is a second, independent body of executed formulas, run in LibreOffice Calc 25.8.7.3 and imported to Google Sheets on 2026-08-30. Two of its pages turn on this argument. The gs-alt rows are Google Sheets alternatives: formulas scoped to that engine in our corpus and executed there only, which is why their LibreOffice cell reads n/a rather than a value.

Inputs: the sort recipe reads A2:A4 = 20, 50, 10; the reverse recipe reads A2:A4 = apple, banana, cherry.

RecipeFormulaExcel (documented)Returned by Google Sheets (executed 2026-08-30)LibreOffice 25.8.7.3 (executed)
sort-a-range-with-a-formula main =SORT(A2:A4,1,-1) 50, 20, 10 10, 20, 50 50, 20, 10
sort-a-range-with-a-formula gs-alt =SORT(A2:A4,1,FALSE) — Sheets-only rewrite, no Excel claim 50, 20, 10 — Google Sheets alternative (executed 2026-08-30) n/a (Sheets-only formula)
reverse-the-order-of-a-list main =SORTBY(A2:A4,ROW(A2:A4),-1) cherry, banana, apple #NAME? cherry, banana, apple
reverse-the-order-of-a-list gs-alt =SORT(A2:A4,ROW(A2:A4),FALSE) — Sheets-only rewrite, no Excel claim cherry, banana, apple — Google Sheets alternative (executed 2026-08-30) n/a (Sheets-only formula)

The fix is one argument, and we ran it. Replace -1 with FALSE: =SORT(A2:A4,1,FALSE) returned 50, 20, 10 in the same Google Sheets run that gave 10, 20, 50 for the -1 form. Nothing else about the formula changes — same range, same sort column, same spill.

The reverse-a-list pair shows the argument doing a second job. SORTBY is the natural Excel and LibreOffice way to flip a list without alphabetising it — sort the range by its own row numbers, descending — and it executed to cherry, banana, apple in Calc 25.8.7.3. In Google Sheets it returned #NAME?, which is a real result rather than an import artefact: our function inventory records SORTBY as undocumented in Sheets, and the corpus’s own =SORTBY(A1:A3,B1:B3) case likewise returned #NAME? there on 2026-08-29. The Sheets rewrite is SORT itself with a range as its second argument — =SORT(A2:A4,ROW(A2:A4),FALSE) — because Google documents sort_column as either a column index or “a range outside of range containing the values by which to sort”. That executed to cherry, banana, apple. So Sheets can sort by an arbitrary key; it just spells it SORT, and the direction flag is still the boolean.

Google also ships SORTN, a top-n sorter that Excel and LibreOffice do not have at all. Our inventory records it as documented in Google Sheets only, and we have authored no test cases for it — it is mentioned here as documentation, with no executed result behind it.

The blank-cell case, and one LibreOffice release that disagreed with itself

The fourth corpus case, =SORT(A1:A1) over a single empty cell, is not about the third argument, but it is the other thing our SORT runs turned up and it is worth recording honestly.

In LibreOffice it is the only cross-release instability in the whole executed corpus. Our LibreOffice version support page reports that of 791 non-volatile cases across 250 functions that ran in all four tested builds, exactly one did not return the identical value in every build after the first that supported it — and it is this one: #NAME? in 24.2.0.3, 0 in 24.8.7.2, #VALUE! in 25.2.0.3, and 0 again in 25.8.7.3. A degenerate input regressed for one release and came back. “Supported” is per case, not per function.

In Google Sheets the same case came back as an empty cell: our readback recorded no value and no error code for it, against a documented 0. Be careful how much weight that carries. Our Sheets measurement is an export-and-readback — the workbook goes to Drive, Google recalculates it, and the file comes back as .xlsx — and an exported cell holding nothing is indistinguishable from a formula that produced nothing. We can say the cell contained no value and no error; we cannot separate “SORT returned blank” from “the export wrote no cell”. What we can say is that the sheet did recalculate: its arithmetic canary passed. Treat it as blank-not-zero with that caveat attached, and do not build on it.

Finding this in a workbook before it costs you

Search the formula text for ,-1) next to SORT. That is the entire signature of the bug. A workbook moving from Excel or LibreOffice to Google Sheets needs every SORT(...,-1) rewritten to SORT(...,FALSE); every SORT(...,1) and every argument-less SORT(range) can be left alone, on the evidence above.

Do not trust the eyeball test on a sorted column. A reversed sort still looks like a sorted list. If the column is a leaderboard, the top row is now the worst performer; if it feeds an INDEX/MATCH or a “first row” reference, the number downstream is wrong and plausible. Check the first value against the maximum, not against your sense of tidiness.

Going the other way is a hard failure, which is better. A Sheets formula written =SORT(A2:A4,1,FALSE) and opened in Excel or LibreOffice hands a boolean to an argument documented to take a number. We have no executed case for that direction — our corpus does not run Sheets-dialect formulas in Calc — so we make no claim about what it returns, only that the rewrite in this page’s table is scoped to Sheets on purpose and is not portable back.

Rebuild descending sorts on SORTBY only if the target has it. SORTBY works in LibreOffice from 24.8.7.2 in our runs and returns #NAME? in Google Sheets, so it is a fine Excel/Calc idiom and a dead end for Sheets. The portable-by-hand alternative for reversing a list, recorded on the how-to page, is an INDEX-with-COUNTA fill-down.

This belongs to the same family as the other quiet Google Sheets divergences we have executed: Google Sheets does not array-evaluate inside a scalar function, where four of the divergent rows come back as plain wrong numbers, is the largest one. SORT’s third argument is narrower but sharper: there is no error to catch anywhere in the chain, and the result is still a correctly-formed, correctly-typed, fully-populated column.

Honest limits

The Excel column throughout is Microsoft’s documented behaviour as recorded in our test corpus. We do not run Excel, and no value in that column is a measurement.

The Google Sheets columns are executed output from dated runs, because Sheets has no version number to pin. The function-corpus values carry the label Google Sheets (Drive import, 2026-08-29); the recipe values come from the 2026-08-30 run of the recipe corpus. In both, a formula-only .xlsx with no cached results goes to Google Drive, is recalculated by Google’s engine, and is exported back for readback, with a deterministic =1111+2222 canary proving the recalculation happened. Google could change any of this tomorrow without changing a version number.

The Sheets cases on this page were written into the .xlsx with plain function names, while the LibreOffice reference run executed the _xlfn. storage form of the same formulas. The formula text is identical, but the two runs did receive different input files, and our results record that note per case. That serialization difference is why the 2026-08-29 Sheets values for SORT exist at all: an earlier prefixed run left them inconclusive.

The LibreOffice columns are executed output from four builds — 24.2.0.3, 24.8.7.2, 25.2.0.3 and 25.8.7.3 — and those four are the only ones we tested. A behaviour we describe as arriving in 24.8.7.2 may have arrived in any release after 24.2.0.3.

Finally, scope. Everything above is measured on the three-argument form of SORT over small ranges. We have no executed case for the fourth argument, for multiple sort keys, for sort_column ranges in Excel or LibreOffice, or for what a boolean does to sort_order outside Sheets. See our methodology for how recalculation is proven rather than assumed, and the SORT function page for the per-engine support matrix.

Check before you migrate