Functions: BAHTTEXT (#291)
Thai number words with บาท / สตางค์ / ถ้วน, rounded to satang, ล้าน repeating per six digits, ลบ for negatives. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
9f896c1249
commit
35d6c23fd1
|
|
@ -197,7 +197,7 @@ egui frontend is a separate crate, so the UI can be swapped without touching the
|
|||
|
||||
GridCraft is in **alpha**: the core workflow works end to end, but depth, fidelity and file
|
||||
compatibility are still rough. It covers 89% of the Excel ribbon commands in our catalog
|
||||
([`docs/parity-checklist.md`](docs/parity-checklist.md)) and 501 of Excel's 523 worksheet functions
|
||||
([`docs/parity-checklist.md`](docs/parity-checklist.md)) and 502 of Excel's 523 worksheet functions
|
||||
([`docs/function-parity.md`](docs/function-parity.md)); weighted by what Excel users rely on, we
|
||||
estimate it is about 50% ready for real work. Next up: XLSX fidelity on real-world files, very large
|
||||
workbooks and multi-threaded recalc, chart depth, text in every script, and `.xls` import. Stage,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
**Stage: alpha** · next: beta, ~25 points of "ready for real work" and ~160–240 h away
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-10 · **Change:** major (full re-measure against Excel for Mac 16.113.4; restructured to the craftrules progress-docs standard) · **Target:** Microsoft Excel (Microsoft 365)
|
||||
> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-11 · **Change:** minor (worksheet functions 502 / 523) · **Target:** Microsoft Excel (Microsoft 365)
|
||||
|
||||
GridCraft aims at full Microsoft Excel parity, and at being better in places: faster, open (XLSX
|
||||
is the native format), fully scriptable by agents (MCP, control channel, CLI), and on the web.
|
||||
|
|
@ -21,7 +21,7 @@ This page is the summary. The detail is in:
|
|||
|
||||
| Number | Value | Kind |
|
||||
|---|---|---|
|
||||
| **Feature breadth** (weighted) | **~75%** | estimated, anchored on two measurements: ribbon catalog 258 / 290 (89.0%), worksheet functions 501 / 523 (95.8%; 492 working, 94.1%) |
|
||||
| **Feature breadth** (weighted) | **~75%** | estimated, anchored on two measurements: ribbon catalog 258 / 290 (89.0%), worksheet functions 502 / 523 (96.0%; 493 working, 94.3%) |
|
||||
| **Ready for real work** | **~50%** | estimated from written weights (51.6); [target-app-parity.md](docs/target-app-parity.md) |
|
||||
| **Mainstream practitioner** | **~50%** | estimated: typical analyst/finance user, weekly features, × 0.90 interaction × 0.92 stability × 0.88 file exchange; [method](docs/target-app-parity.md#mainstream-practitioner) |
|
||||
| **Essentials user** | **~63%** | estimated: core features only, × 0.92 launch/stability × 0.95 clarity × 0.90 opening sent files; [method](docs/target-app-parity.md#essentials-user) |
|
||||
|
|
@ -74,7 +74,7 @@ collaboration, mobile, AI).
|
|||
| Area | Breadth | Ready | Hours | Doc |
|
||||
|---|---|---|---|---|
|
||||
| Formula language and calculation | ~92% | ~72% | 20–30 | [target-app-parity.md](docs/target-app-parity.md#feature-areas) |
|
||||
| Worksheet functions | 95.8% measured | ~82% | 18–30 | [function-parity.md](docs/function-parity.md) |
|
||||
| Worksheet functions | 96.0% measured | ~82% | 18–30 | [function-parity.md](docs/function-parity.md) |
|
||||
| Editing, navigation, clipboard, fill | ~90% | ~70% | 15–25 | [ui-parity.md](docs/ui-parity.md) |
|
||||
| Cell formatting, styles, conditional formatting | ~95% | ~80% | 8–14 | [target-app-parity.md](docs/target-app-parity.md#feature-areas) |
|
||||
| Sort, filter, tables, validation, outline | ~82% | ~70% | 10–16 | [target-app-parity.md](docs/target-app-parity.md#feature-areas) |
|
||||
|
|
@ -131,6 +131,7 @@ Ranked; estimates in Opus 5.5 agent-hours. Detail and the full beta-gate list in
|
|||
|
||||
| Date | What landed |
|
||||
|---|---|
|
||||
| 2026-10-11 | BAHTTEXT: amounts in Thai words with Baht and Satang (#291) |
|
||||
| 2026-10-10 | Ribbon translated into Japanese, Chinese, Korean, Brazilian Portuguese and Russian with system-language default (#31, #104, #82); CJK/Thai/Hebrew font fallback (#38); clear messages for encrypted and `.xls` files (#17); smooth line charts (#62). Progress docs restructured to the craftrules standard; full re-measure (this page). Initial ribbon key tips (#43), in-place text box editing (#84), copy as HTML table (#36). ODS and XLSB data import (#100, #101); recalc linear in the number of range formulas (#66); RISC-V Linux build; Flatpak repository on Pages; web cell-commit trap fixed |
|
||||
| 2026-10-09 | Community fixes: spill range operator `A1#`, sheet-scoped names, protection refuses locked-cell edits, Insert/Delete Cells adjust references, `DATE(1900,2,29)`, SUMIF sizing, `ROUND` at 15 digits, `_xlpm.` LAMBDA parameters in XLSX, vertical scrollbar, system appearance, border previews; v0.4.0 |
|
||||
| 2026-10-08 | v0.2.0 and v0.3.0 releases; Flatpak, AppImage zsync, branded DMG; desktop log file; DirectX 12 default on Windows |
|
||||
|
|
@ -142,6 +143,7 @@ Ranked; estimates in Opus 5.5 agent-hours. Detail and the full beta-gate list in
|
|||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-10-11 | minor | Worksheet functions 502 / 523 (BAHTTEXT); progress log row |
|
||||
| 2026-10-10 | minor | Readiness-by-audience table with hours to ~95% per audience; full number unchanged (additive weighted sum) |
|
||||
| 2026-10-10 | minor | Added Mainstream practitioner (~50%) and Essentials user (~63%); languages updated for the 10-10 merges (ribbon in ja, zh, ko, pt-BR, ru); localization 5%→10%; full number re-checked (51.6, unchanged) |
|
||||
| 2026-10-10 | minor | Checked against the alpha gate (six core workflows pass): stays alpha |
|
||||
|
|
|
|||
|
|
@ -403,6 +403,88 @@ fn dollar(a: &[Arg], _c: &mut dyn Ctx) -> R<Value> {
|
|||
text_val(if r < 0.0 { format!("(${body})") } else { format!("${body}") })
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
// BAHTTEXT
|
||||
|
||||
const THAI_DIGITS: [&str; 10] = ["ศูนย์", "หนึ่ง", "สอง", "สาม", "สี่", "ห้า", "หก", "เจ็ด", "แปด", "เก้า"];
|
||||
/// Units, tens, hundreds, thousands, ten thousands, hundred thousands.
|
||||
const THAI_PLACES: [&str; 6] = ["", "สิบ", "ร้อย", "พัน", "หมื่น", "แสน"];
|
||||
|
||||
/// Thai words for a group of up to six decimal digits (most significant first); empty for zero.
|
||||
/// One in the tens is สิบ, two is ยี่สิบ, and a final one after higher digits is เอ็ด.
|
||||
fn thai_group(digits: &[u8]) -> String {
|
||||
let n = digits.len();
|
||||
let higher = digits.iter().take(n.saturating_sub(1)).any(|d| *d != 0);
|
||||
let mut out = String::new();
|
||||
for (i, &d) in digits.iter().enumerate() {
|
||||
let place = n - 1 - i;
|
||||
match (place, d) {
|
||||
(_, 0) => {}
|
||||
(0, 1) if higher => out.push_str("เอ็ด"),
|
||||
(1, 1) => out.push_str("สิบ"),
|
||||
(1, 2) => out.push_str("ยี่สิบ"),
|
||||
_ => {
|
||||
out.push_str(THAI_DIGITS.get(d as usize).copied().unwrap_or_default());
|
||||
out.push_str(THAI_PLACES.get(place).copied().unwrap_or_default());
|
||||
}
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// Thai words for a whole number written in decimal digits: groups of six digits, each but the
|
||||
/// last followed by ล้าน (so 10^12 is หนึ่งล้านล้าน).
|
||||
fn thai_number(digits: &str) -> String {
|
||||
let d: Vec<u8> = digits.bytes().filter(u8::is_ascii_digit).map(|b| b - b'0').skip_while(|x| *x == 0).collect();
|
||||
if d.is_empty() {
|
||||
return "ศูนย์".to_string();
|
||||
}
|
||||
let first = match d.len() % 6 {
|
||||
0 => 6,
|
||||
r => r,
|
||||
};
|
||||
let mut out = String::new();
|
||||
let mut start = 0;
|
||||
let mut len = first;
|
||||
while let Some(group) = d.get(start..start + len) {
|
||||
out.push_str(&thai_group(group));
|
||||
start += len;
|
||||
len = 6;
|
||||
if start < d.len() {
|
||||
out.push_str("ล้าน");
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// BAHTTEXT(number): the amount in Thai words with บาท, rounded to satang (สตางค์); a whole
|
||||
/// number of baht ends in ถ้วน and a negative amount starts with ลบ.
|
||||
fn bahttext(a: &[Arg], _c: &mut dyn Ctx) -> R<Value> {
|
||||
let x = round_half_away(num(a, 0)?, 2);
|
||||
if !x.is_finite() {
|
||||
return Err(CellError::Num);
|
||||
}
|
||||
let fixed = format!("{:.2}", x.abs());
|
||||
let (whole, frac) = fixed.split_once('.').unwrap_or((fixed.as_str(), "00"));
|
||||
let baht = whole.bytes().any(|b| b != b'0');
|
||||
let satang = frac.bytes().any(|b| b != b'0');
|
||||
let mut out = String::new();
|
||||
if x < 0.0 && (baht || satang) {
|
||||
out.push_str("ลบ");
|
||||
}
|
||||
if baht || !satang {
|
||||
out.push_str(&thai_number(whole));
|
||||
out.push_str("บาท");
|
||||
}
|
||||
if satang {
|
||||
out.push_str(&thai_number(frac));
|
||||
out.push_str("สตางค์");
|
||||
} else {
|
||||
out.push_str("ถ้วน");
|
||||
}
|
||||
text_val(out)
|
||||
}
|
||||
|
||||
fn t_fn(a: &[Arg], _c: &mut dyn Ctx) -> R<Value> {
|
||||
match scalar(arg(a, 0)?) {
|
||||
Value::Text(t) => Ok(Value::Text(t)),
|
||||
|
|
@ -762,6 +844,7 @@ pub(crate) fn specs() -> Vec<FnSpec> {
|
|||
fixed
|
||||
),
|
||||
f!("DOLLAR", 1, 2, Text, S, "DOLLAR(number, [decimals])", "Formats a number as currency text.", dollar),
|
||||
f!("BAHTTEXT", 1, 1, Text, S, "BAHTTEXT(number)", "Spells out a number in Thai words with Baht.", bahttext),
|
||||
f!("T", 1, 1, Text, S, "T(value)", "Returns the value if it is text, otherwise empty text.", t_fn),
|
||||
f!(
|
||||
"TEXTBEFORE",
|
||||
|
|
@ -856,6 +939,30 @@ mod tests {
|
|||
|
||||
use crate::util::testutil::*;
|
||||
|
||||
#[test]
|
||||
fn bahttext() {
|
||||
let bt = |x: f64| ev("BAHTTEXT", vec![n(x)]);
|
||||
// Microsoft's example.
|
||||
is_text(bt(1234.0), "หนึ่งพันสองร้อยสามสิบสี่บาทถ้วน");
|
||||
// Tens, เอ็ด, satang, millions and beyond, sign and rounding to satang.
|
||||
is_text(bt(0.0), "ศูนย์บาทถ้วน");
|
||||
is_text(bt(21.25), "ยี่สิบเอ็ดบาทยี่สิบห้าสตางค์");
|
||||
is_text(bt(0.5), "ห้าสิบสตางค์");
|
||||
is_text(bt(101.0), "หนึ่งร้อยเอ็ดบาทถ้วน");
|
||||
is_text(bt(1_000_000.0), "หนึ่งล้านบาทถ้วน");
|
||||
is_text(bt(11_000_000.0), "สิบเอ็ดล้านบาทถ้วน");
|
||||
is_text(bt(2_000_005_000_000.0), "สองล้านห้าล้านบาทถ้วน");
|
||||
is_text(bt(1e12), "หนึ่งล้านล้านบาทถ้วน");
|
||||
is_text(bt(-15.5), "ลบสิบห้าบาทห้าสิบสตางค์");
|
||||
is_text(bt(1.999), "สองบาทถ้วน");
|
||||
is_text(bt(0.005), "หนึ่งสตางค์");
|
||||
is_text(bt(-0.001), "ศูนย์บาทถ้วน");
|
||||
is_err(ev("BAHTTEXT", vec![t("abc")]), CellError::Value);
|
||||
// Huge numbers give text (or #NUM! where rounding overflows), never a panic.
|
||||
assert!(matches!(bt(-1e300), Value::Text(_)));
|
||||
assert!(matches!(bt(f64::MAX), Value::Text(_) | Value::Error(CellError::Num)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn concat_family() {
|
||||
is_text(ev("CONCATENATE", vec![t("a"), n(1.5), b(true)]), "a1.5TRUE");
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Function parity: worksheet functions and formulas
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-10 · **Change:** major (created; measured against Microsoft's published Excel function list) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4
|
||||
> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-11 · **Change:** minor (BAHTTEXT added) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4
|
||||
|
||||
Excel's worksheet functions, category by category, against GridCraft's function library. Part of
|
||||
[target-app-parity.md](target-app-parity.md); gaps feed [gaps.md](gaps.md).
|
||||
|
|
@ -12,7 +12,7 @@ Excel's worksheet functions, category by category, against GridCraft's function
|
|||
them), plus 14 text functions the page lists under combined entries (FIND/FINDB, LEFT/LEFTB,
|
||||
LEN/LENB, MID/MIDB, REPLACE/REPLACEB, RIGHT/RIGHTB, SEARCH/SEARCHB), BETA.INV, and COPILOT and
|
||||
PY (Microsoft 365 functions not on that page when fetched).
|
||||
- **Ours (501):** every function spec in `crates/functions/src/*.rs` (`f!("NAME", …)`) plus the
|
||||
- **Ours (502):** every function spec in `crates/functions/src/*.rs` (`f!("NAME", …)`) plus the
|
||||
evaluator's special forms in `crates/calc/src/eval.rs` (`SPECIAL_FUNCTIONS`: IF, IFS, CHOOSE,
|
||||
OFFSET, INDIRECT, INDEX, SUBTOTAL, AGGREGATE, TEXT, LET, LAMBDA, MAP, REDUCE, SCAN, BYROW, BYCOL,
|
||||
MAKEARRAY…), excluding the test-only `ADD2`. Every one is an Excel name.
|
||||
|
|
@ -23,7 +23,7 @@ Excel's worksheet functions, category by category, against GridCraft's function
|
|||
|
||||
## Coverage
|
||||
|
||||
**Measured: 501 / 523 by name (95.8%); 492 / 523 working (94.1%).**
|
||||
**Measured: 502 / 523 by name (96.0%); 493 / 523 working (94.3%).**
|
||||
|
||||
| Category | Excel | Ours | Working | % working | Missing |
|
||||
|---|---|---|---|---|---|
|
||||
|
|
@ -31,7 +31,7 @@ Excel's worksheet functions, category by category, against GridCraft's function
|
|||
| Math and trigonometry | 80 | 79 | 79 | 99% | PERCENTOF |
|
||||
| Financial | 55 | 51 | 51 | 93% | ODDFPRICE, ODDFYIELD, ODDLPRICE, ODDLYIELD |
|
||||
| Engineering | 54 | 54 | 54 | 100% | — |
|
||||
| Text | 50 | 47 | 47 | 94% | BAHTTEXT, DETECTLANGUAGE, TRANSLATE |
|
||||
| Text | 50 | 48 | 48 | 96% | DETECTLANGUAGE, TRANSLATE |
|
||||
| Lookup and reference | 40 | 36 | 36 | 90% | GETPIVOTDATA, IMAGE, RTD, TRIMRANGE |
|
||||
| Compatibility | 40 | 40 | 40 | 100% | — |
|
||||
| Date and time | 25 | 25 | 25 | 100% | — |
|
||||
|
|
@ -42,9 +42,9 @@ Excel's worksheet functions, category by category, against GridCraft's function
|
|||
| Web | 3 | 3 | 1 | 33% | (WEBSERVICE, FILTERXML are stubs; ENCODEURL works) |
|
||||
| Add-in and Automation | 3 | 0 | 0 | 0% | CALL, EUROCONVERT, REGISTER.ID |
|
||||
| AI and Python | 2 | 0 | 0 | 0% | COPILOT, PY |
|
||||
| **Total** | **523** | **501** | **492** | **94.1%** | 22 missing, 9 stubs |
|
||||
| **Total** | **523** | **502** | **493** | **94.3%** | 21 missing, 9 stubs |
|
||||
|
||||
By the Excel version that introduced them (working / total): before 2010 342 / 360, 2010
|
||||
By the Excel version that introduced them (working / total): before 2010 343 / 360, 2010
|
||||
56 / 56, 2013 49 / 51, 2016 1 / 5, 2019 6 / 6, 2021 11 / 11, 2024 22 / 23, Microsoft 365 5 / 11.
|
||||
Dynamic-array and LAMBDA-era functions (FILTER, SORT, UNIQUE, XLOOKUP, VSTACK, TAKE, GROUPBY,
|
||||
PIVOTBY, REGEXTEST…) are all present.
|
||||
|
|
@ -56,7 +56,7 @@ PIVOTBY, REGEXTEST…) are all present.
|
|||
| FORECAST.ETS family (4) | yes | 4–6 h | AAA exponential smoothing with seasonality detection; needed for Forecast Sheet too |
|
||||
| ODDFPRICE, ODDFYIELD, ODDLPRICE, ODDLYIELD | yes | 2–4 h | Odd first/last period bond maths |
|
||||
| GETPIVOTDATA | yes | 2–3 h | Needs the pivot engine's result cache; also the "Generate GetPivotData" option |
|
||||
| TRIMRANGE, PERCENTOF, BAHTTEXT | yes | 1–2 h | TRIMRANGE also implies the `.:` trim-ref operators |
|
||||
| TRIMRANGE, PERCENTOF | yes | 1–2 h | TRIMRANGE also implies the `.:` trim-ref operators |
|
||||
| IMAGE | yes | 3–5 h | Pictures in cells (see PR #105); fetching URLs needs a privacy decision |
|
||||
| EUROCONVERT | yes | 0.5 h | Fixed conversion table |
|
||||
| CUBE* (7), WEBSERVICE, FILTERXML | partly | 4–8 h | FILTERXML can work offline; CUBE needs an OLAP/data-model source |
|
||||
|
|
@ -97,4 +97,5 @@ workbooks; results checked in as data, not Excel files) and fixing what it finds
|
|||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-10-11 | minor | BAHTTEXT added: 502 / 523 by name, 493 working |
|
||||
| 2026-10-10 | major | Created: 501 / 523 by name, 492 working, per category, against Microsoft's published list |
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Gaps
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-10 · **Change:** major (created from the full re-measure against Excel for Mac 16.113.4 and the issue tracker) · **Target:** Microsoft Excel (Microsoft 365)
|
||||
> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-11 · **Change:** minor (§15: BAHTTEXT landed) · **Target:** Microsoft Excel (Microsoft 365)
|
||||
|
||||
Every known shortfall against Excel, one entry each, ranked by user impact (what blocks someone
|
||||
using GridCraft for real work first). This is the work list: pick from the top, check the open
|
||||
|
|
@ -106,7 +106,7 @@ No alpha blockers: every core workflow passes the [alpha gate](roadmap.md#alpha-
|
|||
#143). **Estimate:** 12–20 h.
|
||||
|
||||
### 15. Remaining functions and an oracle suite (F)
|
||||
- 22 missing, 9 stubs; no Excel-computed oracle corpus; #137, #138. **Estimate:** 18–30 h.
|
||||
- 21 missing, 9 stubs; no Excel-computed oracle corpus; #137, #138. **Estimate:** 18–30 h.
|
||||
[function-parity.md](function-parity.md)
|
||||
|
||||
### 16. Collaboration and review (F)
|
||||
|
|
@ -149,6 +149,7 @@ No alpha blockers: every core workflow passes the [alpha gate](roadmap.md#alpha-
|
|||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-10-11 | minor | §15: BAHTTEXT added (21 functions missing) |
|
||||
| 2026-10-10 | minor | Updated for the 10-10 merges (#17, #31, #38, #62, #82, #104, #116) and the new chart resize bug (#190) |
|
||||
| 2026-10-10 | minor | Noted that no gap blocks the alpha gate |
|
||||
| 2026-10-10 | major | Created: 24 ranked gaps with evidence, from the full re-measure and the 60 open issues |
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Target-app parity: GridCraft vs Microsoft Excel
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-10 · **Change:** major (first full assessment; re-measure against Excel for Mac 16.113.4, replacing the estimates that lived in ROADMAP.md) · **Target:** Microsoft Excel (Microsoft 365)
|
||||
> **Last reviewed:** 2026-10-11 · **Last updated:** 2026-10-11 · **Change:** minor (worksheet functions 502 / 523: BAHTTEXT) · **Target:** Microsoft Excel (Microsoft 365)
|
||||
|
||||
This is the authoritative parity assessment. [`ROADMAP.md`](../ROADMAP.md) summarizes it,
|
||||
[`gaps.md`](gaps.md) lists every shortfall, and the area checklists hold the detail:
|
||||
|
|
@ -14,7 +14,7 @@ generated ribbon checklist is [`parity-checklist.md`](parity-checklist.md).
|
|||
|---|---|---|
|
||||
| Feature breadth (weighted by use) | **~75%** | estimated from the area table below; anchored on two measurements |
|
||||
| Ribbon and menu catalog | **258 / 290 (89.0%)** | measured: `cargo xtask parity` (`crates/engine/src/catalog.rs` ∩ registered command ids) |
|
||||
| Worksheet functions, by name | **501 / 523 (95.8%)** | measured: registered functions vs Microsoft's published function list (method below) |
|
||||
| Worksheet functions, by name | **502 / 523 (96.0%)** | measured: registered functions vs Microsoft's published function list (method below) |
|
||||
| Worksheet functions that do real work | **492 / 523 (94.1%)** | measured: excludes 9 stubs (7 CUBE functions, WEBSERVICE, FILTERXML) |
|
||||
| **Ready for real work** | **~50%** | estimated; written weights below (51.6 computed) |
|
||||
| **Mainstream practitioner** | **~50%** | estimated; [method](#mainstream-practitioner) (69.5 depth × 0.90 × 0.92 × 0.88 = 50.6) |
|
||||
|
|
@ -53,7 +53,7 @@ long `.xls` track, so about half parallelizes (≈30–50 wall-clock hours with
|
|||
LEFT/LEFTB, LEN/LENB, MID/MIDB, REPLACE/REPLACEB, RIGHT/RIGHTB, SEARCH/SEARCHB, BETA.INV) and
|
||||
COPILOT and PY: **523 functions**. Ours: every `f!(…)` spec in `crates/functions/src/*.rs` plus
|
||||
`SPECIAL_FUNCTIONS` in `crates/calc/src/eval.rs` (evaluator special forms), minus the test-only
|
||||
`ADD2`: **501**, all of them Excel names.
|
||||
`ADD2`: **502**, all of them Excel names.
|
||||
- **Ribbon catalog:** `crates/engine/src/catalog.rs` (290 unique ids across 15 tabs) against the
|
||||
313 command ids registered in `crates/engine/src/cmd/*.rs`, recomputed from source by script and
|
||||
identical to the committed `parity-checklist.md`. The catalog is our own transcription of
|
||||
|
|
@ -80,7 +80,7 @@ performance 8, stability 8, localization 4, hardware 2, platforms 2, ecosystem 2
|
|||
| Area | Weight | Breadth | Ready | Hours | Evidence |
|
||||
|---|---|---|---|---|---|
|
||||
| Formula language and calculation | 18 | ~92% | ~72% | 20–30 | A1/R1C1 parser, reference adjustment, dependency-graph recalc, dynamic arrays and `#SPILL!`, `A1#`, LET/LAMBDA and helpers, structured references, names, 3-D references. Open correctness bugs: 15-digit equality (#57), stale spills after structural edits and cleared blockers (#133, #139), 3-D span endpoint deletion (#140), sheet rename and qualified names (#134). Single-threaded |
|
||||
| Worksheet functions | 12 | 95.8% (measured) | ~82% | 18–30 | 501 / 523 names, 492 working. Missing: FORECAST.ETS family, ODDF*/ODDL*, GETPIVOTDATA, TRIMRANGE, PERCENTOF, BAHTTEXT, IMAGE plus cloud functions. No conformance suite against Excel-computed oracles; edge-case bugs keep surfacing (#137, #138). [function-parity.md](function-parity.md) |
|
||||
| Worksheet functions | 12 | 96.0% (measured) | ~82% | 18–30 | 502 / 523 names, 493 working. Missing: FORECAST.ETS family, ODDF*/ODDL*, GETPIVOTDATA, TRIMRANGE, PERCENTOF, IMAGE plus cloud functions. No conformance suite against Excel-computed oracles; edge-case bugs keep surfacing (#137, #138). [function-parity.md](function-parity.md) |
|
||||
| Editing, navigation, clipboard, fill | 12 | ~90% | ~70% | 15–25 | Point mode, F4, AutoComplete, Paste Special, AutoFill, Flash Fill, Find/Replace, Go To Special. Bugs: rectangular drag-select (#28), monthly fill (#132), cut across sheets (#128), Insert Copied Cells missing (#21), key tips only on part of the Home tab (#43; #33, #49). [ui-parity.md](ui-parity.md) |
|
||||
| Cell formatting, styles, conditional formatting | 10 | ~95% | ~80% | 8–14 | Full number-format language, borders, 47 cell styles, 60 table styles, all CF rule kinds including data bars, colour scales and icon sets. Gaps: font weights beyond regular/bold (#168), system fonts list (#4), themes |
|
||||
| Sort, filter, tables, validation, outline | 8 | ~82% | ~70% | 10–16 | Multi-level sort, AutoFilter, Advanced Filter, tables with totals, validation, outline, subtotals, consolidate. Bugs: subtotal header (#131), validation edits (#129), table style panic caught (#130); no slicers on tables |
|
||||
|
|
@ -277,7 +277,7 @@ The inventory carried over from the 2026-10-07 ROADMAP.md, updated for what land
|
|||
- Engine: A1/R1C1 formula parser with reference adjustment, dependency-graph recalculation with
|
||||
dynamic arrays (spill + `#SPILL!`), cycle detection, LET/LAMBDA/MAP/REDUCE/SCAN/BYROW/BYCOL/
|
||||
MAKEARRAY, structured table references, defined names, INDIRECT/OFFSET/INDEX references,
|
||||
501 worksheet functions (478 at M0) (math, statistics and distributions, text and regex, lookup incl.
|
||||
502 worksheet functions (478 at M0) (math, statistics and distributions, text and regex, lookup incl.
|
||||
XLOOKUP/FILTER/SORT/UNIQUE/VSTACK, dates, financial incl. bonds, engineering incl. complex
|
||||
numbers and Bessel, database, information).
|
||||
- Number formats: Excel's full format-code language (sections, conditions, colours, dates and
|
||||
|
|
@ -332,6 +332,7 @@ The inventory carried over from the 2026-10-07 ROADMAP.md, updated for what land
|
|||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-10-11 | minor | Worksheet functions 502 / 523 (96.0%; 493 working): BAHTTEXT |
|
||||
| 2026-10-10 | minor | Readiness-by-audience table: hours to ~95% for each of the three numbers (full 650–1,050, mainstream 200–310, essentials 60–100). Full number confirmed as the additive weighted sum over the written dimension weights (no change) |
|
||||
| 2026-10-10 | minor | Added Mainstream practitioner (~50%) and Essentials user (~63%) with written weights and discounts, and user-evidence counts; re-checked the full number after the 10-10 merges (charts 38→30, localization 5→10; still 51.6, ~50%) |
|
||||
| 2026-10-10 | minor | Stage checked against the new alpha gate (six core workflows, all pass): stays alpha |
|
||||
|
|
|
|||
Loading…
Reference in New Issue