{
  "category": "Math and trigonometry functions",
  "display_name": "SUBTOTAL",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.SUBTOTAL",
  "implementation_state": {
    "answer_bank": null,
    "detail": "Recorded: 8 workbook cells.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": true,
    "state": "matches",
    "state_label": "Matches every recorded Excel answer",
    "summary": "Matches all 8 recorded answers",
    "workbook_corpus": {
      "cells": 9,
      "matched": 8,
      "pending": 1
    }
  },
  "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/subtotal.rs#L186-L196"
      ],
      "repository": "https://github.com/DnaCalc/DnaCalc",
      "shared_code": [
        "catalogue/aggregate::reader",
        "catalogue/aggregate::read_reference",
        "catalogue/subtotal::held_values",
        "catalogue/subtotal::numbers_of",
        "catalogue/subtotal::compute",
        "ported/excel_numeric::excel_sqrt_staged",
        "ported/variance_common::variance_from_values",
        "ported/variance_common::stdev_from_values"
      ],
      "source": "https://github.com/DnaCalc/DnaCalc/blob/9e1884369a678158dd82d3d74188daf986995e87/crates/calc-func/src/catalogue/subtotal.rs#L186-L196",
      "state": "matches",
      "suite": null,
      "summary": "Matches all 8 recorded answers"
    }
  ],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.SUBTOTAL.json",
  "name": "SUBTOTAL",
  "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- **The eleven kernels** — `AVERAGE`, `COUNT`, `COUNTA`, `MAX`, `MIN`, `PRODUCT`, `STDEV`,\n  `STDEVP`, `SUM`, `VAR`, `VARP`. Note that the dispatch table names the *compatibility* forms\n  (`STDEV`, `STDEVP`, `VAR`, `VARP`), not the modern `STDEV.S` / `STDEV.P` / `VAR.S` / `VAR.P`\n  names. `SUBTOTAL` is a fixed table written before that renaming and it did not move.\n- **`SUMIFS` / `COUNTIFS`** — the criteria-based alternative when the filter is a data condition\n  rather than a UI state. They are deterministic in a way `SUBTOTAL` is not, because their filter\n  lives in the formula.\n- **`SUM`** — the direct call, which includes everything regardless of visibility and does not\n  skip nested subtotals. Replacing `SUBTOTAL(9, ...)` with `SUM(...)` in a table that has group\n  subtotals double-counts.\n- **Confused with**: the **Subtotal command** on the Data tab, which is a UI feature that inserts\n  `SUBTOTAL` formulas and grouping outlines. The function and the command share a name and are\n  not the same thing.\n\n\n",
    "how-to-implement": "\n### Numerical notes\n\n\n`SUBTOTAL` performs no arithmetic of its own; its numerical behaviour is a union of eleven\nkernels' behaviours plus one property of its own.\n\n**The kernels split into three difficulty classes.**\n\n2. **`AVERAGE`.** A sum followed by a division: one extra rounding, and the sum's error carried\n   through. Nothing structural.\n3. **`STDEV`, `STDEVP`, `VAR`, `VARP` — the interesting ones.** The textbook computational\n   formula `(SUM x^2 - n*mean^2)/(n-1)` subtracts two large nearly-equal quantities and can\n   return a negative variance on data with a large mean and small spread. Chan, Golub and\n   LeVeque's classic paper catalogues the alternatives and their error behaviour: the two-pass\n   algorithm (compute the mean, then the sum of squared deviations) is accurate and needs the\n   data twice; Welford's updating recurrence is accurate, needs one pass, and is what most modern\n   libraries use. Which of these a given implementation of `STDEV` uses is not something the\n   worksheet can see — and `SUBTOTAL(7, ...)` inherits it wholesale.\n\n**The dispatch adds one more consideration: the visible subset changes the conditioning.** A\nvariance over a filtered subset can be far worse conditioned than the variance over the whole\ncolumn, because filtering can leave a set with a large mean and a tiny spread. A `SUBTOTAL(10,\n...)` that looks stable on the unfiltered data can become numerically fragile the moment a filter\nis applied, and nothing in the interface signals it.\n\nThe Handbook makes no claim about which variance algorithm Excel uses in any of these kernels.\n\n\n",
    "quirks": "\n### The two number ranges\n\n\nThe distinction between `1-11` and `101-111` is not the same as the distinction between hidden\nand filtered, and conflating them is the most common `SUBTOTAL` mistake. Microsoft's two\nstatements, side by side:\n\n- Codes `1-11` **include** manually hidden rows; codes `101-111` **exclude** them.\n- \"The SUBTOTAL function ignores any rows that are not included in the result of a filter, no\n  matter which function_num value you use.\"\n\nSo there are two ways for a row to be invisible and they are treated differently:\n\n| Row is invisible because… | `1-11` | `101-111` |\n|---|---|---|\n| a filter excluded it | ignored | ignored |\n| someone hid the row manually | **included** | ignored |\n\nFiltering is unconditional; manual hiding is the axis the code range controls. A reader who\nhides rows by hand and expects `SUBTOTAL(9, ...)` to drop them will get a total that silently\nincludes them.\n\nTwo further documented constraints belong here:\n\n- **`SUBTOTAL` is designed for vertical ranges.** Microsoft states it plainly: it \"is designed\n  for columns of data, or vertical ranges. It is not designed for rows of data, or horizontal\n  ranges.\" Hidden *columns* have no corresponding rule, which is the practical content of the\n  statement — the visibility machinery is row-shaped.\n- **3-D references are rejected.** \"If any of the references are 3-D references, SUBTOTAL returns\n  the #VALUE! error value.\"\n\n\n\n### Result and edge cases\n\n\nReturns `Number`. The kind and meaning of that number are whatever the selected aggregate\nproduces.\n\n- **Empty visible set.** What `SUBTOTAL(1, ...)` returns when every row is filtered out is not\n  documented; `AVERAGE` over nothing is `#DIV/0!` and `SUM` over nothing is zero, so the answer\n  depends on the kernel. The Handbook has not checked.\n- **`function_num` out of the documented set** — `0`, `12`, `100`, `112`, a non-integer — is not\n  documented. `#VALUE!` is the plausible answer and the Handbook does not assert it.\n- **Text, logicals and empty cells** in the references follow each kernel's own scan policy,\n  which is not uniform across the eleven: `COUNT` and `COUNTA` differ from each other by exactly\n  this, and that difference is preserved through the dispatch.\n\n\n\n### Errors\n\n\n| Error | Condition | Source |\n|---|---|---|\n| `#VALUE!` | Any reference is a 3-D reference | Documented by Microsoft |\n| `#VALUE!` | `function_num` is outside the documented set | Not documented; plausible, unverified |\n| `#DIV/0!` | The selected kernel is `AVERAGE`, `STDEV`, `VAR` (or their `1xx` forms) and the visible set is too small | Inherited from the kernel; not documented on this page |\n| propagated | An error value in a visible cell surfaces as that error | Shared coercion rules and the module's `ReductionFold` |\n\n\n",
    "sources": "\n- Microsoft, \"SUBTOTAL function\" —\n  <https://support.microsoft.com/en-us/office/subtotal-function-7b027003-f060-4ade-9040-e478765b9939>\n  (signature; the full `function_num` table reproduced above; \"these nested subtotals are ignored\n  to avoid double counting\"; \"The SUBTOTAL function ignores any rows that are not included in the\n  result of a filter, no matter which function_num value you use\"; the vertical-range design\n  note; and \"If any of the references are 3-D references, SUBTOTAL returns the #VALUE! error\n  value\").\n- Welford, \"Note on a Method for Calculating Corrected Sums of Squares and Products\",\n  *Technometrics*, 1962 — the stable updating variance recurrence.\n- Chan, Golub & LeVeque, \"Algorithms for Computing the Sample Variance: Analysis and\n  Recommendations\", *The American Statistician*, 1983 — the comparison of variance formulations.\n- Higham, *Accuracy and Stability of Numerical Algorithms* — summation and variance error bounds.\n- Handbook projections `data/functions/FUNC.SUBTOTAL.json` (arity 2-255,\n  `host_interaction_class: WorkbookState`, `thread_safety_class: HostSerialized`,\n  `determinism_class: Deterministic`, `volatility_class: NonVolatile`,\n  `error_collapse_profile: ReductionFold`, `numerical_reduction_policy=SequentialLeftFold`,\n  `arg_preparation_profile: RefsVisibleInAdapter`) and `data/presence/FUNC.SUBTOTAL.json` (module\n  shared with `FUNC.AGGREGATE`).\n- Handbook [Coercion and lifting](../model/02-coercion-and-lifting.md) and\n  [The value universe](../model/01-value-universe.md).\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`SUBTOTAL(function_num, ref1, [ref2], ...)` applies one of eleven aggregate functions to its\nreferences, with two structural behaviours layered on top:\n\n    SUBTOTAL(f, R) = A_f ( { v in R : v is visible under the active policy,\n                             and v is not itself part of a nested SUBTOTAL result } )\n\nwhere `A_f` is the aggregate selected by `function_num`.\n\n**The dispatch table**, exactly as Microsoft documents it:\n\n| `function_num` (includes hidden rows) | `function_num` (ignores hidden rows) | Function |\n|---|---|---|\n| 1 | 101 | `AVERAGE` |\n| 2 | 102 | `COUNT` |\n| 3 | 103 | `COUNTA` |\n| 4 | 104 | `MAX` |\n| 5 | 105 | `MIN` |\n| 6 | 106 | `PRODUCT` |\n| 7 | 107 | `STDEV` |\n| 8 | 108 | `STDEVP` |\n| 9 | 109 | `SUM` |\n| 10 | 110 | `VAR` |\n| 11 | 111 | `VARP` |\n\n`SUBTOTAL` has no mathematics of its own. Everything numerical about it is inherited from the\nkernel it selects, and the eleven kernels span three quite different numerical characters: plain\nreductions (`SUM`, `PRODUCT`, `MAX`, `MIN`, counting), a ratio (`AVERAGE`), and the four\nsecond-moment functions (`STDEV`, `STDEVP`, `VAR`, `VARP`) whose stability is a research topic in\nits own right. That heterogeneity is the point of the *Numerical notes* below.\n\n**The two structural behaviours** are what actually make `SUBTOTAL` different from calling the\naggregate directly:\n\n1. **Nested subtotals are excluded.** \"If there are other subtotals within ref1, ref2,… (or\n   nested subtotals), these nested subtotals are ignored to avoid double counting.\" This is what\n   permits the classic layout — a grand total that spans a column already containing group\n   subtotals — to be written without arithmetic gymnastics. It is a self-referential rule: the\n   function inspects the *formulas* in its reference range, not merely their values.\n2. **Invisible rows may be excluded**, on two different and independently specified axes. See\n   below.\n\n\n\n### Arguments\n\n\n| Argument | Meaning | Default |\n|---|---|---|\n| `function_num` | The aggregate selector, from the table above. Required. | — |\n| `ref1` | The first range to aggregate. Required. | — |\n| `ref2, ...` | Further ranges. Optional. | — |\n\nThe commonly misunderstood position is `function_num`, and specifically the belief that the\n`1xx` codes are \"the same but better\". They are not the same: they differ on manually hidden\nrows and agree on everything else. Choosing between them is choosing a policy about hidden data,\nand the right choice depends on why the rows are hidden.\n\n"
  },
  "signature": {
    "display": "SUBTOTAL(function_num, ref1, [ref2], ...)",
    "parameters": [
      {
        "description": null,
        "name": "function_num",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "ref1",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "ref2",
        "optional": true,
        "repeats": true
      }
    ],
    "trailing_repeats": true
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "implemented",
        "reason": null
      },
      "arity": {
        "max": 255,
        "min": 2
      },
      "category": "Math and trigonometry functions",
      "classification": {
        "arg_preparation_profile": "RefsVisibleInAdapter",
        "coercion_lift_profile": "Custom",
        "determinism_class": "Deterministic",
        "error_collapse_profile": "ReductionFold",
        "fec_dependency_profile": "Composite",
        "host_interaction_class": "WorkbookState",
        "kernel_signature_class": "Custom",
        "rich_value_usage": "RichBlind",
        "surface_fec_dependency_profile": "Composite",
        "thread_safety_class": "HostSerialized",
        "volatility_class": "NonVolatile"
      },
      "descriptions": {
        "long": null,
        "short": "A summary (sum, count, average and more) of a range that skips nested subtotals",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Returns a subtotal in a list or database",
        "microsoft_url": "https://support.microsoft.com/en-us/office/subtotal-function-7b027003-f060-4ade-9040-e478765b9939"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "SUBTOTAL"
        },
        {
          "locale": "bg-BG",
          "name": "SUBTOTAL"
        },
        {
          "locale": "cs-CZ",
          "name": "SUBTOTAL"
        },
        {
          "locale": "da-DK",
          "name": "SUBTOTAL"
        },
        {
          "locale": "de-DE",
          "name": "SUBTOTAL"
        },
        {
          "locale": "el-GR",
          "name": "SUBTOTAL"
        },
        {
          "locale": "en-AU",
          "name": "SUBTOTAL"
        },
        {
          "locale": "en-GB",
          "name": "SUBTOTAL"
        },
        {
          "locale": "en-US",
          "name": "SUBTOTAL"
        },
        {
          "locale": "es-ES",
          "name": "SUBTOTALES"
        },
        {
          "locale": "et-EE",
          "name": "SUBTOTAL"
        },
        {
          "locale": "fi-FI",
          "name": "VÄLISUMMA"
        },
        {
          "locale": "fr-FR",
          "name": "SOUS.TOTAL"
        },
        {
          "locale": "he-IL",
          "name": "SUBTOTAL"
        },
        {
          "locale": "hr-HR",
          "name": "SUBTOTAL"
        },
        {
          "locale": "hu-HU",
          "name": "RÉSZÖSSZEG"
        },
        {
          "locale": "id-ID",
          "name": "SUBTOTAL"
        },
        {
          "locale": "it-IT",
          "name": "SUBTOTAL"
        },
        {
          "locale": "ja-JP",
          "name": "SUBTOTAL"
        },
        {
          "locale": "ko-KR",
          "name": "SUBTOTAL"
        },
        {
          "locale": "lt-LT",
          "name": "SUBTOTAL"
        },
        {
          "locale": "lv-LV",
          "name": "SUBTOTAL"
        },
        {
          "locale": "nb-NO",
          "name": "DELSUM"
        },
        {
          "locale": "nl-NL",
          "name": "SUBTOTAAL"
        },
        {
          "locale": "pl-PL",
          "name": "SUMY.CZĘŚCIOWE"
        },
        {
          "locale": "pt-BR",
          "name": "SUBTOTAL"
        },
        {
          "locale": "pt-PT",
          "name": "SUBTOTAL"
        },
        {
          "locale": "ro-RO",
          "name": "SUBTOTAL"
        },
        {
          "locale": "ru-RU",
          "name": "ПРОМЕЖУТОЧНЫЕ.ИТОГИ"
        },
        {
          "locale": "sk-SK",
          "name": "SUBTOTAL"
        },
        {
          "locale": "sl-SI",
          "name": "SUBTOTAL"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "PODZBIR"
        },
        {
          "locale": "sv-SE",
          "name": "DELSUMMA"
        },
        {
          "locale": "th-TH",
          "name": "SUBTOTAL"
        },
        {
          "locale": "tr-TR",
          "name": "ALTTOPLAM"
        },
        {
          "locale": "uk-UA",
          "name": "SUBTOTAL"
        },
        {
          "locale": "vi-VN",
          "name": "SUBTOTAL"
        },
        {
          "locale": "zh-CN",
          "name": "SUBTOTAL"
        },
        {
          "locale": "zh-HK",
          "name": "SUBTOTAL"
        },
        {
          "locale": "zh-TW",
          "name": "SUBTOTAL"
        }
      ],
      "signature": {
        "display": "SUBTOTAL(function_num, ref1, [ref2], ...)",
        "parameters": [
          {
            "description": null,
            "name": "function_num",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "ref1",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "ref2",
            "optional": true,
            "repeats": true
          }
        ],
        "trailing_repeats": true
      },
      "surface_name": "SUBTOTAL",
      "version_marker": null,
      "xlcall": {
        "code": "344",
        "symbol": "xlfSubtotal"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/subtotal-function-7b027003-f060-4ade-9040-e478765b9939"
  },
  "try_it": {
    "formula": "=SUBTOTAL(9,B2:B4)",
    "inputs": {
      "B2": 1,
      "B3": 2,
      "B4": 3
    }
  },
  "url": "https://handbook.dnacalc.com/functions/SUBTOTAL.html",
  "variants": [],
  "versions": []
}