From 229df9213cefda351bba82c12b3a3187ce657f60 Mon Sep 17 00:00:00 2001
From: Claude
Date: Mon, 5 Oct 2026 00:17:15 +0000
Subject: [PATCH 1/3] Read an error code held in a cell as the error itself
(#226)
A cell holding #N/A, #DIV/0!, #VALUE!, #REF!, #NAME?, #NUM! or #NULL! as a
value was text, so SUM stepped over it to a clean-looking total and
IFERROR let it through. literalValue now reads the exact code as the error,
which covers every way in at once: typing, pasting, opening a file's
t="e" cells, and the codes a pivot writes for a group's error.
A leading apostrophe, the Text format, and text that only starts with #
stay text, and a file's string cell reading "#N/A" keeps its apostrophe on
import, as before. Export now takes the error from literalValue instead of
a second list of codes.
Constant error cells leave the open report (#227): the app keeps them
whole now, so nothing about them is lost.
Recount to 1984 tests in 141 files; retake picture 27 and the social card.
Co-Authored-By: Claude Opus 5.5
Claude-Session: https://claude.ai/code/session_013pmWZsbmugfpqtYazrzfjj
---
README.en.md | 37 ++++----
README.md | 37 ++++----
public/screenshots/27-landing-stats.png | Bin 62735 -> 63822 bytes
public/screenshots/en/27-landing-stats.png | Bin 60352 -> 61304 bytes
public/screenshots/screenshots.json | 4 +-
public/social-preview.png | Bin 109968 -> 110645 bytes
src/app/opengraph-image.tsx | 2 +-
src/i18n/en.ts | 5 +-
src/i18n/th.ts | 4 +-
src/lib/cellLiteral.test.ts | 22 ++++-
src/lib/cellLiteral.ts | 18 +++-
src/lib/dataSources/jsonToTable.ts | 3 +-
src/lib/excelIO.ts | 15 ++--
src/lib/fileLosses.test.ts | 14 +---
src/lib/fileLosses.ts | 35 +-------
src/store/errorLiterals.test.ts | 93 +++++++++++++++++++++
16 files changed, 192 insertions(+), 97 deletions(-)
create mode 100644 src/store/errorLiterals.test.ts
diff --git a/README.en.md b/README.en.md
index a09dc712..51d07965 100644
--- a/README.en.md
+++ b/README.en.md
@@ -44,7 +44,7 @@ right here, with the URL, the header and the data never passing through our serv
-
+
@@ -65,7 +65,7 @@ self-hosted, straight from PostgreSQL/MySQL — one saved read-only query, and n
and full-fidelity Excel/PDF export, where a chart exported to `.xlsx` is a real, editable chart
bound to its cells, because the OOXML chart parts are written by hand (ExcelJS writes none). Plus optional
bring-your-own-backend cloud save and live co-editing over it — presence, last-writer-wins with the loser told, and
-an undo that does not erase the other person's work. Bilingual UI (Thai/English), 1979 automated tests.
+an undo that does not erase the other person's work. Bilingual UI (Thai/English), 1984 automated tests.
---
@@ -109,7 +109,7 @@ Want the harder parts: [embedding a Thai font in the PDF, with stacked tone mark
---
-### 🧪 What 1979 passing tests could not catch
+### 🧪 What 1984 passing tests could not catch
Every test of the assistant **mocks the model** — it returns what I imagined it would. Put a real
API key behind it, ask fourteen ordinary questions, and **six answers used functions this engine
@@ -120,7 +120,7 @@ Then **the first fix made it worse.** The rule started as "give the closest form
allows", so _"join all the names into one line"_ came back as `=SUM(A2:A20)` — `0` in the cell, no
error, nothing to notice. **A visible `#NAME?` traded for an invisible wrong number.**
-**And it happened again, in a different place.** With every gate green — 1979 tests, `axe` clean on
+**And it happened again, in a different place.** With every gate green — 1984 tests, `axe` clean on
both pages at two widths — an hour of clicking through the public build the way a first-time visitor
would found three things no gate can see:
@@ -395,7 +395,7 @@ Other available commands:
| `npm run build` | Build a production bundle |
| `npm run start` | Run the production build (run `npm run build` first) |
| `npm run lint` | Check code quality with ESLint |
-| `npm test` | Run the 1979-case Vitest suite |
+| `npm test` | Run the 1984-case Vitest suite |
| `npm run check:readme` | Check the READMEs still match the code (links/images/test count/new modules/both languages) |
| `npm run check:screens` | Figures printed on a screenshot still match the source |
| `npm run check:rls` | Two real accounts against your own Supabase: does the database refuse what the policies say it should (needs env) |
@@ -1253,6 +1253,7 @@ share one rule (`src/lib/cellLiteral.ts`), in this order:
| A cell formatted as **Text** (number format menu · Excel's `@`) | `123` | text — for a whole column of codes |
| An integer with a leading zero | `0812345678`, `00123` | text, automatically (`0` and `0.5` are still numbers) |
| Twelve digits or more, nothing else | `1234567890123` | text, automatically (eleven digits or fewer, or with a point or sign, are numbers) |
+| An error code as Excel spells it (#226) | `#N/A`, `#DIV/0!` | **the error value**, as in Excel — `#1` or `#N/A please` stay text |
| A number as a screen shows it — commas at the thousands, a trailing `%`, or a currency sign in front (#52) | `1,250`, `12%`, `฿1,500.00` | **a number** — `12%` is 0.12 (as #53 stores it) · the cell shows what was typed |
| Everything else | `-3`, `12.50`, `10000000000` | a number, as before |
@@ -2518,7 +2519,6 @@ package again as it opens and **says so before anything is edited**: what, how m
| Excel PivotTables | values only | static numbers, not a PivotTable |
| Formulas calling a function the engine lacks | `#NAME?` | **the formula is kept**, and Excel calculates it |
| Range names that cannot come in (a formula, a whole column, several areas, or a sheet the file lacks) | formulas using them read `#NAME?` | the name is lost; formulas still carry it |
-| Cells holding a constant error value (`#DIV/0!`, `#N/A`) | shown as the text of the code; a formula that reads one does not see an error, so `SUM` steps over it (until [#226](https://github.com/SuruchBoss/ExcelToGo/issues/226)) | **written back as the error value** |
| External links to other files | values do not update | lost |
| Macros (VBA) | not run | lost |
@@ -2526,8 +2526,8 @@ package again as it opens and **says so before anything is edited**: what, how m
- **A plain file sees nothing.** The report comes up only when something is actually lost.
- **A constant error cell used to open blank, with nothing said** (#227), and a total over it read as a clean number. It now
- keeps its code and goes back out as the error it was. An error code typed as Excel spells it (`#N/A`, `#DIV/0!`) also
- goes out as the error, as Excel would store it; a leading apostrophe or the Text format keeps it text.
+ opens as the error value itself (#226), so a formula that reads it sees an error as in Excel, and it goes back out as
+ the error it was. Nothing about it is lost, so it is no longer in this report.
- **Got it** closes it. It opens again from the **menu** (or the amber button beside Export Excel from 1366px) for as long
as the file's sheets are open; undoing the open, or opening another file over it, takes the report away too.
- It reads the original package, not what the importer returned, because what the importer returned is exactly what
@@ -3023,7 +3023,7 @@ architecture behind it.
| `@anthropic-ai/sdk` | Connects to the Claude API for the AI assistant |
| `lucide-react` | UI icons |
| `clsx` | Conditional className composition |
-| `vitest` | Unit tests for the formula engine, sort logic, JSON-to-table conversion, pagination, rate limiting, templates, file fidelity, conditional formatting and live blocks (1979 cases) |
+| `vitest` | Unit tests for the formula engine, sort logic, JSON-to-table conversion, pagination, rate limiting, templates, file fidelity, conditional formatting and live blocks (1984 cases) |
> **Note:** No off-the-shelf formula library (e.g. HyperFormula) is used — the **formula engine is hand-written**
> (tokenizer, parser, evaluator, and functions) to keep full control over its behavior. See
@@ -3297,7 +3297,7 @@ src/
fillSeries.ts # What dragging the corner continues into — numbers, Thai days and months, quarters, formulas
sheetSearch.ts # Find and replace over the raw text rather than the displayed result
workbookRefs.ts # The formula rewrites that are not a fact about one sheet: cross-sheet shifts, renames
- fileLosses.ts # What an opened file holds that the app can't keep (pictures, charts, PivotTables, macros, links, missing functions, constant error values), read from the package (#83)
+ fileLosses.ts # What an opened file holds that the app can't keep (pictures, charts, PivotTables, macros, links, missing functions), read from the package (#83)
sheetNames.ts # Excel's sheet-name rules in one place: ≤31 chars, no \ / ? * [ ] :, unique ignoring case (#54)
byok.ts # The visitor's own API key: this tab only, masked when shown
sheet.ts # The core sheet data model, whole-sheet computation, applying a formula by scope,
@@ -3708,6 +3708,12 @@ shows as Infinity rather than Excel's `#NUM!`; only `^` and `POWER` were fixed.
Full support for arithmetic/comparison/concatenation operators (`+ - * / ^ = <> < > <= >= &`) and Excel-style
error values: `#DIV/0!`, `#VALUE!`, `#NAME?`, `#N/A`, `#REF!`, `#CIRCULAR!`.
+**An error code held in a cell as a value is the error itself, as in Excel (#226).** `#N/A`, `#DIV/0!`, `#VALUE!`,
+`#REF!`, `#NAME?`, `#NUM!` and `#NULL!` typed into a cell, pasted from Excel, opened from a file or written by a pivot used
+to be text, so `SUM` stepped over them to a clean-looking total and `IFERROR` let them through. Now `SUM` gives the
+error and `IFERROR`/`IFNA` catch it. A leading apostrophe, the Text format, or text that only starts with `#` (`#1`,
+`#N/A please`) stays text, and so does a file's text cell that happens to read `#N/A`, as Excel stores it.
+
Want to add a formula to the drag-and-drop palette? Add the real function in `functions.ts`, then add its entry
plus both languages' text in `formulaCatalog.ts` and `i18n/th.ts`/`en.ts`.
@@ -4063,13 +4069,13 @@ the framework bundle itself, which isn't a trade worth making here. Written down
## 🧪 Testing
```bash
-npm test # 1979 cases across 140 files, via Vitest
+npm test # 1984 cases across 141 files, via Vitest
```
Testing is focused on the **formula engine, sort logic, JSON-to-table conversion, pagination, rate-limit backoff, Excel templates and live-block placement** — pure functions with no React/DOM dependency, so
they run fast and give high confidence.
-**But not one of those 1979 cases opens the app**, and nearly every bug this project found by hand lived in
+**But not one of those 1984 cases opens the app**, and nearly every bug this project found by hand lived in
the wiring *between* pieces that all passed their tests — the toolbar's "+ row" called `addRow`, which
announced nothing, while `insertRowAtSelection` next to it announced correctly (both tested) · the AI
assistant sent a range including its text header, because the context builder read raw `sheet.cells`
@@ -4188,10 +4194,10 @@ once; disable `ArrowRight` in the grid and two assertions in the third fail. (Th
second one stayed green: the `case` I inserted landed *after* the existing `case "ArrowRight"` and was dead
code. Proving a gate means checking that the thing you meant to break actually broke.)
-> **1979 tests passed, and 43% of the assistant's answers were unusable** — because those tests mock
+> **1984 tests passed, and 43% of the assistant's answers were unusable** — because those tests mock
> the model, so it returns what the test author imagined. A test count says what you thought to ask,
> not whether you asked enough. Only a real API key found this: see
-> [What 1979 passing tests could not catch](#-what-1979-passing-tests-could-not-catch), repeatable
+> [What 1984 passing tests could not catch](#-what-1984-passing-tests-could-not-catch), repeatable
> with `npm run check:ai`.
| File | Cases | Tests |
@@ -4232,7 +4238,7 @@ code. Proving a gate means checking that the thing you meant to break actually b
| `sheetNames.test.ts` | 7 | Excel's sheet-name rules (#54): each rule broken, case counted as one name, cleaning a name and finding a free one, + never reusing a name after a delete, an old save's duplicate keeping its formulas on the first tab, an invalid name renamed with its formulas |
| `sheetMerges.test.ts` | 35 | Which cells a merge swallows, shifting merges on row/column insert and delete, dropping one that collapses to a single cell |
| `sheetTemplate.test.ts` | 14 | Which cells are locked vs. fields, inline and range-backed dropdown options, column-width conversion |
-| `fileLosses.test.ts` | 12 | What an opened file can't keep (#83): a real file with a picture, a chart and a function the engine lacks, counted with its sheet; that formula exported as it was; a plain file reporting nothing; `_xlfn.` spelling of a function the engine has not counted; PivotTables, shapes, macros, links and a chart sheet as the spec lays them out; a non-zip not failing the open; range names that cannot come in (#60) as one line of the same report, after the missing functions, the whole report for a file with nothing else, and still said when the package cannot be read again; constant error cells (#227) counted with their sheet while a formula whose result is an error is not, and still counted after an export and a reopen |
+| `fileLosses.test.ts` | 11 | What an opened file can't keep (#83): a real file with a picture, a chart and a function the engine lacks, counted with its sheet; that formula exported as it was; a plain file reporting nothing; `_xlfn.` spelling of a function the engine has not counted; PivotTables, shapes, macros, links and a chart sheet as the spec lays them out; a non-zip not failing the open; range names that cannot come in (#60) as one line of the same report, after the missing functions, the whole report for a file with nothing else, and still said when the package cannot be read again; constant error cells (#227) no longer reported, since the app reads them as the errors they are from #226 |
| `excelIO.test.ts` | 58 | Builds a real .xlsx and round-trips it: reading fields/dropdowns/widths, an unprotected file isn't a template, export→import comes back identical, and styling (fills/font sizes/borders/row heights/merges) round-trips, as do all five kinds of conditional formatting rule and cell notes (both the plain-string and Excel's rich-text form), cross-sheet dropdowns read from the sheet the rule names (quoted names, a hidden sheet, a missing one, and the PaynEat ERP draft-0 template), a column exactly width 9 still 9 after export (#136), a merge in the file holding its value in the top-left cell only with SUM/COUNTA matching Excel and the merge still exported (#55), a real `t="e"` cell opening as its error code rather than blank, going back out as `t="e"` and still there on a reopen, while `'#N/A` and a Text-formatted cell go out as text (#227) |
| `charts.test.ts` | 42 | Reading a range into series and labels (including a text label column), gaps for non-numbers, a zero-anchored axis, moving/resizing/clamping a chart's frame, what the legend names per kind, shifting on edits |
| `server/urlGuard.test.ts` | 31 | Addresses the server refuses to reach (loopback, private ranges, cloud metadata, IPv6 link-local), IPv4 embedded in IPv6 (`::ffff:`, `::`, SIIT, NAT64, 6to4, Teredo), non-http schemes, and the allowlist |
@@ -4259,6 +4265,7 @@ code. Proving a gate means checking that the thing you meant to break actually b
| `store/datePivot.test.ts` | 1 | A pivot by day (#45): its rows are headed with dates, not serials |
| `store/pivotSize.test.ts` | 6 | A summary sheet as big as its answer (#56): all 35 products with the Grand total row in bold, all twelve months with the Grand total column, the same after a refresh, a small result still opening on a 30×10 sheet with room to work, a result too big for a sheet built nowhere and its size said, and a refresh too big for one alerting while the old pivot stays |
| `store/pivotError.test.ts` | 2 | A pivot over a source with an error (#222): Sum, Average, Min and Max of the group holding `#DIV/0!` and the Grand total show `#DIV/0!` while the other group keeps its number, when built and when refreshed after the source gains the error |
+| `store/errorLiterals.test.ts` | 4 | An error code held in a cell as a value is the error (#226), by every way in: typed (`SUM` gives `#DIV/0!`, `IFERROR`/`IFNA` catch it), pasted as Excel copies it (`#1`, `#N/A please`, `'#N/A` stay text), opened from a file (a `t="e"` cell is the error, a string cell reading `#N/A` stays text), and `SUM`/`IFERROR` over a pivot sheet holding an error |
| `store/dateEntry.test.ts` | 5 | Entering a date as a person does (#45): `=TODAY()`/`=DATE()`/`=NOW()` formatted as dates while the cell is General, a date and time widening a default-width column, picking a date format replacing the file's layout |
| `store/convertDates.test.ts` | 5 | "Convert to dates" and "Date (B.E.)" through the store (#82): converted cells show the Buddhist year while unreadable ones and formulas stay, A.D. month-first, one undo for all, a chosen format kept, the B.E. format shown and switched back |
| `store/sampleNotice.test.ts` | 19 | Opening blank, the sample opened by its button and undone, a sample left in the browser (either language) not restored while one edit of any kind makes it work, New file undone and announced, the sample notice only while untouched, and the sample following the language on screen |
diff --git a/README.md b/README.md
index cc721cf9..03acf7bd 100644
--- a/README.md
+++ b/README.md
@@ -40,7 +40,7 @@
-
+
@@ -61,7 +61,7 @@ and saying so when data came back incomplete. A range can be given a name (in Th
what it means, and a cell can carry a rule about what may go in it, refused before it is written rather than
flagged afterwards. Conditional formatting re-colours cells from their current values — comparisons,
top/bottom ranks, colour scales and data bars — and round-trips through Excel's own rule format. Bilingual UI
-(Thai/English), 1979 automated tests. บันทึกบนคลาวด์และการแก้พร้อมกันหลายคนมีให้เลือกใช้ได้ โดยต่อ backend ของคุณเอง
+(Thai/English), 1984 automated tests. บันทึกบนคลาวด์และการแก้พร้อมกันหลายคนมีให้เลือกใช้ได้ โดยต่อ backend ของคุณเอง
---
@@ -106,7 +106,7 @@ top/bottom ranks, colour scales and data bars — and round-trips through Excel'
---
-### 🧪 สิ่งที่เทสต์ 1979 เคสจับไม่ได้
+### 🧪 สิ่งที่เทสต์ 1984 เคสจับไม่ได้
เทสต์ของผู้ช่วย AI ใช้ **mock ทั้งหมด** — มันตอบตามที่ผมคิดว่ามันจะตอบ พอเอา API key จริงมายิงคำถามธรรมดา
14 ข้อ **6 คำตอบใช้ฟังก์ชันที่เอนจินนี้ไม่มี** (`TEXTJOIN` `FIND` `RANK.EQ` `SUMPRODUCT` `CEILING` `CHAR`)
@@ -116,7 +116,7 @@ top/bottom ranks, colour scales and data bars — and round-trips through Excel'
มันจึงตอบคำถาม *"ต่อชื่อทั้งหมดเป็นบรรทัดเดียว"* ด้วย `=SUM(A2:A20)` ซึ่งได้ `0` โดยไม่มีอะไรบอกว่าผิด
**เปลี่ยน error ที่มองเห็น เป็นตัวเลขผิดที่มองไม่เห็น**
-**แล้วมันก็เกิดอีก คนละที่** ตอนที่ทุกด่านเขียวหมด — 1979 เทสต์ผ่าน, `axe` ไม่มี violation ทั้งสองหน้า
+**แล้วมันก็เกิดอีก คนละที่** ตอนที่ทุกด่านเขียวหมด — 1984 เทสต์ผ่าน, `axe` ไม่มี violation ทั้งสองหน้า
ที่สองความกว้าง — ผมลองไล่คลิก build สาธารณะแบบคนที่เพิ่งเข้ามาครั้งแรกอยู่ชั่วโมงหนึ่ง แล้วเจอสามอย่าง
ที่ไม่มีด่านไหนมองเห็น:
@@ -381,7 +381,7 @@ npm run dev
| `npm run build` | build เป็นเวอร์ชัน production |
| `npm run start` | รันเวอร์ชันที่ build แล้ว (ต้อง `npm run build` ก่อน) |
| `npm run lint` | ตรวจสอบคุณภาพโค้ดด้วย ESLint |
-| `npm test` | รัน unit test 1979 เคสด้วย Vitest |
+| `npm test` | รัน unit test 1984 เคสด้วย Vitest |
| `npm run check:readme` | ตรวจว่า README ยังตรงกับโค้ด (ลิงก์/ภาพ/จำนวนเทสต์/โมดูลใหม่/สองภาษาตรงกัน) |
| `npm run check:screens` | ตัวเลขที่พิมพ์อยู่บนภาพหน้าจอยังตรงกับซอร์สไหม |
| `npm run check:rls` | ยิงจริงสองบัญชีบน Supabase ของคุณ ว่าฐานข้อมูลปฏิเสธตามที่ policy เขียนไว้ไหม (ต้องตั้ง env) |
@@ -1118,6 +1118,7 @@ VAT = 0.07 จึงขึ้น "0.07%" ทั้งบนจอและใน
| เซลล์รูปแบบ **ข้อความ** (เมนูรูปแบบตัวเลข · Excel `@`) | `123` | ข้อความ — เหมาะกับทั้งคอลัมน์ที่เป็นรหัส |
| จำนวนเต็มที่มีศูนย์นำหน้า | `0812345678`, `00123` | ข้อความ อัตโนมัติ (`0` กับ `0.5` ยังเป็นตัวเลข) |
| ตัวเลขล้วน 12 หลักขึ้นไป | `1234567890123` | ข้อความ อัตโนมัติ (11 หลักลงมา หรือมีจุด/เครื่องหมาย ยังเป็นตัวเลข) |
+| รหัส error ตรงตามที่ Excel เขียน (#226) | `#N/A`, `#DIV/0!` | **ค่า error** แบบใน Excel — `#1` หรือ `#N/A please` ยังเป็นข้อความ |
| ตัวเลขแบบที่จอแสดง — จุลภาคตรงหลักพัน, `%` ท้าย หรือสัญลักษณ์เงินข้างหน้า (#52) | `1,250`, `12%`, `฿1,500.00` | **ตัวเลข** — `12%` คือ 0.12 (แบบเดียวกับ #53) · จอแสดงตามที่พิมพ์ |
| ที่เหลือ | `-3`, `12.50`, `10000000000` | ตัวเลขเหมือนเดิม |
@@ -2208,16 +2209,14 @@ merge เลื่อนตามการแทรก/ลบแถวและ
| Pivot Table ของ Excel | เห็นแค่ค่า | ค่าเป็นตัวเลขนิ่ง ไม่ใช่ Pivot Table |
| สูตรที่ใช้ฟังก์ชันที่เอนจินไม่มี | ขึ้น `#NAME?` | **สูตรเดิมยังอยู่** เปิดใน Excel แล้วคำนวณได้ |
| ชื่อช่วงที่นำเข้าไม่ได้ (ชื่อที่เป็นสูตร ทั้งคอลัมน์ หลายช่วง หรือชี้ชีตที่ไม่มี) | สูตรที่ใช้ชื่อขึ้น `#NAME?` | ชื่อหายไป สูตรยังถือชื่อนั้นไว้ |
-| เซลล์ที่เก็บค่า error คงที่ (`#DIV/0!`, `#N/A`) | แสดงเป็นข้อความของรหัส สูตรที่อ่านช่องนั้นไม่เห็นว่าเป็น error `SUM` จึงข้ามไป (จนกว่า [#226](https://github.com/SuruchBoss/ExcelToGo/issues/226) จะเข้า) | **เขียนกลับเป็นค่า error เหมือนเดิม** |
| ลิงก์ไปไฟล์อื่น (external links) | ค่าไม่อัปเดต | หายไป |
| มาโคร (VBA) | ไม่รัน | หายไป |

- **ไฟล์ธรรมดาไม่เห็นอะไรเลย** รายงานขึ้นเฉพาะเมื่อเจอของที่เก็บไม่ได้จริง
-- **เซลล์ที่เก็บค่า error คงที่เคยเปิดมาเป็นช่องว่างโดยไม่มีอะไรบอก** (#227) และยอดรวมที่อ่านช่องนั้นออกมาเป็นตัวเลขดูปกติ · ตอนนี้รหัสยังอยู่
- และส่งออกกลับเป็นค่า error เหมือนเดิม · รหัส error ที่พิมพ์ตรงตามที่ Excel เขียน (`#N/A`, `#DIV/0!`) ก็ส่งออกเป็นค่า error แบบที่ Excel เก็บ
- ถ้าขึ้นต้นด้วย `'` หรือจัดรูปแบบเป็นข้อความจะยังเป็นข้อความ
+- **เซลล์ที่เก็บค่า error คงที่เคยเปิดมาเป็นช่องว่างโดยไม่มีอะไรบอก** (#227) และยอดรวมที่อ่านช่องนั้นออกมาเป็นตัวเลขดูปกติ · ตอนนี้เปิดมาเป็นค่า error
+ จริง (#226) สูตรที่อ่านช่องนั้นเห็นเป็น error แบบใน Excel และส่งออกกลับเป็นค่า error เหมือนเดิม จึงไม่อยู่ในรายงานนี้แล้ว
- กด **เข้าใจแล้ว** เพื่อปิด แล้วเปิดดูอีกครั้งได้จาก**เมนู** (หรือปุ่มสีเหลืองข้างปุ่มส่งออก Excel ตั้งแต่ 1366px) ตราบเท่าที่ชีตจากไฟล์นั้นยังเปิดอยู่
· undo การเปิดไฟล์ หรือเปิดไฟล์อื่นทับ รายงานก็หายไปด้วย
- อ่านจาก package ต้นฉบับ ไม่ใช่จากผลของตัวนำเข้า เพราะผลของตัวนำเข้าคือสิ่งที่ของพวกนี้หายไปแล้ว ·
@@ -2631,7 +2630,7 @@ stack ของ `font-mono` จึงต่อท้ายด้วย Plex Sans
| `@anthropic-ai/sdk` | เชื่อมต่อ Claude API สำหรับผู้ช่วย AI |
| `lucide-react` | ไอคอน UI |
| `clsx` | รวม className แบบมีเงื่อนไข |
-| `vitest` | unit test เอนจินคำนวณสูตร, ตรรกะเรียงข้อมูล, แปลง JSON เป็นตาราง, การแบ่งหน้า/rate limit, แม่แบบ/รูปแบบจากไฟล์ และบล็อกข้อมูลสด (1979 เคส) |
+| `vitest` | unit test เอนจินคำนวณสูตร, ตรรกะเรียงข้อมูล, แปลง JSON เป็นตาราง, การแบ่งหน้า/rate limit, แม่แบบ/รูปแบบจากไฟล์ และบล็อกข้อมูลสด (1984 เคส) |
> **หมายเหตุ:** ไม่ได้ใช้ไลบรารีคำนวณสูตรสำเร็จรูป (เช่น HyperFormula) แต่เขียน **เอนจินคำนวณสูตรขึ้นเอง**
> ทั้ง tokenizer, parser, evaluator และฟังก์ชันต่างๆ เพื่อควบคุมพฤติกรรมได้เต็มที่ ดูรายละเอียดที่หัวข้อ
@@ -2891,7 +2890,7 @@ src/
fillSeries.ts # ลากมุมแล้วได้อะไรต่อ — ชุดตัวเลข วันไทย เดือนไทย ไตรมาส และการขยับสูตร
sheetSearch.ts # ค้นหา/แทนที่จากข้อความดิบ ไม่ใช่ผลลัพธ์ที่แสดง
workbookRefs.ts # การแก้สูตรที่ไม่ใช่เรื่องของชีตเดียว — แทรกแถวข้ามชีต และเปลี่ยนชื่อชีต
- fileLosses.ts # ไฟล์ที่เปิดมามีอะไรที่แอปเก็บไว้ไม่ได้ (รูป กราฟ Pivot มาโคร ลิงก์ ฟังก์ชันที่ไม่มี ค่า error คงที่) อ่านจาก package (#83)
+ fileLosses.ts # ไฟล์ที่เปิดมามีอะไรที่แอปเก็บไว้ไม่ได้ (รูป กราฟ Pivot มาโคร ลิงก์ ฟังก์ชันที่ไม่มี) อ่านจาก package (#83)
sheetNames.ts # กติกาชื่อชีตของ Excel ที่เดียว — ≤31 ตัว, ไม่มี \ / ? * [ ] :, ไม่ซ้ำแม้ต่างตัวพิมพ์ (#54)
byok.ts # เก็บ API key ของผู้ใช้ไว้ในแท็บเดียว + ปิดบังตอนแสดงผล
sheet.ts # โมเดลข้อมูลตารางหลัก, คำนวณค่าทั้งชีต, ใส่สูตรตาม scope ต่างๆ, แทรก/ลบแถว-คอลัมน์
@@ -3251,6 +3250,11 @@ error อยู่แล้ว คือ `IF` `IFERROR` `IFNA` `COUNT` `COUNTA`
รองรับตัวดำเนินการคำนวณ/เปรียบเทียบ/ต่อข้อความครบ (`+ - * / ^ = <> < > <= >= &`) และแจ้ง error แบบ Excel:
`#DIV/0!`, `#VALUE!`, `#NAME?`, `#N/A`, `#REF!`, `#CIRCULAR!`
+**รหัส error ที่อยู่ในเซลล์เป็นค่า ก็เป็น error จริงแบบใน Excel (#226)** — `#N/A`, `#DIV/0!`, `#VALUE!`, `#REF!`, `#NAME?`, `#NUM!`
+และ `#NULL!` ที่พิมพ์ลงเซลล์ วางมาจาก Excel เปิดมาจากไฟล์ หรือที่ Pivot เขียนลงชีต เดิมเก็บเป็นข้อความ `SUM` จึงข้ามไปแล้วได้ยอดที่ดูปกติ
+และ `IFERROR` จับไม่ได้ · ตอนนี้ `SUM` ได้ error และ `IFERROR`/`IFNA` จับได้ · ขึ้นต้นด้วย `'` จัดรูปแบบเป็นข้อความ หรือแค่ขึ้นต้นด้วย `#`
+(`#1`, `#N/A please`) ยังเป็นข้อความ · ข้อความในไฟล์ที่บังเอิญเป็น `#N/A` ก็ยังเป็นข้อความตามที่ Excel เก็บ
+
ต้องการสูตรเพิ่มเติมในแถบลากวาง? เพิ่มฟังก์ชันจริงที่ `functions.ts` แล้วเพิ่มรายการ + คำแปล 2 ภาษาที่
`formulaCatalog.ts` + `i18n/th.ts`/`en.ts`
@@ -3528,13 +3532,13 @@ B อ่านและแก้ได้ แต่ยังยึดเป็
## 🧪 การทดสอบ
```bash
-npm test # 1979 เคส ใน 140 ไฟล์ ด้วย Vitest
+npm test # 1984 เคส ใน 141 ไฟล์ ด้วย Vitest
```
โฟกัสเทสต์ไปที่ **เอนจินคำนวณสูตร, ตรรกะเรียงข้อมูล, การแปลง JSON เป็นตาราง, การไล่ดึงหน้าถัดไป, การถอยเมื่อโดน rate limit, แม่แบบจากไฟล์ Excel, กฎจัดรูปแบบตามเงื่อนไข และการวางบล็อกข้อมูลสด** — ส่วนที่เป็น pure function ล้วน ไม่ต้องพึ่ง React/DOM
จึงเทสต์ได้เร็วและมั่นใจได้สูง
-**แต่ 1979 เคสนั้นไม่มีสักเคสที่เปิดแอป** และบั๊กที่โปรเจกต์นี้เจอด้วยการนั่งกดเอง อยู่ที่รอยต่อระหว่างชิ้นส่วนที่ผ่านเทสต์
+**แต่ 1984 เคสนั้นไม่มีสักเคสที่เปิดแอป** และบั๊กที่โปรเจกต์นี้เจอด้วยการนั่งกดเอง อยู่ที่รอยต่อระหว่างชิ้นส่วนที่ผ่านเทสต์
ทุกตัวแทบทั้งหมด — ปุ่ม "+ แถว" บนแถบเครื่องมือเรียก `addRow` ที่ไม่ประกาศอะไรเลย ขณะที่ `insertRowAtSelection`
ข้าง ๆ ประกาศถูกต้อง (ทั้งคู่เทสต์ผ่าน) · ผู้ช่วย AI ส่งช่วงที่รวมหัวคอลัมน์ไปด้วย เพราะตัวประกอบ context อ่าน
`sheet.cells` ที่เป็นสูตรดิบแทนค่าที่คำนวณแล้ว (ทั้งคู่เทสต์ผ่าน) · ปุ่มใหม่หนึ่งปุ่มดันปุ่มสลับภาษาตกขอบจอไป 42px
@@ -3634,9 +3638,9 @@ seed ถูกปักไว้ ด่านที่แดงจึงแด
ในตารางแล้วสองข้อในflow ที่สามตกทันที (ครั้งแรกที่ลองปิดยังเขียวอยู่ เพราะ `case` ที่แทรกเข้าไปไปอยู่หลัง
`case "ArrowRight"` เดิม กลายเป็นโค้ดตาย — การพิสูจน์ต้องเช็กด้วยว่าของที่ตั้งใจทำให้พังนั้นพังจริง)
-> **1979 เคสผ่านหมด แต่ 43% ของคำตอบจากผู้ช่วย AI ใช้ไม่ได้** — เพราะเทสต์ส่วนนั้น mock ตัวโมเดลไว้
+> **1984 เคสผ่านหมด แต่ 43% ของคำตอบจากผู้ช่วย AI ใช้ไม่ได้** — เพราะเทสต์ส่วนนั้น mock ตัวโมเดลไว้
> มันจึงตอบตามที่คนเขียนเทสต์คิดว่ามันจะตอบ จำนวนเทสต์บอกได้แค่ว่าเราถามอะไรไปบ้าง ไม่ได้บอกว่าเราถาม
-> ครบหรือยัง เรื่องนี้เจอได้ก็ต่อเมื่อเอา API key จริงมายิง — ดู [สิ่งที่เทสต์ 1979 เคสจับไม่ได้](#-สิ่งที่เทสต์-1979-เคสจับไม่ได้)
+> ครบหรือยัง เรื่องนี้เจอได้ก็ต่อเมื่อเอา API key จริงมายิง — ดู [สิ่งที่เทสต์ 1984 เคสจับไม่ได้](#-สิ่งที่เทสต์-1984-เคสจับไม่ได้)
> และรันซ้ำเองได้ด้วย `npm run check:ai`
| ไฟล์ | เคส | ทดสอบอะไร |
@@ -3677,7 +3681,7 @@ seed ถูกปักไว้ ด่านที่แดงจึงแด
| `sheetNames.test.ts` | 7 | กติกาชื่อชีตของ Excel (#54): ทุกข้อที่ผิด, ตัวพิมพ์เล็กใหญ่ถือเป็นชื่อเดียว, แก้ชื่อให้ถูกและหาชื่อที่ว่าง, ปุ่ม + ไม่ได้ชื่อซ้ำหลังลบแท็บ, งานเก่าที่ชื่อซ้ำ: แท็บแรกได้ชื่อเดิมและสูตรไม่ย้าย, ชื่อผิดกติกาเปลี่ยนพร้อมสูตร |
| `sheetMerges.test.ts` | 35 | ช่องไหนถูก merge กลืน, การเลื่อน merge ตอนแทรก/ลบแถว-คอลัมน์, merge ที่เหลือช่องเดียวถูกทิ้ง |
| `sheetTemplate.test.ts` | 14 | เซลล์ไหนล็อก/กรอกได้, ตัวเลือก dropdown แบบ inline และแบบอ้างช่วง, แปลงความกว้างคอลัมน์ |
-| `fileLosses.test.ts` | 12 | ไฟล์ที่เปิดมามีอะไรที่เก็บไว้ไม่ได้ (#83): ไฟล์จริงที่มีรูป กราฟ และฟังก์ชันที่เอนจินไม่มี นับได้ครบพร้อมชื่อชีต, สูตรนั้นส่งออกไปเหมือนเดิม, ไฟล์ธรรมดาไม่มีรายงาน, `_xlfn.` ของฟังก์ชันที่มีไม่ถูกนับ, Pivot Table/รูปร่าง/มาโคร/ลิงก์ และ chart sheet ตามรูปแบบใน spec, ไฟล์ที่ไม่ใช่ zip ไม่ทำให้การเปิดล้ม, ชื่อช่วงที่นำเข้าไม่ได้ (#60) เป็นบรรทัดหนึ่งของรายงานเดียวกัน ต่อจากฟังก์ชันที่ไม่มี เป็นรายงานทั้งหมดของไฟล์ที่ไม่มีอย่างอื่น และยังบอกแม้อ่าน package ซ้ำไม่ได้, เซลล์ error คงที่ (#227) นับพร้อมชื่อชีตแต่สูตรที่ผลเป็น error ไม่นับ และยังนับได้หลังส่งออกแล้วเปิดใหม่ |
+| `fileLosses.test.ts` | 11 | ไฟล์ที่เปิดมามีอะไรที่เก็บไว้ไม่ได้ (#83): ไฟล์จริงที่มีรูป กราฟ และฟังก์ชันที่เอนจินไม่มี นับได้ครบพร้อมชื่อชีต, สูตรนั้นส่งออกไปเหมือนเดิม, ไฟล์ธรรมดาไม่มีรายงาน, `_xlfn.` ของฟังก์ชันที่มีไม่ถูกนับ, Pivot Table/รูปร่าง/มาโคร/ลิงก์ และ chart sheet ตามรูปแบบใน spec, ไฟล์ที่ไม่ใช่ zip ไม่ทำให้การเปิดล้ม, ชื่อช่วงที่นำเข้าไม่ได้ (#60) เป็นบรรทัดหนึ่งของรายงานเดียวกัน ต่อจากฟังก์ชันที่ไม่มี เป็นรายงานทั้งหมดของไฟล์ที่ไม่มีอย่างอื่น และยังบอกแม้อ่าน package ซ้ำไม่ได้, เซลล์ error คงที่ (#227) ไม่อยู่ในรายงานแล้วเพราะแอปอ่านเป็น error จริงตั้งแต่ #226 |
| `excelIO.test.ts` | 58 | สร้างไฟล์ .xlsx จริงแล้ววนครบรอบ: อ่านช่องกรอก/dropdown/ความกว้าง, ไฟล์ที่ไม่ protect ไม่ใช่แม่แบบ, export แล้ว import กลับได้เหมือนเดิม, และรูปแบบ (แถบสี/ขนาดตัวอักษร/เส้นขอบ/ความสูงแถว/merge) ครบรอบ รวมถึงกฎจัดรูปแบบตามเงื่อนไขทั้ง 5 แบบ และโน้ตของเซลล์ (ทั้งที่เขียนเป็นข้อความธรรมดาและ rich text ของ Excel), dropdown ข้ามชีตอ่านจากชีตที่กฎชี้ (ชื่อชีตมีเครื่องหมายคำพูด, ชีตซ่อน, ชีตที่ไม่มีอยู่, แม่แบบร่าง 0 ของ PaynEat ERP), คอลัมน์กว้าง 9 พอดีส่งออกแล้วยังเป็น 9 (#136), merge ในไฟล์มีค่าที่ซ้ายบนช่องเดียว SUM/COUNTA ตรงกับ Excel และ merge ยังส่งออกไป (#55), เซลล์ `t="e"` จริงเปิดมาได้รหัส error ไม่ใช่ช่องว่าง ส่งออกกลับเป็น `t="e"` และเปิดซ้ำยังอยู่ ส่วน `'#N/A` กับช่องรูปแบบข้อความยังออกเป็นข้อความ (#227) |
| `charts.test.ts` | 42 | อ่านช่วงเป็นชุดข้อมูล+ป้ายกำกับ (รวมกรณีคอลัมน์ซ้ายเป็นข้อความ), ช่องว่างเมื่อไม่ใช่ตัวเลข, แกนที่รวมศูนย์, การย้าย/ย่อขยาย/หนีบกรอบไว้ในชีต, คำอธิบายสีตามชนิดกราฟ, การเลื่อนตามแทรก/ลบ |
| `server/urlGuard.test.ts` | 31 | ที่อยู่ที่ห้ามยิงถึง (loopback, วงใน, metadata ของคลาวด์, IPv6 link-local), IPv4 ที่ซ่อนใน IPv6 (`::ffff:`, `::`, SIIT, NAT64, 6to4, Teredo), scheme ที่ไม่ใช่ http, และ allowlist |
@@ -3700,6 +3704,7 @@ seed ถูกปักไว้ ด่านที่แดงจึงแด
| `store/datePivot.test.ts` | 1 | pivot ตามวัน (#45): หัวแถวเป็นวันที่ ไม่ใช่เลข serial |
| `store/pivotSize.test.ts` | 6 | ชีตสรุปใหญ่เท่าผลลัพธ์ (#56): 35 สินค้าครบพร้อมแถวรวมตัวหนา, 12 เดือนครบพร้อมคอลัมน์รวม, สรุปใหม่ก็ได้ครบ, ผลเล็กยังได้ชีต 30×10 ที่มีที่ทำงาน, ผลที่ใหญ่เกินชีตไม่สร้างแต่บอกขนาด และสรุปใหม่ที่ใหญ่เกินเตือนโดย pivot เดิมไม่ถูกทับ |
| `store/pivotError.test.ts` | 2 | pivot ที่แหล่งข้อมูลมี error (#222): ผลรวม เฉลี่ย ต่ำสุด สูงสุด ของกลุ่มที่มี `#DIV/0!` และแถวรวมขึ้น `#DIV/0!` กลุ่มอื่นได้ตัวเลขเดิม ทั้งตอนสร้างและตอนสรุปใหม่หลังแหล่งข้อมูลมี error |
+| `store/errorLiterals.test.ts` | 4 | รหัส error ที่อยู่ในเซลล์เป็นค่าคือ error จริง (#226) ทุกทางเข้า: พิมพ์ (`SUM` ได้ `#DIV/0!` · `IFERROR`/`IFNA` จับได้), วางแบบที่ Excel ก๊อป (`#1`, `#N/A please`, `'#N/A` ยังเป็นข้อความ), เปิดจากไฟล์ (เซลล์ `t="e"` เป็น error แต่ string cell ที่เป็น `#N/A` ยังเป็นข้อความ) และ `SUM`/`IFERROR` ที่อ่านชีต pivot ที่มี error |
| `store/dateEntry.test.ts` | 5 | พิมพ์วันที่แบบคน (#45): `=TODAY()`/`=DATE()`/`=NOW()` ได้รูปแบบวันที่เองถ้าเซลล์ยังเป็น "ทั่วไป", วันที่และเวลาขยายคอลัมน์ที่ยังกว้างเท่าเดิม, เลือกรูปแบบวันที่แทนรูปแบบของไฟล์ |
| `store/convertDates.test.ts` | 5 | "แปลงเป็นวันที่" และ "วันที่ (พ.ศ.)" ผ่าน store (#82): แปลงแล้วแสดงปี พ.ศ. ช่องอ่านไม่ออกและสูตรไม่ถูกแตะ, ค.ศ. เดือนก่อน, undo ครั้งเดียวกลับทั้งหมด, รูปแบบที่เลือกไว้ไม่ถูกทับ, รูปแบบ พ.ศ. แสดงและกลับเป็นวันที่ปกติได้ |
| `store/sampleNotice.test.ts` | 19 | เปิดมาเป็นตารางว่าง, ข้อมูลตัวอย่างเปิดด้วยปุ่มและ undo ได้, ตัวอย่างที่ค้างในเบราว์เซอร์ (ทั้งสองภาษา) ไม่ถูกคืน แต่แก้แล้วแม้จุดเดียวถือเป็นงาน, ไฟล์ใหม่ undo ได้และประกาศออกเสียง, แถบตัวอย่างอยู่เฉพาะตอนที่ยังไม่แตะ และตัวอย่างตามภาษาบนจอ |
diff --git a/public/screenshots/27-landing-stats.png b/public/screenshots/27-landing-stats.png
index 71229d0ca47da225bc89f911963974475c2d99f1..40839822d89e5fb28e2b0d27918dd2dc09815827 100644
GIT binary patch
literal 63822
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