Text functions
UNICHAR
Matches all 285 recorded answers
Recorded: 285 workbook cells. How we measure this · See the Rust code
Local names in 40 languages
| Language | Name in Excel |
|---|---|
| Arabic | UNICHAR |
| Bulgarian | UNICHAR |
| Czech | UNICHAR |
| Danish | UNICHAR |
| German | UNICHAR |
| Greek | UNICHAR |
| English (Australia) | UNICHAR |
| English (United Kingdom) | UNICHAR |
| English (United States) | UNICHAR |
| Spanish | UNICAR |
| Estonian | UNICHAR |
| Finnish | UNICODEMERKKI |
| French | UNICAR |
| Hebrew | UNICHAR |
| Croatian | UNICHAR |
| Hungarian | UNIKARAKTER |
| Indonesian | UNICHAR |
| Italian | UNICHAR |
| Japanese | UNICHAR |
| Korean | UNICHAR |
| Lithuanian | UNICHAR |
| Latvian | UNICHAR |
| Norwegian | UNICHAR |
| Dutch | UNITEKEN |
| Polish | ZNAK.UNICODE |
| Portuguese (Brazil) | UNICHAR |
| Portuguese (Portugal) | UNICARÁT |
| Romanian | UNICHAR |
| Russian | ЮНИСИМВ |
| Slovak | UNICHAR |
| Slovenian | UNICHAR |
| Serbian (Latin) | UNICHAR |
| Swedish | UNITECKENKOD |
| Thai | UNICHAR |
| Turkish | UNICODEKARAKTERİ |
| Ukrainian | UNICHAR |
| Vietnamese | UNICHAR |
| Chinese (Simplified) | UNICHAR |
| Chinese (Hong Kong) | UNICHAR |
| Chinese (Traditional) | UNICHAR |
Names from Microsoft's support site.
What it does
UNICHAR(number)
UNICHAR maps a number to the text consisting of the single Unicode character with that code
point.
Precisely: given a number n, truncate it to an integer, interpret that integer as a Unicode code
point, and return a one-character string containing it. "One character" here means one Unicode
scalar value — which, in the UTF-16 code-unit model this Handbook uses for worksheet text (see
the value universe), is two code units when the code point is
outside the Basic Multilingual Plane. So UNICHAR(128512) is one character but occupies two code
units, and functions that count code units will say so.
The interesting part of UNICHAR is not the mapping, which is trivial, but the domain. Three
regions of the integer line behave differently and the distinction is the whole function:
- Valid scalar values —
1through0xD7FFand0xE000through0x10FFFF. These are the code points that can be encoded in UTF-16 and stored in a worksheet string. - Surrogate code points —
0xD800through0xDFFF. These are not characters. They exist only as the two halves of a UTF-16 surrogate pair, and asking for one on its own is a request for half a character. Whether Excel refuses this or produces an unpaired surrogate is exactly the kind of question this Handbook does not answer from memory; see below. - Out of range —
0, negatives, and anything above0x10FFFF. Microsoft's page documents these as errors.
This is why UNICHAR is the right tool for constructing test data. It is the only ordinary way to
write an arbitrary code point into a worksheet from a formula, which makes it the entry point for
probing every other text function's Unicode behaviour.
Arguments
UNICHAR(number)
| Argument | Required | Meaning |
|---|---|---|
number | yes | The Unicode code point, as a number. |
There is only one argument, and only one subtlety in it: it is a number, so text that reads as a
number converts (see coercion and lifting) and TRUE
converts to 1. Fractional values are truncated toward zero rather than rejected — the Handbook
states that as the expected behaviour for this family and lists it below as unverified.
The argument is a code point, not a byte and not a UTF-16 code unit. That distinction is invisible
below 0x10000 and decisive above it.
Try it
Quirks
Result and edge cases
The return kind is Text: a string of one Unicode scalar, which is one or two UTF-16 code units.
UNICHAR is a scalar kernel and lifts elementwise over array arguments; the rules, including
element-local errors, are in coercion and lifting. This is
what makes UNICHAR(SEQUENCE(n) + k) the standard idiom for generating a character sweep, and it
is worth knowing that a single bad element in that sweep yields an error in that cell only, not a
failed call.
Specific edges:
UNICHAR(10)andUNICHAR(13)produce line-break characters, which is the usual reason to reach for this function outside Unicode work — thoughCHARis the more common idiom there.UNICHAR(160)produces the non-breaking space, the characterTRIMdoes not remove. This pairing is the standard repair for web-pasted text.- Errors propagate from the argument ahead of any domain check.
- An empty referenced cell delivers
Empty, which is distinct from an omitted argument; see the value universe.
Errors
Microsoft's page is the authority on the documented error conditions and is linked below; the Handbook could not retrieve it while this entry was written, so this section states expectations to be checked against it rather than quoting it.
| Error | Status |
|---|---|
#VALUE! for number = 0, negative, or above the largest valid code point | expected; confirm against Microsoft's page and by probe |
#VALUE! for text that does not read as a number | expected from the shared to-number coercion rule, not from a function-specific statement |
| any error value, propagated from the argument | follows from the universal error-propagation rule in the coercion chapter |
The status of the surrogate range 0xD800–0xDFFF is not something this page asserts at all. It
is listed as an open probe below.
How to implement
Notes for implementers
- Truncate before validating, and say which you do first.
UNICHAR(65.9)andUNICHAR(-0.5)land differently depending on the order, and the second is the interesting one: truncation toward zero turns-0.5into0, which is documented as an error anyway, but truncation toward negative infinity would give-1. Order matters for the error reason, and may matter for the error at all. - Decide the surrogate policy explicitly. Rust's
char, .NET'sRune, and Python'schrdisagree about lone surrogates: two of them refuse, one produces them. Whichever your host language does by default will silently become yourUNICHARbehaviour if you do not intervene. - Do not route through UTF-8 and back. A round trip through a UTF-8 string type will reject or mangle exactly the inputs whose behaviour is most in question. Work in UTF-16 code units, which is the model the worksheet uses.
- The result must be able to hold an unpaired surrogate if you decide to admit one, which means your text type cannot be a validated-UTF-8 or validated-UTF-16 string. The value-universe chapter records that ill-formed UTF-16 is a reachable state in Excel by another route (interop truncation splitting a pair), so this is not a hypothetical requirement.
- Lift over arrays. The sweep idiom depends on it.
Rust code
Show the CalcFunc source of this function
Quoted from the public repository DnaCalc/DnaCalc, crates calc-func and calc-fml, at commit 9e1884369a67. Comments are the source's own. A kernel shared with other functions appears once, on its module page.
UNICHAR · 4 lines · calc-func/src/catalogue/text_functions.rs on GitHub3 unichar_fn "UNICHAR" (1, 1) [V "number"] |s, a, sv| {
let n = num(s, a, 0)?;
out_text(k::unichar(n))
}
unichar · 12 lines · calc-func/src/ported/text_kernels.rs on GitHubpub(crate) fn unichar(n: f64) -> Result<ExcelText, WorksheetErrorCode> {
let n = n.trunc();
if !n.is_finite() || !(1.0..=0x10FFFF as f64).contains(&n) {
return Err(WorksheetErrorCode::Value);
}
let codepoint = n as u32;
if (0xD800..=0xDFFF).contains(&codepoint) {
return Err(WorksheetErrorCode::NA);
}
let scalar = char::from_u32(codepoint).ok_or(WorksheetErrorCode::Value)?;
Ok(text_from_str(&scalar.to_string()))
}
Kernels shared with other functions
text_from_strported/text_kernels
Argument and result plumbing
No implementation has been published with a Handbook test suite for this function.
Version differences
No comparison between specific Excel builds is recorded here yet. This does not establish that all builds behave alike.
Alternatives
Relationships
CHAR— the older, narrower counterpart.CHARtakes a number in a single-byte range and is interpreted through the system character set;UNICHARtakes a Unicode code point directly.CHARis not deprecated and is not superseded byUNICHAR; the two answer different questions, and they agree only over the ASCII range.CODE—CHAR's inverse, and the older counterpart toUNICODE.TEXT,VALUE— unrelated despite the naming; those convert between numbers and formatted representations, not between numbers and code points.- Readers confuse
UNICHAR(65)with"65". It is"A".
Named variants
No named variants are recorded yet.
Suggest a correction or contribute an implementation · For agents