dsh-office-kit 0.4.2 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/skills/excel-live-control/SKILL.md +119 -152
- package/assets/skills/excel-live-control/domain_guidance/financial_models.md +42 -58
- package/assets/skills/excel-live-control/domain_guidance/healthcare.md +36 -42
- package/assets/skills/excel-live-control/domain_guidance/marketing_advertising.md +33 -34
- package/assets/skills/excel-live-control/domain_guidance/scientific_research.md +34 -36
- package/assets/skills/excel-live-control/references/office-automation.md +127 -153
- package/assets/skills/excel-live-control/references/read_only_qna.md +40 -45
- package/assets/skills/excel-live-control/style_guidelines.md +56 -64
- package/assets/skills/excel-live-control/workflows/create_workflows.md +40 -47
- package/assets/skills/excel-live-control/workflows/edit_workflows.md +37 -45
- package/assets/skills/office-documents/SKILL.md +24 -60
- package/assets/skills/office-documents/examples/end_to_end_smoke_test.md +5 -5
- package/assets/skills/office-documents/ooxml/comments.md +8 -8
- package/assets/skills/office-documents/ooxml/hyperlinks_and_fields.md +10 -10
- package/assets/skills/office-documents/ooxml/rels_and_content_types.md +7 -7
- package/assets/skills/office-documents/ooxml/tracked_changes.md +12 -12
- package/assets/skills/office-documents/references/docx-structure.md +11 -13
- package/assets/skills/office-documents/references/template-elicitation.md +11 -13
- package/assets/skills/office-documents/references/writing-quality.md +20 -20
- package/assets/skills/office-documents/tasks/accessibility_a11y.md +16 -22
- package/assets/skills/office-documents/tasks/captions_crossrefs.md +23 -26
- package/assets/skills/office-documents/tasks/clean_tracked_changes.md +17 -22
- package/assets/skills/office-documents/tasks/comments_manage.md +9 -11
- package/assets/skills/office-documents/tasks/compare_diff.md +10 -16
- package/assets/skills/office-documents/tasks/create_edit.md +14 -16
- package/assets/skills/office-documents/tasks/equations.md +17 -28
- package/assets/skills/office-documents/tasks/fields_update.md +14 -16
- package/assets/skills/office-documents/tasks/fixtures_edge_cases.md +19 -33
- package/assets/skills/office-documents/tasks/footnotes_endnotes.md +12 -14
- package/assets/skills/office-documents/tasks/forms_content_controls.md +16 -20
- package/assets/skills/office-documents/tasks/headings_numbering.md +17 -22
- package/assets/skills/office-documents/tasks/images_figures.md +15 -25
- package/assets/skills/office-documents/tasks/multi_doc_merge.md +13 -23
- package/assets/skills/office-documents/tasks/navigation_internal_links.md +18 -21
- package/assets/skills/office-documents/tasks/privacy_scrub_metadata.md +16 -22
- package/assets/skills/office-documents/tasks/protection_restrict_editing.md +19 -21
- package/assets/skills/office-documents/tasks/read_review.md +9 -20
- package/assets/skills/office-documents/tasks/redaction_anonymization.md +17 -18
- package/assets/skills/office-documents/tasks/sections_layout.md +16 -23
- package/assets/skills/office-documents/tasks/style_lint_normalize.md +18 -22
- package/assets/skills/office-documents/tasks/tables_spreadsheets.md +21 -31
- package/assets/skills/office-documents/tasks/templates_style_packs.md +17 -21
- package/assets/skills/office-documents/tasks/toc_workflow.md +10 -14
- package/assets/skills/office-documents/tasks/verify_render.md +11 -23
- package/assets/skills/office-documents/tasks/watermarks_background.md +11 -15
- package/assets/skills/office-documents/troubleshooting/libreoffice_headless.md +6 -6
- package/assets/skills/office-documents/troubleshooting/run_splitting.md +12 -12
- package/assets/skills/office-pdf/SKILL.md +36 -51
- package/assets/skills/office-pdf/references/form-fields.md +20 -20
- package/assets/skills/office-pdf/references/geometry.md +10 -10
- package/assets/skills/office-pdf/references/layout-quality.md +13 -13
- package/assets/skills/office-pdf/references/limits.md +12 -56
- package/assets/skills/office-pdf/tasks/annotations.md +5 -5
- package/assets/skills/office-pdf/tasks/create.md +6 -9
- package/assets/skills/office-pdf/tasks/edit-pages.md +14 -14
- package/assets/skills/office-pdf/tasks/forms.md +15 -15
- package/assets/skills/office-pdf/tasks/read.md +9 -9
- package/assets/skills/office-pdf/tasks/redact.md +18 -18
- package/assets/skills/office-pdf/tasks/stamp.md +10 -10
- package/assets/skills/office-presentations/SKILL.md +71 -91
- package/assets/skills/office-presentations/container_tools/render_slides.py +1 -1
- package/assets/skills/office-presentations/domain_guidance/finance.md +16 -16
- package/assets/skills/office-presentations/recipes/README.md +24 -35
- package/assets/skills/office-presentations/recipes/autolayout.md +12 -13
- package/assets/skills/office-presentations/recipes/connectors.md +11 -12
- package/assets/skills/office-presentations/recipes/images.md +11 -12
- package/assets/skills/office-presentations/recipes/master-and-layouts.md +18 -18
- package/assets/skills/office-presentations/recipes/native-charts.md +8 -8
- package/assets/skills/office-presentations/recipes/rich-text-runs.md +13 -13
- package/assets/skills/office-presentations/recipes/speaker-notes.md +7 -7
- package/assets/skills/office-presentations/recipes/tables.md +14 -14
- package/assets/skills/office-presentations/recipes/textbox-at-coordinate.md +9 -9
- package/assets/skills/office-presentations/recipes/theme-tokens.md +7 -8
- package/assets/skills/office-presentations/references/authoring-workflow.md +38 -43
- package/assets/skills/office-presentations/references/finalization.md +10 -12
- package/assets/skills/office-presentations/references/native-bullets.md +14 -18
- package/assets/skills/office-presentations/references/native-evidence.md +18 -32
- package/assets/skills/office-presentations/references/style-guidelines.md +27 -32
- package/assets/skills/office-presentations/references/templates.md +31 -60
- package/assets/skills/office-presentations/routing/google_slides.md +4 -4
- package/assets/skills/office-presentations/tasks/apply-annotations.md +17 -17
- package/assets/skills/office-presentations/tasks/charts-tables-notes.md +20 -23
- package/assets/skills/office-presentations/tasks/create-deck.md +19 -19
- package/assets/skills/office-presentations/tasks/edit-deck.md +14 -16
- package/assets/skills/office-presentations/tasks/inspect-and-verify.md +31 -34
- package/assets/skills/office-presentations/tasks/template-following.md +23 -28
- package/assets/skills/office-spreadsheets/SKILL.md +32 -39
- package/assets/skills/office-spreadsheets/recipes/charts.md +8 -26
- package/assets/skills/office-spreadsheets/recipes/conditional-formats.md +9 -26
- package/assets/skills/office-spreadsheets/recipes/data-tables.md +7 -23
- package/assets/skills/office-spreadsheets/recipes/named-ranges.md +8 -21
- package/assets/skills/office-spreadsheets/recipes/number-formats.md +7 -23
- package/assets/skills/office-spreadsheets/recipes/sparklines.md +7 -20
- package/assets/skills/office-spreadsheets/references/charts.md +15 -34
- package/assets/skills/office-spreadsheets/references/domain/financial-models.md +10 -25
- package/assets/skills/office-spreadsheets/references/domain/healthcare.md +8 -19
- package/assets/skills/office-spreadsheets/references/domain/marketing.md +8 -22
- package/assets/skills/office-spreadsheets/references/domain/research.md +8 -19
- package/assets/skills/office-spreadsheets/references/formula-patterns.md +20 -50
- package/assets/skills/office-spreadsheets/references/style-guidelines.md +19 -44
- package/assets/skills/office-spreadsheets/references/workbook-structure.md +12 -35
- package/assets/skills/office-spreadsheets/routing/google-sheets.md +11 -26
- package/assets/skills/office-spreadsheets/tasks/analyze-workbook.md +10 -25
- package/assets/skills/office-spreadsheets/tasks/annotations.md +12 -30
- package/assets/skills/office-spreadsheets/tasks/create-workbook.md +5 -5
- package/assets/skills/office-spreadsheets/tasks/diff-workbooks.md +2 -2
- package/assets/skills/office-spreadsheets/tasks/edit-workbook.md +5 -5
- package/assets/skills/office-spreadsheets/tasks/inspect-workbook.md +9 -9
- package/assets/skills/office-spreadsheets/tasks/recalc-and-check.md +10 -30
- package/assets/skills/shared/annotation-recipes.md +98 -120
- package/assets/skills/shared/common-workflow.md +70 -80
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# Formula patterns
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
by engines that disagree at the edges. Prefer the direct, boring form.
|
|
3
|
+
People who did not write a formula have to read it, and engines that disagree at the edges recalculate it. Prefer the direct, boring form.
|
|
5
4
|
|
|
6
5
|
## Anchoring
|
|
7
6
|
|
|
@@ -12,67 +11,38 @@ by engines that disagree at the edges. Prefer the direct, boring form.
|
|
|
12
11
|
| `$A8` | right only | A column of item labels |
|
|
13
12
|
| `$B$3` | never | One rate, a case selector, a fixed constant |
|
|
14
13
|
|
|
15
|
-
`=SUMIFS(Amount,Month,C$4,Item,$A8)` reads the period from the header and the item
|
|
16
|
-
from the label. `=C8*$B$3` multiplies by one fixed rate; `=C8*C$3` multiplies by
|
|
17
|
-
the rate in that column. Getting this backwards is the most common silent error in
|
|
18
|
-
a copied model — check one filled row and one filled column by hand.
|
|
14
|
+
`=SUMIFS(Amount,Month,C$4,Item,$A8)` reads the period from the header and the item from the label. `=C8*$B$3` multiplies by one fixed rate; `=C8*C$3` multiplies by the rate in that column. Getting this backwards is the most common silent error in a copied model — check one filled row and one filled column by hand.
|
|
19
15
|
|
|
20
16
|
## Aggregation
|
|
21
17
|
|
|
22
|
-
- `SUM` for a column, `SUMIFS` for filtered totals, `COUNTIFS` for counts,
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
|
|
26
|
-
- `
|
|
27
|
-
|
|
28
|
-
- `PRODUCT` for multiplied factors, but it skips blanks: a missing input silently
|
|
29
|
-
removes a factor. Check the inputs before trusting the result.
|
|
30
|
-
- `INDEX`/`MATCH`, `VLOOKUP(...,FALSE)`, or `XLOOKUP` — all fine. Keep the exact
|
|
31
|
-
match flag explicit. A matched key is not a filled value: check the returned
|
|
32
|
-
cell for blank as well as for the key existing.
|
|
33
|
-
- Long category lists belong in a mapping table with a lookup, not in a nested
|
|
34
|
-
`IF` chain.
|
|
18
|
+
- `SUM` for a column, `SUMIFS` for filtered totals, `COUNTIFS` for counts, `AVERAGEIFS` for averages.
|
|
19
|
+
- Use `SUMIFS`/`COUNTIFS` even with one criterion; they read the same and extend cleanly.
|
|
20
|
+
- `SUMPRODUCT(qty_range, rate_range)` for paired multiplication; it does not collapse to a single cell the way array arithmetic would.
|
|
21
|
+
- `PRODUCT` for multiplied factors, but it skips blanks: a missing input silently removes a factor. Check the inputs before trusting the result.
|
|
22
|
+
- `INDEX`/`MATCH`, `VLOOKUP(...,FALSE)`, or `XLOOKUP` — all fine. Keep the exact-match flag explicit. A matched key is not a filled value: check the returned cell for blank as well as for the key existing.
|
|
23
|
+
- Long category lists belong in a mapping table with a lookup, not in a nested `IF` chain.
|
|
35
24
|
|
|
36
25
|
## Dates and periods
|
|
37
26
|
|
|
38
|
-
- Use the date the source gives; `TODAY()` only when the workbook should track
|
|
39
|
-
today, and label it when it does.
|
|
27
|
+
- Use the date the source gives; `TODAY()` only when the workbook should track today, and label it when it does.
|
|
40
28
|
- Store real dates with a date number format. Text dates do not calculate.
|
|
41
|
-
- Derive period filters from one header row so a new month is a copy, not an edit:
|
|
42
|
-
|
|
43
|
-
-
|
|
44
|
-
otherwise); say which in the header.
|
|
45
|
-
- Time scales run left to right coarse to fine: Annual, Quarterly, Monthly,
|
|
46
|
-
Weekly — with narrow unfilled spacer columns, not merged headers over hidden
|
|
47
|
-
helpers.
|
|
29
|
+
- Derive period filters from one header row so a new month is a copy, not an edit: `=SUMIFS(Amount,Date,">="&C$4,Date,"<"&EDATE(C$4,1),Item,$A8)`.
|
|
30
|
+
- Week starting on the first business day (Monday unless the business says otherwise); say which in the header.
|
|
31
|
+
- Time scales run left to right coarse to fine: Annual, Quarterly, Monthly, Weekly — with narrow unfilled spacer columns, not merged headers over hidden helpers.
|
|
48
32
|
|
|
49
33
|
## Missing data
|
|
50
34
|
|
|
51
|
-
- A real zero is zero. A missing value is blank, or honestly `n.a.`/`N/A` where
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
-
|
|
55
|
-
block to hide it. `IFERROR(x,0)` turns a broken reference into a plausible zero.
|
|
56
|
-
- Guards must not swallow the failure they guard against: `=IF(C8=0,"n.a.",B8/C8)`
|
|
57
|
-
is a clear answer, `=IFERROR(B8/C8,0)` is a lie.
|
|
58
|
-
- Missing keys in a lookup should show as missing (`=IFNA(...,"not found")`), not
|
|
59
|
-
as zero.
|
|
35
|
+
- A real zero is zero. A missing value is blank, or honestly `n.a.`/`N/A` where the reader expects text. Never substitute one for the other to make a chart look complete.
|
|
36
|
+
- `IFERROR` only around a failure you understand, never around a whole block to hide it. `IFERROR(x,0)` turns a broken reference into a plausible zero.
|
|
37
|
+
- Guards must not swallow the failure they guard against: `=IF(C8=0,"n.a.",B8/C8)` is a clear answer, `=IFERROR(B8/C8,0)` is a lie.
|
|
38
|
+
- Missing keys in a lookup should show as missing (`=IFNA(...,"not found")`), not as zero.
|
|
60
39
|
|
|
61
40
|
## Things not to write
|
|
62
41
|
|
|
63
|
-
- `LET`, dynamic arrays/spills, `MAP`, `REDUCE`, `LAMBDA`: the engines that read
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
- `INDIRECT` for everything. It breaks traceability and does not update when a
|
|
67
|
-
sheet is renamed. Keep it only where the existing file already relies on it.
|
|
68
|
-
- Volatile functions (`TODAY`, `NOW`, `RAND`, `OFFSET`) in a calculation grid:
|
|
69
|
-
every keystroke recalculates them, and the value changes when the file is
|
|
70
|
-
reopened.
|
|
42
|
+
- `LET`, dynamic arrays/spills, `MAP`, `REDUCE`, `LAMBDA`: the engines that read these files implement them unevenly, and openpyxl stores text without validating it.
|
|
43
|
+
- `INDIRECT` for everything. It breaks traceability and does not update when a sheet is renamed. Keep it only where the existing file already relies on it.
|
|
44
|
+
- Volatile functions (`TODAY`, `NOW`, `RAND`, `OFFSET`) in a calculation grid: every keystroke recalculates them, and the value changes when the file is reopened.
|
|
71
45
|
|
|
72
46
|
## Circular references
|
|
73
47
|
|
|
74
|
-
Avoid unintended cycles; Excel flags them for a reason. If a cycle is deliberate
|
|
75
|
-
(interest on average balance, iterative allocation), document it in the sheet,
|
|
76
|
-
confirm iteration is enabled, and verify the result converges to the expected
|
|
77
|
-
number. A model that only "works" because the last recalc happened to stop at
|
|
78
|
-
iteration 100 is not verified.
|
|
48
|
+
Avoid unintended cycles; Excel flags them for a reason. If a cycle is deliberate (interest on average balance, iterative allocation), document it in the sheet, confirm iteration is enabled, and verify the result converges to the expected number. A model that only "works" because the last recalc happened to stop at iteration 100 is not verified.
|
|
@@ -1,69 +1,44 @@
|
|
|
1
1
|
# Style guidelines
|
|
2
2
|
|
|
3
|
-
Precedence: the user's request, then the workbook or template being edited, then a
|
|
4
|
-
domain convention, then these defaults. Defaults apply to new sheets, or to
|
|
5
|
-
restyling the user asked for — never to a sheet you were not asked to touch.
|
|
3
|
+
Precedence: the user's request, then the workbook or template being edited, then a domain convention, then these defaults. Defaults apply to new sheets, or to restyling the user asked for — never to a sheet you were not asked to touch.
|
|
6
4
|
|
|
7
5
|
## Page furniture
|
|
8
6
|
|
|
9
|
-
- One blank row at the top, then a short unfilled title, left aligned, in a size
|
|
10
|
-
clearly larger than the body. No full-width filled banner.
|
|
7
|
+
- One blank row at the top, then a short unfilled title, left aligned, in a size clearly larger than the body. No full-width filled banner.
|
|
11
8
|
- A thin rule under the title separates it from the table; nothing else.
|
|
12
|
-
- Notes sit in ordinary cells to the right of the data, at least one blank column
|
|
13
|
-
away from the last header fill, with wrap off.
|
|
9
|
+
- Notes sit in ordinary cells to the right of the data, at least one blank column away from the last header fill, with wrap off.
|
|
14
10
|
- No footer blocks, no "Prepared by" furniture, no date stamps nobody asked for.
|
|
15
|
-
- Gridlines off on new sheets. Do not change gridlines on a sheet you are editing
|
|
16
|
-
for another reason.
|
|
11
|
+
- Gridlines off on new sheets. Do not change gridlines on a sheet you are editing for another reason.
|
|
17
12
|
|
|
18
13
|
## Structure
|
|
19
14
|
|
|
20
|
-
- Freeze the header row of any table that scrolls, plus the identifying column(s)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
- Section bands: one continuous fill with a single outline around the block; no
|
|
26
|
-
internal borders inside the band, no full-cell grid.
|
|
27
|
-
- Spacer columns are genuinely empty (no values, no borders), not narrow columns
|
|
28
|
-
of spaces.
|
|
29
|
-
- Keep working titles, headers, and input areas unmerged. Center Across Selection
|
|
30
|
-
gives the look of a merge without breaking sorting, filtering, and references.
|
|
15
|
+
- Freeze the header row of any table that scrolls, plus the identifying column(s) when horizontal scrolling hides them. Freeze the smallest useful area and never move content to make freezing convenient.
|
|
16
|
+
- Header row: bold, centred horizontally and vertically, dark fill with white text or a light grey band, thin white separators between header cells.
|
|
17
|
+
- Section bands: one continuous fill with a single outline around the block; no internal borders inside the band, no full-cell grid.
|
|
18
|
+
- Spacer columns are genuinely empty (no values, no borders), not narrow columns of spaces.
|
|
19
|
+
- Keep working titles, headers, and input areas unmerged. Center Across Selection gives the look of a merge without breaking sorting, filtering, and references.
|
|
31
20
|
|
|
32
21
|
## Numbers, inputs, calcs
|
|
33
22
|
|
|
34
23
|
- Typed values with explicit number formats — see `recipes/number-formats.md`.
|
|
35
|
-
- Left-align text, right-align numbers, centre headers, middle-align vertically;
|
|
36
|
-
|
|
37
|
-
-
|
|
38
|
-
colour cue the sheet already uses, calculations stay white. Yellow/amber marks an
|
|
39
|
-
input that still needs updating; keep that cue separate from calculated warnings.
|
|
40
|
-
- When cases exist, show `Case Selected:` plus the linked value near the top of
|
|
41
|
-
each output and build tab, in a restrained dashed outline, and highlight the
|
|
42
|
-
active row in the driver table.
|
|
24
|
+
- Left-align text, right-align numbers, centre headers, middle-align vertically; top-align long wrapped descriptions.
|
|
25
|
+
- Distinguish inputs from calculations consistently: inputs get a light fill or a colour cue the sheet already uses, calculations stay white. Yellow/amber marks an input that still needs updating; keep that cue separate from calculated warnings.
|
|
26
|
+
- When cases exist, show `Case Selected:` plus the linked value near the top of each output and build tab, in a restrained dashed outline, and highlight the active row in the driver table.
|
|
43
27
|
- Technical helper rows above a model are italic and grouped/collapsed.
|
|
44
28
|
|
|
45
29
|
## Conditional formatting as a cue
|
|
46
30
|
|
|
47
|
-
- Bound the rule to the data, and use it for status, risk, variance, and
|
|
48
|
-
|
|
49
|
-
-
|
|
50
|
-
no static green "PASS" paint over a range.
|
|
51
|
-
- Reuse the sheet's existing rule style before inventing a new colour. Two similar
|
|
52
|
-
reds in one workbook look like two different severities.
|
|
31
|
+
- Bound the rule to the data, and use it for status, risk, variance, and exceptions — not decoration.
|
|
32
|
+
- Critical errors: light red fill, bold dark red text. Valid checks stay neutral; no static green "PASS" paint over a range.
|
|
33
|
+
- Reuse the sheet's existing rule style before inventing a new colour. Two similar reds in one workbook look like two different severities.
|
|
53
34
|
|
|
54
35
|
## Typography
|
|
55
36
|
|
|
56
37
|
- One family across the workbook: Helvetica Neue, Helvetica, Arial, then Aptos.
|
|
57
|
-
- Two sizes at most (three counting the title). Largest size no more than six
|
|
58
|
-
|
|
59
|
-
-
|
|
60
|
-
the same line, never on every row.
|
|
61
|
-
- Tighten row heights after content fits; do not shrink the font to win an
|
|
62
|
-
argument with a column width.
|
|
38
|
+
- Two sizes at most (three counting the title). Largest size no more than six points above body. A 10pt body with an 11pt header and a 14pt title is enough.
|
|
39
|
+
- Bold for headers and totals, italic for short context notes — never both on the same line, never on every row.
|
|
40
|
+
- Tighten row heights after content fits; do not shrink the font to win an argument with a column width.
|
|
63
41
|
|
|
64
42
|
## Tab colours
|
|
65
43
|
|
|
66
|
-
Use
|
|
67
|
-
level lighter on assumptions, a distinct muted tone on a ReadMe, a divider tab
|
|
68
|
-
coloured while its children stay plain. Financial Actuals tabs are traditionally
|
|
69
|
-
light tan. Never recolour tabs during an unrelated edit.
|
|
44
|
+
Use colour only to help navigation: a darker brand tone on output tabs, one level lighter on assumptions, a distinct muted tone on a ReadMe, a divider tab coloured while its children stay plain. Financial Actuals tabs are traditionally light tan. Never recolour tabs during an unrelated edit.
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
# Workbook structure
|
|
2
2
|
|
|
3
|
-
Tab roles describe what a sheet *does*, not what tabs a workbook must have. A
|
|
4
|
-
simple workbook can carry several roles as labelled blocks on one sheet; a large
|
|
5
|
-
one separates them because the readers, the refresh cadence, or the audit trail
|
|
6
|
-
differ.
|
|
3
|
+
Tab roles describe what a sheet *does*, not what tabs a workbook must have. A simple workbook can carry several roles as labelled blocks on one sheet; a large one separates them because the readers, the refresh cadence, or the audit trail differ.
|
|
7
4
|
|
|
8
5
|
| Role | Holds | Feeds |
|
|
9
6
|
| --- | --- | --- |
|
|
@@ -16,45 +13,25 @@ differ.
|
|
|
16
13
|
|
|
17
14
|
Rules that keep a workbook readable a year later:
|
|
18
15
|
|
|
19
|
-
- Inputs flow forward: source → build → output. A source tab never reads a
|
|
20
|
-
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
exists on a build tab; they reference it.
|
|
26
|
-
- Checks are terminal. Nothing depends on a check tab, and a passing check stays
|
|
27
|
-
neutral — a wall of green PASS fills trains the reader to ignore the one red
|
|
28
|
-
cell that matters.
|
|
29
|
-
- Combine roles when the workbook is small. Three assumption cells do not need a
|
|
30
|
-
Settings tab; a short labelled block beside the calculation is easier to audit.
|
|
31
|
-
- Add a tab when the reader differs, the data grain differs, the refresh
|
|
32
|
-
boundary differs, or the user asks. Not because a template had one.
|
|
16
|
+
- Inputs flow forward: source → build → output. A source tab never reads a downstream result back in; when it seems to, the value belongs on a build tab.
|
|
17
|
+
- Builds show the steps: quantity × rate, capacity used ÷ capacity available, opening + movements = closing. One dense formula that jumps from input to final number cannot be reviewed and will be wrong the first time an input changes.
|
|
18
|
+
- Outputs consolidate and roll up. They reference the calculation on the build tab; they do not repeat it.
|
|
19
|
+
- Checks are terminal. Nothing depends on a check tab, and a passing check stays neutral — a wall of green PASS fills trains the reader to ignore the one red cell that matters.
|
|
20
|
+
- Combine roles when the workbook is small. Three assumption cells do not need a Settings tab; a short labelled block beside the calculation is easier to audit.
|
|
21
|
+
- Add a tab when the reader differs, the data grain differs, the refresh boundary differs, or the user asks. Not because a template had one.
|
|
33
22
|
|
|
34
23
|
## Physical order
|
|
35
24
|
|
|
36
|
-
For multi-tab workbooks, left to right: outputs, the assumption control panel
|
|
37
|
-
(usually just after the primary output so a reader sees the switch), builds,
|
|
38
|
-
then inputs and sources, with a divider tab such as `Internal >>` guarding the
|
|
39
|
-
tail. The reader gets the answer first; the machinery lives to the right.
|
|
25
|
+
For multi-tab workbooks, left to right: outputs, the assumption control panel (usually just after the primary output so a reader sees the switch), builds, then inputs and sources, with a divider tab such as `Internal >>` guarding the tail. The reader gets the answer first; the machinery lives to the right.
|
|
40
26
|
|
|
41
|
-
Separate schedules when inputs, grain, or owners differ (revenue vs cost bases,
|
|
42
|
-
monthly vs weekly). A single mega-sheet that mixes both grains is where
|
|
43
|
-
double-counting starts.
|
|
27
|
+
Separate schedules when inputs, grain, or owners differ (revenue vs cost bases, monthly vs weekly). A single mega-sheet that mixes both grains is where double-counting starts.
|
|
44
28
|
|
|
45
29
|
## Names
|
|
46
30
|
|
|
47
|
-
Short, descriptive, and about the content: `Pipeline`, `Revenue build`,
|
|
48
|
-
`Monthly forecast`. Not `Sheet3`, not `Data2`, not a sentence. A forecast review
|
|
49
|
-
tab is `Forecast review`, `Forecast variance`, or `Sensitivity`; never `Movement`,
|
|
50
|
-
which says nothing about what moved.
|
|
31
|
+
Short, descriptive, and about the content: `Pipeline`, `Revenue build`, `Monthly forecast`. Not `Sheet3`, not `Data2`, not a sentence. A forecast review tab is `Forecast review`, `Forecast variance`, or `Sensitivity`; never `Movement`, which says nothing about what moved.
|
|
51
32
|
|
|
52
|
-
Divider tabs are labels, not data: `Inputs >>` with its children uncoloured reads
|
|
53
|
-
as a section marker; a coloured tab on every sheet reads as noise.
|
|
33
|
+
Divider tabs are labels, not data: `Inputs >>` with its children uncoloured reads as a section marker; a coloured tab on every sheet reads as noise.
|
|
54
34
|
|
|
55
35
|
## The case selector
|
|
56
36
|
|
|
57
|
-
When a workbook has cases, there is exactly one editable selector, on the cover
|
|
58
|
-
or assumptions tab, with its current value shown as `Case Selected:` near the top
|
|
59
|
-
of every output and build tab. Two selectors, or a selector plus hard-coded
|
|
60
|
-
per-tab values, is how a model ends up reporting two different cases.
|
|
37
|
+
When a workbook has cases, there is exactly one editable selector, on the cover or assumptions tab, with its current value shown as `Case Selected:` near the top of every output and build tab. Two selectors, or a selector plus hard-coded per-tab values, is how a model ends up reporting two different cases.
|
|
@@ -1,36 +1,21 @@
|
|
|
1
1
|
# Google Sheets
|
|
2
2
|
|
|
3
|
-
This runtime works on local files with openpyxl. There are no Google credentials,
|
|
4
|
-
no Drive API, and no live link to a browser sheet, so "update my Google Sheet"
|
|
5
|
-
cannot be done directly.
|
|
3
|
+
This runtime works on local files with openpyxl. There are no Google credentials, no Drive API, and no live link to a browser sheet, so "update my Google Sheet" cannot be done directly.
|
|
6
4
|
|
|
7
5
|
## What to do instead
|
|
8
6
|
|
|
9
|
-
1. Say plainly what is possible: the work is done on a local `.xlsx` file the user
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
for `.xlsx` unless the sheet is truly one flat table.
|
|
14
|
-
3. Do the work on the exported file with this skill, then hand back the `.xlsx`.
|
|
15
|
-
The user re-uploads or imports it. State that formulas recalculate when Sheets
|
|
16
|
-
opens the file.
|
|
17
|
-
4. Do not promise a round trip that keeps Sheets-specific features. Named
|
|
18
|
-
functions, Apps Script, and connected sheets do not survive export.
|
|
7
|
+
1. Say plainly what is possible: the work is done on a local `.xlsx` file the user opens in Sheets, or the user exports the sheet and shares the file.
|
|
8
|
+
2. Ask for an export when the source lives in Sheets: `File > Download > Microsoft Excel (.xlsx)`. A single-sheet CSV loses formulas and formats, so ask for `.xlsx` unless the sheet is truly one flat table.
|
|
9
|
+
3. Do the work on the exported file with this skill, then hand back the `.xlsx`. The user re-uploads or imports it. State that formulas recalculate when Sheets opens the file.
|
|
10
|
+
4. Do not promise a round trip that keeps Sheets-specific features. Named functions, Apps Script, and connected sheets do not survive export.
|
|
19
11
|
|
|
20
|
-
##
|
|
12
|
+
## Formulas for a file that goes back to Sheets
|
|
21
13
|
|
|
22
|
-
- Keep to functions both engines share: `SUMIFS`, `INDEX/MATCH`, `XLOOKUP`,
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
|
|
26
|
-
- Array formulas and dynamic spills behave differently in the two engines. Avoid
|
|
27
|
-
them in shared files.
|
|
28
|
-
- Number formats, conditional-formatting rules, and charts mostly survive an
|
|
29
|
-
export; images and pivot tables often do not. Check them after the round trip
|
|
30
|
-
with `container_tools/inspect_workbook.py`.
|
|
14
|
+
- Keep to functions both engines share: `SUMIFS`, `INDEX/MATCH`, `XLOOKUP`, `IFERROR`, `EDATE`, `TEXT`.
|
|
15
|
+
- Newer functions that Excel stores with an `_xlfn.` prefix are a common source of `#NAME?` after a round trip. If a function is genuinely new, say so.
|
|
16
|
+
- Array formulas and dynamic spills behave differently in the two engines. Avoid them in shared files.
|
|
17
|
+
- Number formats, conditional-formatting rules, and charts mostly survive an export; images and pivot tables often do not. Check them after the round trip with `container_tools/inspect_workbook.py`.
|
|
31
18
|
|
|
32
19
|
## Links
|
|
33
20
|
|
|
34
|
-
A sheet shared by URL is not a workbook on this machine. Do not fetch a Google
|
|
35
|
-
Sheets URL and pretend it is a file: without a published CSV or an export, there
|
|
36
|
-
is nothing to read.
|
|
21
|
+
A sheet shared by URL is not a workbook on this machine. Do not fetch a Google Sheets URL and pretend it is a file: without a published CSV or an export, there is nothing to read.
|
|
@@ -1,37 +1,22 @@
|
|
|
1
1
|
# Answer questions about an existing workbook
|
|
2
2
|
|
|
3
|
-
This is a read-only job. Do not "improve" the file, do not recalculate it in
|
|
4
|
-
place, and do not save a copy unless the user asked for one.
|
|
3
|
+
This is a read-only job. Do not "improve" the file, do not recalculate it in place, and do not save a copy unless the user asked for one.
|
|
5
4
|
|
|
6
5
|
## Procedure
|
|
7
6
|
|
|
8
|
-
1. `"<python>" "<cli>" xlsx read --input "<book.xlsx>" --json-out "<dump>.json"` —
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
file was last written by a script), say so and quote the formula instead of a
|
|
13
|
-
number, or recalculate into a copy first (`tasks/recalc-and-check.md`).
|
|
14
|
-
3. `container_tools/inspect_workbook.py --input "<book.xlsx>" --sample 8` when the
|
|
15
|
-
question touches structure: which cells are formulas, merged ranges, totals
|
|
16
|
-
rows, conditional formats, defined names, hidden rows, extra sheets.
|
|
17
|
-
4. Answer with the cells you used: "`Pipeline!B4:B13`, the Amount column, sums to
|
|
18
|
-
`812,000`" beats "the pipeline is about 800k". Name the sheet, the range, and
|
|
19
|
-
the figure.
|
|
7
|
+
1. `"<python>" "<cli>" xlsx read --input "<book.xlsx>" --json-out "<dump>.json"` — sheet names, used ranges, and cell contents.
|
|
8
|
+
2. Read **values**, not formulas, when the question is about numbers: `xlsx read --data-only` returns cached results. If the cache is empty (the file was last written by a script), say so and quote the formula instead of a number, or recalculate into a copy first (`tasks/recalc-and-check.md`).
|
|
9
|
+
3. `container_tools/inspect_workbook.py --input "<book.xlsx>" --sample 8` when the question touches structure: which cells are formulas, merged ranges, totals rows, conditional formats, defined names, hidden rows, extra sheets.
|
|
10
|
+
4. Answer with the cells you used: "`Pipeline!B4:B13`, the Amount column, sums to `812,000`" beats "the pipeline is about 800k". Name the sheet, the range, and the figure.
|
|
20
11
|
|
|
21
12
|
## Judgement calls
|
|
22
13
|
|
|
23
|
-
- A number that disagrees with the user's expectation is usually a real answer,
|
|
24
|
-
|
|
25
|
-
-
|
|
26
|
-
|
|
27
|
-
- Two tabs with the same title and different numbers: report both and ask which
|
|
28
|
-
one the user means before averaging or picking.
|
|
29
|
-
- Empty cells are not zeros. "Not reported" and "zero" are different answers, and
|
|
30
|
-
a missing month in a total usually means a filter, not a zero.
|
|
14
|
+
- A number that disagrees with the user's expectation is usually a real answer, not an error to fix. Explain the calculation and stop.
|
|
15
|
+
- Pre-existing `#REF!`/`#DIV/0!` cells are part of the answer. Point at them, say what breaks, and wait for instructions.
|
|
16
|
+
- Two tabs with the same title and different numbers: report both and ask which one the user means before averaging or picking.
|
|
17
|
+
- Empty cells are not zeros. "Not reported" and "zero" are different answers, and a missing month in a total usually means a filter, not a zero.
|
|
31
18
|
- If the workbook has a case selector, check it. The answer depends on it.
|
|
32
19
|
|
|
33
20
|
## Output shape
|
|
34
21
|
|
|
35
|
-
Short answer first (one line with the figure), then the cells behind it, then any
|
|
36
|
-
caveat about missing data or stale cache. No file changes, no new workbook, no
|
|
37
|
-
chart unless asked.
|
|
22
|
+
Short answer first (one line with the figure), then the cells behind it, then any caveat about missing data or stale cache. No file changes, no new workbook, no chart unless asked.
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# Resolve an `office-annotations` region to cells
|
|
2
2
|
|
|
3
|
-
The user drags a box on the rendered workbook and types a requirement. The
|
|
4
|
-
payload for spreadsheets is:
|
|
3
|
+
The user drags a box on the rendered workbook and types a requirement. The payload for spreadsheets is:
|
|
5
4
|
|
|
6
5
|
```json
|
|
7
6
|
{
|
|
@@ -15,37 +14,20 @@ payload for spreadsheets is:
|
|
|
15
14
|
}
|
|
16
15
|
```
|
|
17
16
|
|
|
18
|
-
There is no `page`, no `sheet`, and no `range`: the preview client cannot turn a
|
|
19
|
-
pixel rectangle into a cell address and will not fake one. Read it as "look at
|
|
20
|
-
this area of this sheet and do this", not as a cell reference.
|
|
17
|
+
There is no `page`, no `sheet`, and no `range`: the preview client cannot turn a pixel rectangle into a cell address and will not fake one. Read it as "look at this area of this sheet and do this", not as a cell reference.
|
|
21
18
|
|
|
22
19
|
## Procedure
|
|
23
20
|
|
|
24
|
-
1. `read_image` the attachment named `imageName`. It is the screenshot of the
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
sheets more often than you expect — match on a combination (a row label plus
|
|
30
|
-
two numbers), not on one number.
|
|
31
|
-
3. When the numbers are ambiguous, `container_tools/inspect_workbook.py` adds
|
|
32
|
-
formulas, merges, tables, and names; formats often disambiguate ("the only
|
|
33
|
-
column with a `%` format").
|
|
34
|
-
4. State what you resolved, in the user's terms: "`Pipeline!D2:D13`, the Amount
|
|
35
|
-
column — 12 rows of whole dollars". Ask only if two sheets or two columns
|
|
36
|
-
match equally well.
|
|
37
|
-
5. Apply the smallest change that satisfies `requirement` with the mutation tools
|
|
38
|
-
(`tasks/edit-workbook.md`), re-render, and confirm the region now looks right.
|
|
21
|
+
1. `read_image` the attachment named `imageName`. It is the screenshot of the area the user marked: read the visible headers, row labels, and the numbers around the box.
|
|
22
|
+
2. `"<python>" "<cli>" xlsx read --input "<book.xlsx>" --json-out "<dump>.json"`, then match the visible values to sheets and A1 addresses. Values repeat across sheets more often than you expect — match on a combination (a row label plus two numbers), not on one number.
|
|
23
|
+
3. When the numbers are ambiguous, `container_tools/inspect_workbook.py` adds formulas, merges, tables, and names; formats often disambiguate ("the only column with a `%` format").
|
|
24
|
+
4. State what you resolved, in the user's terms: "`Pipeline!D2:D13`, the Amount column — 12 rows of whole dollars". Ask only if two sheets or two columns match equally well.
|
|
25
|
+
5. Apply the smallest change that satisfies `requirement` with the mutation tools (`tasks/edit-workbook.md`), re-render, and confirm the region now looks right.
|
|
39
26
|
|
|
40
27
|
## What not to do
|
|
41
28
|
|
|
42
|
-
- Do not compute a cell from the rectangle's coordinates. Header width, frozen
|
|
43
|
-
|
|
44
|
-
- Do not
|
|
45
|
-
|
|
46
|
-
-
|
|
47
|
-
surrounding convention and change the cells the requirement names.
|
|
48
|
-
- If the region covers a chart or a picture, the change is to the object, not the
|
|
49
|
-
cells behind it — check `charts`/`images` in the inspect output first.
|
|
50
|
-
- If nothing on the page carries the values in the screenshot, say which image
|
|
51
|
-
you looked at and what you could not locate. Do not guess a sheet.
|
|
29
|
+
- Do not compute a cell from the rectangle's coordinates. Header width, frozen panes, hidden columns, and zoom all move cells under the same pixel.
|
|
30
|
+
- Do not edit the first sheet because it was the default. The visible page may be the fourth sheet.
|
|
31
|
+
- Do not re-style the whole sheet to make the marked area consistent. Match the surrounding convention and change the cells the requirement names.
|
|
32
|
+
- If the region covers a chart or a picture, the change is to the object, not the cells behind it — check `charts`/`images` in the inspect output first.
|
|
33
|
+
- If nothing on the page carries the values in the screenshot, say which image you looked at and what you could not locate. Do not guess a sheet.
|
|
@@ -40,9 +40,9 @@
|
|
|
40
40
|
|
|
41
41
|
## Order of work
|
|
42
42
|
|
|
43
|
-
1. Sketch
|
|
44
|
-
2. Put
|
|
45
|
-
3. Write
|
|
43
|
+
1. Sketch sheets as roles, not tabs: inputs, calculations, outputs, checks. A five-line model belongs on one sheet with labelled blocks.
|
|
44
|
+
2. Put number formats on the cells, not on a copy of the values. `#,##0` for currency-ish amounts, `0.0%` for percentages, `yyyy-mm-dd` for real dates.
|
|
45
|
+
3. Write calculations as visible steps (quantity × rate, opening + movements = closing) and link the output to the build rather than repeating the arithmetic.
|
|
46
46
|
4. Add a chart only when it answers a comparison question the numbers alone answer slowly; see `references/charts.md`.
|
|
47
47
|
5. Render and read the PNG, then recalc if formulas exist.
|
|
48
48
|
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
## Pitfalls
|
|
61
61
|
|
|
62
62
|
- Values written through the CLI keep their type: `1840000` is a number, `"1,840,000"` is text and will not sum. Format numbers, never pre-format them as strings.
|
|
63
|
-
- A chart whose `max_row`
|
|
64
|
-
- `anchor` is where the chart's top-left corner sits; a chart outside the print area gets cut off by `xlsx render`. Put it below or beside the data inside the printed range.
|
|
63
|
+
- A chart whose `max_row` exceeds the data plots empty points as zero, which reads as a collapse to the floor. Match the range to the data.
|
|
64
|
+
- `anchor` is where the chart's top-left corner sits; a chart outside the print area gets cut off by `xlsx render`. Put it below or beside the data, inside the printed range.
|
|
65
65
|
- Dates must be real dates (`date(2026, 1, 31)` via a snippet, or Excel serial numbers), never `"Jan-26"` strings, or period filters fail silently.
|
|
66
66
|
- Set the font family explicitly if the file will be opened on another machine; a missing Calibri falls back to a serif in some renderers and every column width shifts.
|
|
@@ -25,8 +25,8 @@ Exit code `0` means the files match at the requested level, `1` means difference
|
|
|
25
25
|
|
|
26
26
|
Run it as `--before original --after original-edited` immediately after any edit, and read the "changed" sections as the diff you are about to describe to the user:
|
|
27
27
|
|
|
28
|
-
1.
|
|
29
|
-
2. A sheet, table, name, or chart
|
|
28
|
+
1. Cells you did not intend to touch are collateral damage — revert and redo with a narrower edit.
|
|
29
|
+
2. A sheet, table, name, or chart under "removed" is a lost object; rebuild it from `recipes/charts.md` / `recipes/named-ranges.md` before presenting.
|
|
30
30
|
3. Formatting-only differences across many rows usually mean a style object was reapplied to a range instead of a cell.
|
|
31
31
|
|
|
32
32
|
Diffing a file against itself is a useful sanity check that the tool and the file load cleanly: it should return `identical: true`.
|
|
@@ -5,7 +5,7 @@ The file is the specification. Read its conventions before writing a cell, then
|
|
|
5
5
|
## Procedure
|
|
6
6
|
|
|
7
7
|
1. `"<python>" "<cli>" xlsx read --input "<book.xlsx>" --json-out "<dump>.json"` — every sheet, its used range, and its formulas.
|
|
8
|
-
2. `"<python>" "<skill>/container_tools/inspect_workbook.py" --input "<book.xlsx>"` — what the read verb
|
|
8
|
+
2. `"<python>" "<skill>/container_tools/inspect_workbook.py" --input "<book.xlsx>"` — what the read verb hides: merged ranges, conditional formatting, defined names, Excel Tables, charts and their series, freeze panes, protections. It prints JSON; `--no-values` skips the second load that looks for cached results.
|
|
9
9
|
3. Render the sheets you are about to touch and look at them: `xlsx render`, then `read_image`. Match the surrounding format, not your personal default.
|
|
10
10
|
4. Apply the edit with the narrowest tool that fits (below), or with an openpyxl snippet when the change is not one of those shapes.
|
|
11
11
|
5. Read back and re-check structure, recalculate if formulas changed, render again, compare.
|
|
@@ -24,11 +24,11 @@ There is no `xlsx edit` verb. Each tool loads the workbook, changes only what yo
|
|
|
24
24
|
| Add a native chart | `add_chart.py --input "<book.xlsx>" --sheet Trend --type line --title "Monthly revenue (USD)" --anchor A6 --data-min-col 2 --data-min-row 3 --data-max-col 13 --data-max-row 3 --cat-min-row 2 --cat-max-row 2` |
|
|
25
25
|
| Embed an image | `add_image.py --input "<book.xlsx>" --sheet Cover --path logo.png --anchor B2 --width 320` |
|
|
26
26
|
|
|
27
|
-
Each tool writes `<input>-edited.xlsx` unless you pass `--out`, so chain by naming outputs
|
|
27
|
+
Each tool writes `<input>-edited.xlsx` unless you pass `--out`, so chain by naming outputs — never edit the file you just read and lose the step in between.
|
|
28
28
|
|
|
29
29
|
`cells.json` is `{"sheet": "Model", "cells": {"B3": 0.07, "D9": "=SUM(D2:D8)"}}` or a list of those. `styles.json` is `{"sheet": "Model", "styles": {"A11:B11": {"bold": true}, "C11:C14": {"number_format": "0.0%"}}}`.
|
|
30
30
|
|
|
31
|
-
Two tool limits are deliberate: `append_rows.py` does not extend an Excel Table, copy the formula from the row above, or grow a chart —
|
|
31
|
+
Two tool limits are deliberate: `append_rows.py` does not extend an Excel Table, copy the formula from the row above, or grow a chart — use a snippet from `recipes/data-tables.md` and `recipes/charts.md`, or the new rows sit outside the table and the chart stops at the old last row. `add_chart.py` treats a one-row data range as one series of many points (what a monthly row means) but cannot set axis number formats or series colours; fix those in the same snippet.
|
|
32
32
|
|
|
33
33
|
## What must survive an edit
|
|
34
34
|
|
|
@@ -48,7 +48,7 @@ New conditional formatting that covers a whole table must extend to the rows you
|
|
|
48
48
|
## Cells: the smallest change
|
|
49
49
|
|
|
50
50
|
- Write to the sheet and address you resolved; never "the first empty row" of an unnamed sheet.
|
|
51
|
-
- A text edit changes run-level text only
|
|
51
|
+
- A text edit changes run-level text only; the cell format stays unless the request names it.
|
|
52
52
|
- A number-format change is a format change, not a value change: do not replace `0.0649` with `6.5%` text.
|
|
53
53
|
- Do not autofit every column or restyle a table to fix one clipped cell. Widen the column, or shrink the font only for that block.
|
|
54
54
|
- Do not add spacer rows, helper sheets, or "Notes" tabs unless the request needs them.
|
|
@@ -66,4 +66,4 @@ If `xlsx read` shows `#REF!`, `#DIV/0!`, or a formula pointing at a sheet that n
|
|
|
66
66
|
"<python>" "<cli>" xlsx render --input "<book-edited.xlsx>" --out-dir "<render-dir>"
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
The diff is the closest thing to a guarantee that nothing else moved: it reports changed cells and formulas, changed formatting unless you pass `--no-formats`, and structure changes (sheets, merges, widths, tables, charts, defined names). Exit code `1` means differences — not failure. Use `--sheet` to narrow and `--limit` to cap the per-sheet cell list.
|
|
69
|
+
The diff is the closest thing to a guarantee that nothing else moved: it reports changed cells and formulas, changed formatting unless you pass `--no-formats`, and structure changes (sheets, merges, widths, tables, charts, defined names). Exit code `1` means differences — not failure. Use `--sheet` to narrow and `--limit` to cap the per-sheet cell list. Gate flags and exit codes: `tasks/recalc-and-check.md`.
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Two readers, different jobs:
|
|
4
4
|
|
|
5
|
-
- `"<python>" "<cli>" xlsx read --input "<book.xlsx>" [--data-only]` —
|
|
6
|
-
- `"<python>" "<skill>/container_tools/inspect_workbook.py" --input "<book.xlsx>"` — the structure around the cells: formats that govern how they read, objects
|
|
5
|
+
- `"<python>" "<cli>" xlsx read --input "<book.xlsx>" [--data-only]` — cell values per sheet, as arrays without coordinates. `--data-only` returns cached results instead of formula text.
|
|
6
|
+
- `"<python>" "<skill>/container_tools/inspect_workbook.py" --input "<book.xlsx>"` — the structure around the cells: the formats that govern how they read, the objects beside them, and whether the formulas were ever computed.
|
|
7
7
|
|
|
8
|
-
Run both before editing, and after
|
|
8
|
+
Run both before editing, and again after to prove nothing was lost.
|
|
9
9
|
|
|
10
10
|
## What the inspector reports
|
|
11
11
|
|
|
@@ -19,20 +19,20 @@ Run both before editing, and after editing to prove nothing was lost.
|
|
|
19
19
|
| `sheets[].print_area`, `freeze_panes`, `gridlines` | Layout choices a render will honour |
|
|
20
20
|
| `sheets[].merged` | Merged ranges; a value lives in the top-left cell only |
|
|
21
21
|
| `sheets[].tables` | Excel Table names and refs; rows appended below a `ref` land outside the table |
|
|
22
|
-
| `sheets[].charts[].anchor`, `.kind`, `.series` | Where a chart sits and what it plots; `anchor` outside `print_area`
|
|
22
|
+
| `sheets[].charts[].anchor`, `.kind`, `.series` | Where a chart sits and what it plots; an `anchor` outside `print_area` is cut off when printed |
|
|
23
23
|
| `sheets[].conditional_formats[].rules` | `type` (`cellIs`, `colorScale`, `dataBar`, `expression`), `operator`, `formula`, `priority`. A rule whose range stops short of new rows silently stops applying |
|
|
24
24
|
| `sheets[].data_validations` | Dropdowns and constraints an edit must preserve |
|
|
25
25
|
| `sheets[].hidden_rows`, `hidden_columns` | Content the user deliberately folded away |
|
|
26
26
|
| `sheets[].formulas.shared`, `.array`, `.data_tables` | Non-trivial formula storage; re-saving can materialise or drop these |
|
|
27
27
|
| `sheets[].values.cached`, `.missing`, `.errors` | How many formula cells carry a cached result, carry none, or carry an error value |
|
|
28
28
|
|
|
29
|
-
`--no-values` skips the second load that reads cached results (faster on big files, blind to whether formulas
|
|
29
|
+
`--no-values` skips the second load that reads cached results (faster on big files, blind to whether formulas ever computed). `--sample N` sets how many formula samples per sheet are printed (default 5).
|
|
30
30
|
|
|
31
31
|
## How to read it
|
|
32
32
|
|
|
33
33
|
- `values.missing` equal to `formulas.count` means nothing has ever calculated this file. Do not quote any formula result; recalculate first (`tasks/recalc-and-check.md`).
|
|
34
|
-
- `values.errors` non-empty is pre-existing damage (or a
|
|
35
|
-
- `container.pivot_tables > 0` or `has_vba_project: true` means a plain openpyxl rewrite is risky: back up, change the fewest cells possible,
|
|
34
|
+
- `values.errors` non-empty is pre-existing damage (or a deliberate `#N/A` sentinel). Report it; do not fix it unasked.
|
|
35
|
+
- `container.pivot_tables > 0` or `has_vba_project: true` means a plain openpyxl rewrite is risky: back up, change the fewest cells possible, re-inspect after saving.
|
|
36
36
|
- `formulas.shared > 0` means a spreadsheet app wrote the file; copy an existing formula down rather than inventing a new pattern.
|
|
37
|
-
- A
|
|
38
|
-
- `print_area` and chart `anchor`
|
|
37
|
+
- A huge `dimensions` with few real cells is a formatting artefact (fill applied to whole columns). Do not "clean" it; note it if the user asks why the file is slow.
|
|
38
|
+
- `print_area` and chart `anchor` explain most render surprises: charts clipped at the page edge, or whole data blocks missing from a PDF because they fall outside the print range.
|