{
  "category": "Lookup and reference functions",
  "display_name": "TRIMRANGE",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.TRIMRANGE",
  "implementation_state": {
    "answer_bank": null,
    "detail": "Recorded: 2 workbook cells.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "matches",
    "state_label": "Matches every recorded Excel answer",
    "summary": "Matches all 2 recorded answers",
    "workbook_corpus": {
      "cells": 2,
      "matched": 2
    }
  },
  "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/offset.rs#L62-L74",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/offset.rs#L156-L240",
        "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/offset.rs#L242-L284"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "catalogue/offset::span"
      ],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/offset.rs#L62-L74",
      "state": "matches",
      "suite": null,
      "summary": "Matches all 2 recorded answers"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.TRIMRANGE.json",
  "name": "TRIMRANGE",
  "notes": [],
  "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- **The trim-reference operators** are the operator form of the same idea, and are modeled in\n  this Handbook as functions: `FUNC.OP_TRIM_REF_LEADING`, `FUNC.OP_TRIM_REF_TRAILING` and\n  `FUNC.OP_TRIM_REF_BOTH` (see [the call pipeline](../model/03-call-pipeline.md), \"Operators are\n  functions\"). `A.:A` and its relatives are the terse spelling of `TRIMRANGE(A:A, …)`.\n- **`OFFSET` with `COUNTA`** is the idiom `TRIMRANGE` replaces, and it is volatile.\n- **`INDEX`-built ranges** (`A1:INDEX(A:A, n)`) are the non-volatile pre-`TRIMRANGE` idiom.\n- **`TOCOL(…, 1)`** removes *all* blanks and flattens; `TRIMRANGE` removes only the margin and\n  keeps the rectangle.\n- **`FILTER`** removes rows by predicate.\n- **`ROWS`/`COUNTA`** are what people reach for when they want the *size* of the populated\n  region rather than its contents.\n\n\n",
    "how-to-implement": "\n### Notes for implementers\n\n- Trimming is per axis and per edge: four independent decisions driven by two codes. Scanning\n  in from each edge is the natural implementation and is `O(m + n)` in the populated case, not\n  `O(mn)` — worth getting right, because whole-column references are the intended input.\n- Interior blanks must survive. A compaction pass is a different function.\n- The blank predicate must be stated and shared with the rest of the engine.\n- The code table and default are exactly the place to *not* guess. Whatever mapping is\n  implemented should be traceable to a source, and the divergence recorded above should be\n  resolved by observation before either mapping is trusted.\n\n\n",
    "quirks": "\n### A documented divergence\n\nMicrosoft's page, retrieved for this entry, documents three arguments, `1` meaning *leading*,\n`2` meaning *trailing*, and a default of `3`.\n\nThe Handbook does not resolve this here, and does not silently prefer either side. What can be\nsaid honestly:\n\n- The two accounts disagree about the **default**, about the **meaning of the codes `1` and\n  `2`**, and about the **existence of a fourth argument**.\n- Nobody has run the experiment that would settle it. It is a single afternoon's work: enter\n  `TRIMRANGE` with each code in each position against a range with known leading and trailing\n  blanks, and record what comes back.\n\nUntil that happens, treat Microsoft's table as the documented behaviour and treat any\nimplementation's code mapping as an implementation detail to verify rather than to trust.\n\n\n\n### Result and edge cases\n\n\nThe return kind is an array containing the trimmed contents.\n\n- **What counts as blank** is the pivotal question, exactly as for `TOCOL`: an empty cell\n  certainly, but a cell holding `\"\"`, or a formula returning `\"\"`, is a different matter. A\n  column of formulas that return `\"\"` below the data is the single most common real input to\n  `TRIMRANGE`, and the documentation does not say what happens to it.\n- **Interior blanks survive**, always.\n- Dynamic-array publication and `#SPILL!` are host-side adaptation.\n\n\n\n### Errors\n\nThe Handbook therefore states the error surface as **unsettled**: there is a declared\nimplementation mapping and no documented counterpart, and the two have not been compared.\n\n\n",
    "sources": "- Microsoft, *TRIMRANGE function* —\n  <https://support.microsoft.com/en-us/office/trimrange-function-d7812248-3bc5-4c6b-901c-1afa9564f999>\n  (syntax `=TRIMRANGE(range,[trim_rows],[trim_cols])`, the `0`/`1`/`2`/`3` code tables for both\n  axes, and the default of `3` for each). Retrieved for this page.\n- Handbook `content/model/01-value-universe.md` (the `#CALC!` empty-array convention) and\n  `content/model/03-call-pipeline.md` (the trim-reference operator identities).\n\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`TRIMRANGE` removes blank rows and columns from the **edges** of a range or array and returns\nwhat is left.\n\nThe operation scans inward from each edge until it meets a non-blank cell, then keeps the\nrectangle bounded by those four positions. Interior blanks are untouched — a blank row in the\nmiddle of populated data stays exactly where it is. `TRIMRANGE` is a *margin* operation, not a\ncompaction; anything that removes interior blanks (`TOCOL(…, 1)`, `FILTER`) is a different\nfunction.\n\nWhich edges are trimmed is controlled per axis: rows and columns have independent settings for\nwhether leading blanks, trailing blanks, both, or neither are removed.\n\n\n\n### Arguments\n\n\nMicrosoft documents `TRIMRANGE(range, [trim_rows], [trim_cols])`:\n\n| Argument | Documented default | Meaning |\n|---|---|---|\n| `range` | required | The range (or array) to be trimmed |\n| `trim_rows` | `3` | `0` none · `1` leading blank rows · `2` trailing blank rows · `3` both |\n| `trim_cols` | `3` | `0` none · `1` leading blank cols · `2` trailing blank cols · `3` both |\n\nSo the documented default trims blank margins on all four sides.\n\nThe argument most likely to be misread is the code itself, because `1` and `2` are not\nsymmetric-looking and there is nothing in the call site to remind you which is which. `0` and\n`3` are safe; the intermediate values are worth spelling out in a comment.\n\n\n"
  },
  "signature": {
    "display": "TRIMRANGE(range, [trim_rows], [trim_cols])",
    "parameters": [
      {
        "description": null,
        "name": "range",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "trim_rows",
        "optional": true,
        "repeats": false
      },
      {
        "description": null,
        "name": "trim_cols",
        "optional": true,
        "repeats": false
      }
    ],
    "trailing_repeats": false
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "implemented",
        "reason": null
      },
      "arity": {
        "max": 3,
        "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": "WorkbookState",
        "kernel_signature_class": "Custom",
        "rich_value_usage": "RichBlind",
        "surface_fec_dependency_profile": "RefOnly",
        "thread_safety_class": "HostSerialized",
        "volatility_class": "NonVolatile"
      },
      "descriptions": {
        "long": null,
        "short": "A range with its empty outer rows and columns cut away",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Scans in from the edges of a range or array until it finds a non-blank cell (or value), it then excludes those blank rows or columns",
        "microsoft_url": "https://support.microsoft.com/en-us/office/trimrange-function-d7812248-3bc5-4c6b-901c-1afa9564f999"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "TRIMRANGE"
        },
        {
          "locale": "bg-BG",
          "name": "TRIMRANGE"
        },
        {
          "locale": "cs-CZ",
          "name": "OŘÍZNOUTOBLAST"
        },
        {
          "locale": "da-DK",
          "name": "TRIMOMRÅDE"
        },
        {
          "locale": "de-DE",
          "name": "TRIMRANGE"
        },
        {
          "locale": "el-GR",
          "name": "TRIMRANGE"
        },
        {
          "locale": "en-AU",
          "name": "TRIMRANGE"
        },
        {
          "locale": "en-GB",
          "name": "TRIMRANGE"
        },
        {
          "locale": "en-US",
          "name": "TRIMRANGE"
        },
        {
          "locale": "es-ES",
          "name": "RECORTAR.RANGO"
        },
        {
          "locale": "et-EE",
          "name": "TRIMRANGE"
        },
        {
          "locale": "fi-FI",
          "name": "RAJAAALUE"
        },
        {
          "locale": "fr-FR",
          "name": "SUPPR.PLAGE*"
        },
        {
          "locale": "he-IL",
          "name": "TRIMRANGE"
        },
        {
          "locale": "hr-HR",
          "name": "TRIMRANGE"
        },
        {
          "locale": "hu-HU",
          "name": "KIMETSZÉSITARTOMÁNY"
        },
        {
          "locale": "id-ID",
          "name": "TRIMRANGE"
        },
        {
          "locale": "it-IT",
          "name": "TRIMRANGE"
        },
        {
          "locale": "ja-JP",
          "name": "TRIMRANGE"
        },
        {
          "locale": "ko-KR",
          "name": "TRIMRANGE"
        },
        {
          "locale": "lt-LT",
          "name": "TRIMRANGE"
        },
        {
          "locale": "lv-LV",
          "name": "TRIMRANGE"
        },
        {
          "locale": "nb-NO",
          "name": "TRIMRANGE"
        },
        {
          "locale": "nl-NL",
          "name": "TRIMBEREIK"
        },
        {
          "locale": "pl-PL",
          "name": "PRZYTNIJZAKRES"
        },
        {
          "locale": "pt-BR",
          "name": "TRIMRANGE"
        },
        {
          "locale": "pt-PT",
          "name": "APARARINTERVALO"
        },
        {
          "locale": "ro-RO",
          "name": "TRIMRANGE"
        },
        {
          "locale": "ru-RU",
          "name": "УРЕЗДИАПАЗОН"
        },
        {
          "locale": "sk-SK",
          "name": "TRIMRANGE"
        },
        {
          "locale": "sl-SI",
          "name": "TRIMRANGE"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "TRIMRANGE"
        },
        {
          "locale": "sv-SE",
          "name": "KLIPPOMRÅDE"
        },
        {
          "locale": "th-TH",
          "name": "TRIMRANGE"
        },
        {
          "locale": "tr-TR",
          "name": "KIRPARALIĞI"
        },
        {
          "locale": "uk-UA",
          "name": "TRIMRANGE"
        },
        {
          "locale": "vi-VN",
          "name": "TRIMRANGE"
        },
        {
          "locale": "zh-CN",
          "name": "TRIMRANGE"
        },
        {
          "locale": "zh-HK",
          "name": "TRIMRANGE"
        },
        {
          "locale": "zh-TW",
          "name": "TRIMRANGE"
        }
      ],
      "signature": {
        "display": "TRIMRANGE(range, [trim_rows], [trim_cols])",
        "parameters": [
          {
            "description": null,
            "name": "range",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "trim_rows",
            "optional": true,
            "repeats": false
          },
          {
            "description": null,
            "name": "trim_cols",
            "optional": true,
            "repeats": false
          }
        ],
        "trailing_repeats": false
      },
      "surface_name": "TRIMRANGE",
      "version_marker": null,
      "xlcall": null
    },
    "microsoft": "https://support.microsoft.com/en-us/office/trimrange-function-d7812248-3bc5-4c6b-901c-1afa9564f999"
  },
  "try_it": {
    "formula": "=TRIMRANGE({1;2;3})"
  },
  "url": "https://handbook.dnacalc.com/functions/TRIMRANGE.html",
  "variants": [],
  "versions": []
}