{
  "category": "Lookup and reference functions",
  "display_name": "SORT",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.SORT",
  "implementation_state": {
    "answer_bank": null,
    "detail": "Of 93 recorded answers (93 workbook cells), 20 do not match: 4 differ in kind or value, 16 are refused.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "differs",
    "state_label": "Known larger differences",
    "summary": "Known larger differences on 20 of 93 recorded answers",
    "workbook_corpus": {
      "cells": 93,
      "matched": 73,
      "other_mismatch": 4,
      "refused": 16
    }
  },
  "implementations": [
    {
      "commit": "9e1884369a678158dd82d3d74188daf986995e87",
      "flavour": "excel-compatibility-candidate",
      "language": "Rust",
      "name": "CalcFunc",
      "own_code": [
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/arrays.rs#L637-L639",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/arrays.rs#L383-L426"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "catalogue/arrays::prepared",
        "catalogue/arrays::prepared_one",
        "catalogue/arrays::as_array",
        "catalogue/arrays::integer",
        "catalogue/arrays::descending",
        "catalogue/arrays::flag",
        "catalogue/arrays::kind",
        "catalogue/arrays::order",
        "catalogue/arrays::sorted_indices",
        "catalogue/arrays::reordered",
        "catalogue/comparison::numbers",
        "catalogue/comparison::in_band",
        "catalogue/comparison::Rounded::up",
        "catalogue/comparison::Roundings::of",
        "catalogue/comparison::Roundings::disjoint",
        "catalogue/comparison::texts",
        "catalogue/comparison/collation::compare",
        "catalogue/comparison/collation::weighed",
        "catalogue/comparison/collation::measured_iteration_extension",
        "catalogue/comparison/sort_key::table",
        "catalogue/comparison/sort_key::decode64",
        "catalogue/comparison/sort_key::Reader::byte",
        "catalogue/comparison/sort_key::Reader::varint",
        "catalogue/comparison/sort_key::Reader::done",
        "catalogue/comparison/sort_key::in_ranges",
        "catalogue/comparison/sort_key::build",
        "catalogue/comparison/sort_key::han_base",
        "catalogue/comparison/sort_key::derive",
        "catalogue/comparison/sort_key::shared_jamo_tails",
        "catalogue/comparison/sort_key::ordinary_jamo_prefix",
        "catalogue/comparison/sort_key::independent_jamo_suffix",
        "catalogue/comparison/sort_key::jamo_leading_primary",
        "catalogue/comparison/sort_key::leading_order",
        "catalogue/comparison/sort_key::Before::separate_special",
        "catalogue/comparison/sort_key::Gathered::kana",
        "catalogue/comparison/sort_key::Gathered::unit",
        "catalogue/comparison/sort_key::parts",
        "catalogue/comparison/sort_key::diacritic_order",
        "catalogue/comparison/sort_key::diacritics",
        "decimal::low32",
        "decimal::Natural::from_u64",
        "decimal::Natural::pow10",
        "decimal::Natural::normalize",
        "decimal::Natural::is_zero",
        "decimal::Natural::mul_add_small",
        "decimal::Natural::times_pow10",
        "decimal::Natural::times_pow5",
        "decimal::Natural::times_pow2",
        "decimal::ExactDecimal::binary",
        "ported/dynamic_array_reshape_family::coerce_prepared_to_number"
      ],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/arrays.rs#L637-L639",
      "state": "differs",
      "suite": null,
      "summary": "Known larger differences on 20 of 93 recorded answers"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.SORT.json",
  "name": "SORT",
  "notes": [
    {
      "basis": "77 recorded controls over three bases (時, 人, 漢).",
      "documentation": null,
      "evidence": [
        {
          "commit": "44db028d72d692e94557b3657748d25643cd199d",
          "locator": "fn1_han_iteration_comparison_and_lookup_order",
          "note": "recorded order pinned",
          "path": "crates/calc-fml/tests/acceptance/f3.rs",
          "repository": "DnaCalc"
        }
      ],
      "functions": [
        "FUNC.OP_LESS_THAN",
        "FUNC.SORT"
      ],
      "inferred": null,
      "kind": "quirk",
      "note_id": "FN-SORT-001",
      "open": [],
      "recorded_on": "2026-11-04",
      "repros": [
        {
          "call": "=\"時々\"<\"時時\"",
          "correct": null,
          "excel": {
            "bits": null,
            "display": "TRUE",
            "kind": "logical"
          },
          "input_route": "formula-literal",
          "inputs": [],
          "recorded_in": "Excel 16.0.20527.20088 Current Channel, Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZA",
          "source": {
            "commit": "f3275d997ae0706471e7b2c52b36fafad6966a03",
            "locator": "sheet fn1_collation, row 2, column 4",
            "note": null,
            "path": "crates/calc-func/tests/captures/catalogue/sections/fn1_collation.capture.json",
            "repository": "DnaCalc"
          }
        },
        {
          "call": "=\"時々\"<\"時a\"",
          "correct": null,
          "excel": {
            "bits": null,
            "display": "TRUE",
            "kind": "logical"
          },
          "input_route": "formula-literal",
          "inputs": [],
          "recorded_in": "Excel 16.0.20527.20088 Current Channel, Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZA",
          "source": {
            "commit": "f3275d997ae0706471e7b2c52b36fafad6966a03",
            "locator": "sheet fn1_collation, row 3, column 4",
            "note": null,
            "path": "crates/calc-func/tests/captures/catalogue/sections/fn1_collation.capture.json",
            "repository": "DnaCalc"
          }
        },
        {
          "call": "=TEXTJOIN(\"|\",FALSE,SORT({\"時々\";\"時時\";\"時\";\"時a\";\"時b\"}))",
          "correct": null,
          "excel": {
            "bits": null,
            "display": "時|時々|時a|時b|時時",
            "kind": "text"
          },
          "input_route": "formula-literal",
          "inputs": [],
          "recorded_in": "Excel 16.0.20527.20088 Current Channel, Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZA",
          "source": {
            "commit": "f3275d997ae0706471e7b2c52b36fafad6966a03",
            "locator": "sheet fn1_collation, row 229, column 4",
            "note": null,
            "path": "crates/calc-func/tests/captures/catalogue/sections/fn1_collation.capture.json",
            "repository": "DnaCalc"
          }
        }
      ],
      "schema": "efh.function-note/v1",
      "statement": "In text comparison and SORT, after a Han character the iteration mark 々 sorts before Latin letters and before the doubled character: 時 < 時々 < 時a < 時b < 時時. Latin letters sort before Han here, and 時々 is not treated as 時時.",
      "status": "measured",
      "title": "A Han iteration mark is not read as a repeat of the character"
    }
  ],
  "schema": "efh.function-reference/v1",
  "section_order": [
    "what-it-does",
    "try-it",
    "quirks",
    "how-to-implement",
    "version-differences",
    "alternatives"
  ],
  "sections": {
    "alternatives": "\n### Relationships\n\n\n- **`SORTBY`** is the sibling that sorts by *external* keys: one or more arrays parallel to the\n  data but not part of it, each with its own direction. `SORT` is the special case where the\n  key lives inside the array. `SORTBY` also supports multi-level sorts, which `SORT` does not.\n- **`UNIQUE`** removes duplicates; `SORT(UNIQUE(x))` is the standard composition and the two\n  are frequently confused because both \"tidy up a list\".\n- **`FILTER`** selects rows; `SORT` reorders them. `SORT(FILTER(...))` is the usual pipeline.\n- **`LARGE` / `SMALL` / `RANK`** answer order questions about a single vector without\n  materializing a sorted copy.\n- The legacy equivalent is the **Data ▸ Sort** command, which mutates the sheet. `SORT` is the\n  formula form: the source is untouched and the result recomputes.\n\n\n",
    "how-to-implement": "\n### Notes for implementers\n\n\n- Sorting must move whole rows, not just the key column. An implementation that sorts the key\n  and reassembles by index is fine; one that sorts each column independently is catastrophic\n  and produces plausible-looking output.\n- The omitted-slot call shape (`SORT(a,,-1)`) must normalize to the same default path as an\n  absent trailing argument. This is a real, recorded defect class in this family.\n- Stability is a decision, and an undecided one is a source of nondeterminism across\n  implementations. Record whatever choice is made.\n- The cross-kind comparison order is shared with every other ordering surface in the engine\n  (`SORTBY`, `LARGE`, ordered `MATCH`, `XMATCH`'s nearest modes). It should live in one place.\n- Text collation is locale-dependent, which means `SORT` cannot be `portable-reproducible`\n  without a declared collation; that declaration belongs in the flavour's contract, not in the\n  kernel.\n\n\n",
    "quirks": "\n### Result and edge cases\n\n\nThe return kind is an array with the same dimensions as `array`, published as a dynamic-array\nspill.\n\n- **Ties.** Whether the permutation is stable — whether rows with equal keys keep their\n  original relative order — is not stated by the documentation. It is observable, it matters\n  for reproducibility, and the Handbook has not pinned it.\n- **Mixed types in the key column.** `SORT` needs a total order across value kinds. Microsoft\n  documents such an order for `MATCH` (numbers, then text, then `FALSE`, then `TRUE`); whether\n  `SORT` uses the same one is an open question here.\n- **Text ordering is locale-dependent.** Sorting text means collation, and collation depends on\n  the locale. This is the one part of `SORT` that cannot be characterized by a locale-free\n  vector suite.\n- **`sort_index` out of range** is expected to be an error rather than a clamp; the specific\n  error is not documented.\n- **1×1 and single-row/single-column arrays** are trivially sorted but are exactly where\n  array-versus-scalar shape mistakes surface — see the `ROWS` page for why a 1×1 result must\n  stay an array.\n\n\n\n### Errors\n\n\nMicrosoft's page does not enumerate error conditions for `SORT` itself; it mentions `#REF!`\narising in cross-workbook dynamic-array scenarios when the source workbook is closed and the\nformula is refreshed, which is a dynamic-array behaviour rather than a `SORT` behaviour.\n\nBeyond that, the errors a reader will actually meet are `#SPILL!` when the result cannot be\nplaced (a publication outcome, not a function outcome) and whatever `SORT` returns for an\nout-of-range `sort_index`, which the Handbook has not verified. Error values inside `array`\nare carried along as values — `SORT` selects and reorders, it does not evaluate — but where\nthey sort to is unverified.\n\n\n",
    "sources": "- Microsoft, *SORT function* —\n  <https://support.microsoft.com/en-us/office/sort-function-22f63bd0-ccc8-492f-953d-c20e8e44b86c>\n  (syntax, the four arguments with their defaults `1`, `1`, `FALSE`, and the note about `#REF!`\n  in cross-workbook dynamic-array refresh). Retrieved for this page.\n- Microsoft, *MATCH function* — for the one cross-type ordering Microsoft does document.\n- Handbook `content/model/01-value-universe.md` (`Missing` versus `Empty`) and\n  `content/model/03-call-pipeline.md` (dynamic-array publication as host-side adaptation).\n- Handbook `data/functions/FUNC.SORT.json` (signature, arity, classification axes).\n\n",
    "version-differences": "No comparison between specific Excel builds is recorded here yet. This does not establish that all builds behave alike.",
    "what-it-does": "\n`SORT` permutes an array along one axis. It returns an array of **exactly the same shape** as\nits input — no rows are added, removed or merged — whose rows (or, with `by_col` set, whose\ncolumns) have been reordered so that the values in one designated column (or row) are in\nascending or descending order.\n\nStated precisely: let `A` be an `m × n` array. With `by_col` false, `SORT` computes a\npermutation `π` of `1..m` such that the sequence `A[π(1), k], A[π(2), k], …` is ordered, where\n`k` is `sort_index`, and returns the array `B` with `B[i, j] = A[π(i), j]`. The whole row moves\nwith its key; that is the entire point, and it is what distinguishes `SORT` from sorting a\nsingle column in isolation.\n\nTwo facts follow from \"permutation of the same shape\" that are worth stating because readers\nroutinely expect otherwise:\n\n- **`SORT` does not deduplicate.** Equal keys keep all their rows. That is `UNIQUE`'s job.\n- **`SORT` does not filter.** Blanks are values and get a position in the order; they are not\n  dropped. A range with trailing blank rows sorts those blanks somewhere, usually visibly.\n\nThe comparison order over mixed value kinds — numbers against text against logicals against\nblanks — is the part the documentation does not state, and it is the part the Handbook has not\nverified. Everything else about `SORT` is shape arithmetic.\n\n\n\n### Arguments\n\n\nMicrosoft documents `SORT(array, [sort_index], [sort_order], [by_col])`.\n\n| Argument | Default | Meaning |\n|---|---|---|\n| `array` | required | The range or array to sort |\n| `sort_index` | `1` | Which row or column supplies the keys |\n| `sort_order` | `1` | `1` ascending, `-1` descending |\n| `by_col` | `FALSE` | `FALSE` sorts rows by a column key; `TRUE` sorts columns by a row key |\n\nThe argument most often misread is `by_col`, because it changes what `sort_index` *indexes*.\nWith `by_col` false (the default), `sort_index` names a **column** and rows are permuted. With\n`by_col` true, `sort_index` names a **row** and columns are permuted. The flag and the index\nare coupled; changing one without the other silently sorts by the wrong key.\n\n`sort_index` is relative to `array`, not to the worksheet. If `array` is `C2:F20`, then\n`sort_index` `1` means column `C`.\n\n"
  },
  "signature": {
    "display": "SORT(array, [sort_index], [sort_order], [by_col])",
    "parameters": [
      {
        "description": null,
        "name": "array",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "sort_index",
        "optional": true,
        "repeats": false
      },
      {
        "description": null,
        "name": "sort_order",
        "optional": true,
        "repeats": false
      },
      {
        "description": null,
        "name": "by_col",
        "optional": true,
        "repeats": false
      }
    ],
    "trailing_repeats": false
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "implemented",
        "reason": null
      },
      "arity": {
        "max": 4,
        "min": 1
      },
      "category": "Lookup and reference functions",
      "classification": {
        "arg_preparation_profile": "ValuesOnlyPreAdapter",
        "coercion_lift_profile": "Custom",
        "determinism_class": "Deterministic",
        "error_collapse_profile": "None",
        "fec_dependency_profile": "None",
        "host_interaction_class": "None",
        "kernel_signature_class": "Custom",
        "rich_value_usage": "RichBlind",
        "surface_fec_dependency_profile": "RefOnly",
        "thread_safety_class": "SafePure",
        "volatility_class": "NonVolatile"
      },
      "descriptions": {
        "long": null,
        "short": "The contents of an array in sorted order",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Sorts the contents of a range or array",
        "microsoft_url": "https://support.microsoft.com/en-us/office/sort-function-22f63bd0-ccc8-492f-953d-c20e8e44b86c"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "SORT"
        },
        {
          "locale": "bg-BG",
          "name": "SORT"
        },
        {
          "locale": "cs-CZ",
          "name": "SORT"
        },
        {
          "locale": "da-DK",
          "name": "SORTER"
        },
        {
          "locale": "de-DE",
          "name": "SORT"
        },
        {
          "locale": "el-GR",
          "name": "SORT"
        },
        {
          "locale": "en-AU",
          "name": "SORT"
        },
        {
          "locale": "en-GB",
          "name": "SORT"
        },
        {
          "locale": "en-US",
          "name": "SORT"
        },
        {
          "locale": "es-ES",
          "name": "ORDENAR"
        },
        {
          "locale": "et-EE",
          "name": "SORT"
        },
        {
          "locale": "fi-FI",
          "name": "LAJITTELE"
        },
        {
          "locale": "fr-FR",
          "name": "TRIER*"
        },
        {
          "locale": "he-IL",
          "name": "SORT"
        },
        {
          "locale": "hr-HR",
          "name": "SORT"
        },
        {
          "locale": "hu-HU",
          "name": "SORBA.RENDEZ"
        },
        {
          "locale": "id-ID",
          "name": "SORT"
        },
        {
          "locale": "it-IT",
          "name": "SORT"
        },
        {
          "locale": "ja-JP",
          "name": "SORT"
        },
        {
          "locale": "ko-KR",
          "name": "SORT"
        },
        {
          "locale": "lt-LT",
          "name": "SORT"
        },
        {
          "locale": "lv-LV",
          "name": "SORT"
        },
        {
          "locale": "nb-NO",
          "name": "SORT"
        },
        {
          "locale": "nl-NL",
          "name": "SOORT"
        },
        {
          "locale": "pl-PL",
          "name": "SORTUJ"
        },
        {
          "locale": "pt-BR",
          "name": "SORT"
        },
        {
          "locale": "pt-PT",
          "name": "ORDENAR"
        },
        {
          "locale": "ro-RO",
          "name": "SORT"
        },
        {
          "locale": "ru-RU",
          "name": "СОРТ"
        },
        {
          "locale": "sk-SK",
          "name": "SORT"
        },
        {
          "locale": "sl-SI",
          "name": "SORT"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "SORTIRANJE"
        },
        {
          "locale": "sv-SE",
          "name": "SORTERA"
        },
        {
          "locale": "th-TH",
          "name": "SORT"
        },
        {
          "locale": "tr-TR",
          "name": "SIRALA"
        },
        {
          "locale": "uk-UA",
          "name": "SORT"
        },
        {
          "locale": "vi-VN",
          "name": "SORT"
        },
        {
          "locale": "zh-CN",
          "name": "SORT"
        },
        {
          "locale": "zh-HK",
          "name": "SORT"
        },
        {
          "locale": "zh-TW",
          "name": "SORT"
        }
      ],
      "signature": {
        "display": "SORT(array, [sort_index], [sort_order], [by_col])",
        "parameters": [
          {
            "description": null,
            "name": "array",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "sort_index",
            "optional": true,
            "repeats": false
          },
          {
            "description": null,
            "name": "sort_order",
            "optional": true,
            "repeats": false
          },
          {
            "description": null,
            "name": "by_col",
            "optional": true,
            "repeats": false
          }
        ],
        "trailing_repeats": false
      },
      "surface_name": "SORT",
      "version_marker": null,
      "xlcall": null
    },
    "microsoft": "https://support.microsoft.com/en-us/office/sort-function-22f63bd0-ccc8-492f-953d-c20e8e44b86c"
  },
  "try_it": {
    "formula": "=SORT({3;1;2})"
  },
  "url": "https://handbook.dnacalc.com/functions/SORT.html",
  "variants": [],
  "versions": [
    {
      "behaviour": "=TEXTJOIN(\"|\",FALSE,SORT({\"時々\";\"時時\";\"時\";\"時a\";\"時b\"})) returned 時|時々|時a|時b|時時. Inputs were supplied through formula literals. These are controls from this environment, not a same-input comparison with another build.",
      "excel_build": "16.0.20527.20088",
      "observations": [
        {
          "call": "=TEXTJOIN(\"|\",FALSE,SORT({\"時々\";\"時時\";\"時\";\"時a\";\"時b\"}))",
          "excel": {
            "bits": null,
            "display": "時|時々|時a|時b|時時",
            "kind": "text"
          },
          "input_route": "formula-literal",
          "inputs": [],
          "recorded_in": "Excel 16.0.20527.20088 Current Channel, Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZA"
        }
      ],
      "platform": "Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZA",
      "sources": [
        "https://github.com/DnaCalc/ExcelFunctionsHandbook/blob/3345a87/content/notes/FN-SORT-001.json"
      ]
    }
  ]
}