{
  "category": "User defined functions that are installed with add-ins",
  "display_name": "REGISTER.ID",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.REGISTER.ID",
  "implementation_state": {
    "answer_bank": null,
    "detail": "It registers a procedure in a library with the host. DNA Calc recognises the name and calculates no answer.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": false,
    "state": "host",
    "state_label": "Needs a host",
    "summary": "Needs a host that can load code",
    "workbook_corpus": null
  },
  "implementations": [],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.REGISTER.ID.json",
  "name": "REGISTER.ID",
  "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- **[`CALL`](FUNC.CALL.md)** — the consumer of the id and the other member of\n  `call_register_id_family`. The two functions are one mechanism split across two names, and\n  neither page is complete without the other.\n- **`REGISTER`** — the macro-sheet-only registration function that can also publish a function\n  name and argument names into Excel's user interface. Microsoft contrasts the two explicitly,\n  as quoted above. It is not part of this Handbook's worksheet-function catalog.\n- **`UNREGISTER`** — the teardown counterpart, likewise macro-sheet-only.\n- **XLL add-ins** — every function an XLL publishes goes through the same C API registration\n  path. `REGISTER.ID` is that path exposed as a formula, minus the naming.\n- **`EUROCONVERT`** — a category-mate under \"User defined functions that are installed with\n  add-ins\", but a computation rather than a seam.\n\n",
    "how-to-implement": "\n### Notes for implementers\n\n\n- The register-or-lookup duality is the specification. An implementation that always registers\n  will leak bindings across recalculations; one that only looks up cannot bootstrap.\n- The id must be opaque and must not be assumed stable. Any implementation that returns, say, a\n  hash of the arguments is offering a stability guarantee Excel does not make — and workbooks\n  will come to depend on it.\n- `type_text`'s code set is C API vocabulary, not worksheet vocabulary. It must be reproduced,\n  not redesigned. This is shared with `CALL`; the two functions must agree exactly, since a\n  binding made by one is consumed by the other.\n- The `ValuesOnlyPreAdapter` classification (unlike `CALL`'s `RefsVisibleInAdapter`) means\n  registration takes plain values only, which is consistent with all three arguments being\n  strings. See [the call pipeline](../model/03-call-pipeline.md) for what the two profiles\n  mean.\n- Registration mutates host state. `HostSerialized` is the right classification, and any engine\n  running formulas in parallel must respect it.\n\n\n",
    "quirks": "\n### Result and edge cases\n\n\nA register id — an opaque value whose only documented use is as `CALL`'s first argument. The\nHandbook has not characterized its value kind beyond \"something a formula can hold and pass\nalong\"; it should be treated as a token, not as a number to compute with.\n\nThe interesting edges are all about *when* the binding exists:\n\n- **Session scope.** Registration state belongs to the Excel session. What a saved workbook\n  holds is the last computed value, not a live binding.\n- **Recalculation.** The function is recorded as `NonVolatile`, so it is not re-evaluated on\n  every calculation; whether the id it returns remains valid across a session in which the DLL\n  is unloaded is not documented.\n- **`UNREGISTER`.** The teardown counterpart exists as a macro-sheet function. What a\n  previously returned id does after its registration is torn down is not documented.\n\n\n\n### Errors\n\n\nMicrosoft's `REGISTER.ID` page documents no error-value table. As with `CALL`, that absence is\nsubstantive rather than accidental: the interesting failures — a DLL that will not load, an\nentry point that is absent, a signature that does not match — are operating-system and\nloader-level events, and the documentation does not map them onto worksheet error values.\n\nThe Handbook does not know what a missing DLL or a missing entry point returns. That is stated\nas an unknown, not filled in by analogy.\n\n\n",
    "sources": "- Microsoft, \"REGISTER.ID function\" —\n  <https://support.microsoft.com/en-us/office/register-id-function-f8f0af0f-fd66-4704-a0f2-87b27b175b50>\n  (syntax, all three arguments including the ordinal form of `procedure` and the first-letter\n  rule for `type_text`, the \"already registered, you can omit this argument\" remark, the\n  worksheet-versus-`REGISTER` contrast quoted above, and the per-environment syntax note).\n- Microsoft, \"CALL function\" —\n  <https://support.microsoft.com/en-us/office/call-function-32d58445-e646-4ffd-8d5e-b45077a5e995>\n  (the consuming side of the seam and the caution that governs both pages).\n- Handbook `data/presence/FUNC.REGISTER.ID.json` — the implementing module\n  `earlier-implementation/call_register_id_family.rs` and its surface-dispatch entry.\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`REGISTER.ID` is the other half of Excel's native-code seam. Where [`CALL`](FUNC.CALL.md)\ninvokes, `REGISTER.ID` **binds**: it associates a DLL, an entry point and a type signature, and\nreturns an opaque token standing for that binding. It is the only piece of the XLL registration\nmachinery that Microsoft documents as usable from an ordinary worksheet.\n\n\nTwo operations behind one name, and the distinction is the whole function:\n\n1. **If the procedure is not yet registered**, `REGISTER.ID` registers it and returns the new\n   register id.\n2. **If it is already registered**, `REGISTER.ID` returns the existing id.\n\nThat is why `type_text` is optional. Microsoft states it directly: \"If the function or code\nresource is already registered, you can omit this argument.\" So a two-argument call is a pure\n*lookup*, and a three-argument call is *register-or-lookup*. A workbook can therefore call\n`REGISTER.ID` repeatedly without accumulating registrations — it is idempotent in effect, which\nis what makes it safe to put in a cell that recalculates.\n\nThe id itself is opaque and **session-scoped**. It is not a stable identifier: nothing\nguarantees the same value across sessions, machines, or Excel builds. A workbook that saves an\nid and reuses it later is relying on something no documentation promises.\n\n`REGISTER.ID` is also the *narrower* of the two registration functions. Microsoft draws the\nline explicitly: \"REGISTER.ID can be used on worksheets (unlike REGISTER), but you cannot\nspecify a function name and argument names with REGISTER.ID.\" So the trade is worksheet\navailability in exchange for the ability to publish the procedure under a name in Excel's\nfunction list. `REGISTER.ID` binds for `CALL`'s benefit; `REGISTER` binds for the user\ninterface's benefit.\n\n\n\n### Arguments\n\n\n`REGISTER.ID(module_text, procedure, [type_text])` — arity 2 to 3, matching the reference\nengine's recorded arity.\n\n- **`module_text`** (required) — text naming the DLL that contains the function, in Excel for\n  Windows. Resolution follows the operating system's library search, so which file this names\n  is a property of the machine, not of the workbook.\n- **`procedure`** (required) — text naming the function in the DLL. Microsoft adds that \"you\n  can also use the ordinal value of the function from the EXPORTS statement in the\n  module-definition file (.DEF)\". Two kinds of value, one argument slot — the same overload\n  `CALL` carries, and the same source of confusion.\n- **`type_text`** (optional) — text specifying the data type of the return value and of all\n  arguments, with the **first letter specifying the return value**. Omissible only when the\n  procedure is already registered.\n\nMicrosoft also notes that `REGISTER.ID` \"has a slightly different syntax for each operating\nenvironment\", distinguishing Windows and Macintosh. The Handbook has not characterized the\nnon-Windows form.\n\nThe misunderstood position is `type_text`. It is not a description of the function for Excel's\nbenefit — it is the marshalling contract, and it is the reason the seam is dangerous. Because\nthe caller writes it as a string with nothing checking it against the DLL, a wrong `type_text`\nis a memory-safety problem rather than a worksheet error. That risk belongs to the seam as a\nwhole and is set out on the [`CALL`](FUNC.CALL.md) page; it applies from the moment\nregistration happens, not only at invocation.\n\n\n"
  },
  "signature": {
    "display": "REGISTER.ID(module_text, procedure, [type_text])",
    "parameters": [
      {
        "description": null,
        "name": "module_text",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "procedure",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "type_text",
        "optional": true,
        "repeats": false
      }
    ],
    "trailing_repeats": false
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "host",
        "reason": "It registers a procedure in a library with the host. DNA Calc recognises the name and calculates no answer."
      },
      "arity": {
        "max": 3,
        "min": 2
      },
      "category": "User defined functions that are installed with add-ins",
      "classification": {
        "arg_preparation_profile": "ValuesOnlyPreAdapter",
        "coercion_lift_profile": "Custom",
        "determinism_class": "ExternalEventDependent",
        "error_collapse_profile": "None",
        "fec_dependency_profile": "ExternalProvider",
        "host_interaction_class": "ApplicationState",
        "kernel_signature_class": "Custom",
        "rich_value_usage": "RichBlind",
        "surface_fec_dependency_profile": "ExternalProvider",
        "thread_safety_class": "HostSerialized",
        "volatility_class": "NonVolatile"
      },
      "descriptions": {
        "long": null,
        "short": "Identifier of a registered procedure in a code library (DLL)",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Returns the register ID of the specified dynamic link library (DLL) or code resource that has been previously registered",
        "microsoft_url": "https://support.microsoft.com/en-us/office/register-id-function-f8f0af0f-fd66-4704-a0f2-87b27b175b50"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "REGISTER.ID"
        },
        {
          "locale": "bg-BG",
          "name": "REGISTER.ID"
        },
        {
          "locale": "cs-CZ",
          "name": "REGISTER.ID"
        },
        {
          "locale": "da-DK",
          "name": "REGISTER.ID"
        },
        {
          "locale": "de-DE",
          "name": "REGISTER.ID"
        },
        {
          "locale": "el-GR",
          "name": "REGISTER.ID"
        },
        {
          "locale": "en-AU",
          "name": "REGISTER.ID"
        },
        {
          "locale": "en-GB",
          "name": "REGISTER.ID"
        },
        {
          "locale": "en-US",
          "name": "REGISTER.ID"
        },
        {
          "locale": "es-ES",
          "name": "ID.REGISTRO"
        },
        {
          "locale": "et-EE",
          "name": "REGISTER.ID"
        },
        {
          "locale": "fi-FI",
          "name": "REKISTERI.TUNNUS"
        },
        {
          "locale": "fr-FR",
          "name": "REGISTRE.NUMERO*"
        },
        {
          "locale": "he-IL",
          "name": "REGISTER.ID"
        },
        {
          "locale": "hr-HR",
          "name": "REGISTER.ID"
        },
        {
          "locale": "hu-HU",
          "name": "KÜLSŐ.AZONOSÍTÓ"
        },
        {
          "locale": "id-ID",
          "name": "REGISTER.ID"
        },
        {
          "locale": "it-IT",
          "name": "REGISTER.ID"
        },
        {
          "locale": "ja-JP",
          "name": "REGISTER.ID"
        },
        {
          "locale": "ko-KR",
          "name": "REGISTER.ID"
        },
        {
          "locale": "lt-LT",
          "name": "REGISTER.ID"
        },
        {
          "locale": "lv-LV",
          "name": "REGISTER.ID"
        },
        {
          "locale": "nb-NO",
          "name": "REGISTER-ID"
        },
        {
          "locale": "nl-NL",
          "name": "REGISTRATIE.ID"
        },
        {
          "locale": "pl-PL",
          "name": "REJESTR.KOD"
        },
        {
          "locale": "pt-BR",
          "name": "REGISTER.ID"
        },
        {
          "locale": "pt-PT",
          "name": "REGISTER.ID"
        },
        {
          "locale": "ro-RO",
          "name": "REGISTER.ID"
        },
        {
          "locale": "ru-RU",
          "name": "РЕГИСТРАТОР.ИД"
        },
        {
          "locale": "sk-SK",
          "name": "REGISTER.ID"
        },
        {
          "locale": "sl-SI",
          "name": "REGISTER.ID"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "REGISTER.ID"
        },
        {
          "locale": "sv-SE",
          "name": "REGISTRERA.ID"
        },
        {
          "locale": "th-TH",
          "name": "REGISTER.ID"
        },
        {
          "locale": "tr-TR",
          "name": "YAZMAÇ.KODU"
        },
        {
          "locale": "uk-UA",
          "name": "REGISTER.ID"
        },
        {
          "locale": "vi-VN",
          "name": "REGISTER.ID"
        },
        {
          "locale": "zh-CN",
          "name": "REGISTER.ID"
        },
        {
          "locale": "zh-HK",
          "name": "REGISTER.ID"
        },
        {
          "locale": "zh-TW",
          "name": "REGISTER.ID"
        }
      ],
      "signature": {
        "display": "REGISTER.ID(module_text, procedure, [type_text])",
        "parameters": [
          {
            "description": null,
            "name": "module_text",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "procedure",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "type_text",
            "optional": true,
            "repeats": false
          }
        ],
        "trailing_repeats": false
      },
      "surface_name": "REGISTER.ID",
      "version_marker": null,
      "xlcall": {
        "code": "267",
        "symbol": "xlfRegisterId"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/register-id-function-f8f0af0f-fd66-4704-a0f2-87b27b175b50"
  },
  "try_it": {
    "formula": "=REGISTER.ID(\"example.dll\",\"ExampleFunction\",\"J\")",
    "note": "This Excel interface needs a host library. OneCalc cannot load a native library in this preview.",
    "preview_status": "refused"
  },
  "url": "https://handbook.dnacalc.com/functions/REGISTER.ID.html",
  "variants": [],
  "versions": []
}