dsh-office-kit 0.4.1 → 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 +120 -148
- package/assets/skills/excel-live-control/container_tools/live_excel.py +9 -0
- 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 +9 -9
- 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 +105 -29
- package/package.json +1 -1
- package/postinstall.mjs +58 -17
- package/python/office_cli.py +70 -7
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
# The COM object model behind a live edit
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
boundaries, and every object you hold is a proxy that re-reads state when you ask it.
|
|
6
|
-
That explains most of the rules below.
|
|
3
|
+
The target is an out-of-process COM server that owns a window. Each property read or write
|
|
4
|
+
is a remote call; each object is a proxy that re-reads state. That explains most rules here.
|
|
7
5
|
|
|
8
6
|
`container_tools/live_excel.py` wraps the common cases. Read this when the CLI has no verb
|
|
9
|
-
for
|
|
10
|
-
are extending the tool.
|
|
7
|
+
for the task, a failure is unexplained, or you extend the tool.
|
|
11
8
|
|
|
12
9
|
## Reaching the running instance
|
|
13
10
|
|
|
@@ -15,36 +12,33 @@ are extending the tool.
|
|
|
15
12
|
$app = [Runtime.InteropServices.Marshal]::GetActiveObject('Excel.Application')
|
|
16
13
|
```
|
|
17
14
|
|
|
18
|
-
-
|
|
19
|
-
Excel.Application` creates a new
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
|
|
24
|
-
- WPS
|
|
25
|
-
|
|
26
|
-
`
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
it stays invisible until something shows it, and it leaks until `Application.Quit()`.
|
|
15
|
+
- The only supported way to find a running instance. `New-Object -ComObject
|
|
16
|
+
Excel.Application` creates a new invisible one; never use it for user work.
|
|
17
|
+
- Only in Windows PowerShell 5.1 (`powershell.exe`); PowerShell 7 (`pwsh`) removed it,
|
|
18
|
+
which is why the tool shells out to `powershell.exe`.
|
|
19
|
+
- Nothing running raises `0x800401E3 (MK_E_UNAVAILABLE)`. Ask the user to open the
|
|
20
|
+
workbook; launch nothing.
|
|
21
|
+
- WPS registers `Ket.Application` and `Excel.Application`, so attaching does not prove
|
|
22
|
+
Microsoft Excel. `Application.Name`/`Version` are useless here (WPS reports `Microsoft
|
|
23
|
+
Excel` / `12.0`). Infer the product from `Application.Path`.
|
|
24
|
+
- The running-object table is per user session and outlives the creating process. A hidden
|
|
25
|
+
self-test instance stays attachable, invisible until shown, and leaks until
|
|
26
|
+
`Application.Quit()`.
|
|
31
27
|
|
|
32
28
|
## Addressing
|
|
33
29
|
|
|
34
30
|
`Application` → `Workbooks` → `Workbook` → `Sheets` → `Worksheet` → `Range`.
|
|
35
31
|
|
|
36
32
|
- Collections are **1-based**: `$book.Sheets.Item(1)`. `Item(0)` throws.
|
|
37
|
-
- `$sheet.Cells` is the whole sheet; `$sheet.UsedRange` is the rectangle
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
- A1 strings: `A1`, `B4:D9`, `$B$14`, `Sheet1!A1:C9`, `'Build Detail'!E14` (quote
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
spelling.
|
|
47
|
-
- Multi-area ranges (`A1:A5,C1:C5`) exist; the tool refuses them for writes because a
|
|
33
|
+
- `$sheet.Cells` is the whole sheet; `$sheet.UsedRange` is the rectangle holding content or
|
|
34
|
+
formatting. Clearing the last cell does not shrink it: a read hint, never an edit
|
|
35
|
+
boundary.
|
|
36
|
+
- A1 strings: `A1`, `B4:D9`, `$B$14`, `Sheet1!A1:C9`, `'Build Detail'!E14` (quote names
|
|
37
|
+
with spaces). `$r.Address(0,0)` gives `A1:C3`; report the absolute form the user can
|
|
38
|
+
paste into the Name Box.
|
|
39
|
+
- Sheet-name matching is case-insensitive in .NET but exact for COM:
|
|
40
|
+
`$book.Sheets.Item('Build')` throws on `build`. Use `Worksheet.Name` for spelling.
|
|
41
|
+
- Multi-area ranges (`A1:A5,C1:C5`) exist; the tool refuses them for writes because one
|
|
48
42
|
rectangular `Value2` assignment cannot fill them.
|
|
49
43
|
|
|
50
44
|
## Cells: what you write and what comes back
|
|
@@ -52,156 +46,136 @@ $app = [Runtime.InteropServices.Marshal]::GetActiveObject('Excel.Application')
|
|
|
52
46
|
| Property | Use it for | Reads back |
|
|
53
47
|
| --- | --- | --- |
|
|
54
48
|
| `Range.Value2` | every value: numbers, text, dates (as serials), booleans, arrays | typed scalars / `Object[,]` |
|
|
55
|
-
| `Range.Formula` | formulas in A1 notation; also
|
|
49
|
+
| `Range.Formula` | formulas in A1 notation; also how to read them back | `String`, e.g. `=SUM(B2:B9)` |
|
|
56
50
|
| `Range.FormulaR1C1` | fills where you think in offsets | `String` |
|
|
57
|
-
| `Range.Text` | the
|
|
58
|
-
|
|
59
|
-
- **`Value2`
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
-
|
|
66
|
-
you are writing.
|
|
67
|
-
- A multi-cell read returns a 2-D `Object[,]` with **1-based** indices. A single cell
|
|
51
|
+
| `Range.Text` | the displayed string, after number format | per-cell only |
|
|
52
|
+
|
|
53
|
+
- **`Value2` preserves type and ignores locale.** A `Double` stays a number, a `String`
|
|
54
|
+
stays text — unless the app parses it as a date, currency, or `=1+1`. `"2026-01-31"`
|
|
55
|
+
written through `Value2` produced serial `46053` in a date-formatted cell. For literal
|
|
56
|
+
text, store the serial/number and set a number format, or prefix the apostrophe. Never
|
|
57
|
+
rely on the parse.
|
|
58
|
+
- **`$null` empties a cell**, the supported way to clear one value inside a written block.
|
|
59
|
+
- A multi-cell read returns a 2-D `Object[,]` with **1-based** indices; a single cell
|
|
68
60
|
returns a scalar, so code that always indexes `[1,1]` fails on one-cell ranges.
|
|
69
|
-
- **Errors
|
|
70
|
-
`-
|
|
71
|
-
`-
|
|
72
|
-
`
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
-
|
|
82
|
-
|
|
83
|
-
- Formulas are text. There is no calculation on write; the value updates when the
|
|
84
|
-
application recalculates, which is why `recalc` exists.
|
|
61
|
+
- **Errors are integers.** `#DIV/0!` is Int32 SCODE `-2146826281`; `#VALUE!` `-2146826273`,
|
|
62
|
+
`#REF!` `-2146826265`, `#NAME?` `-2146826259`, `#NUM!` `-2146826252`, `#N/A`
|
|
63
|
+
`-2146826246`. WPS returns `False` from `WorksheetFunction.IsError` and throws on
|
|
64
|
+
`SpecialCells(16)`, so test "is this an Int32?", then read `Range.Text`,
|
|
65
|
+
`Range.Formula`, `Range.Address(0,0)` for that cell alone.
|
|
66
|
+
- `Range.Text` is per-cell; on a multi-cell range WPS returns `DBNull`, so the tool reads
|
|
67
|
+
cell by cell (hence the `--display` cap).
|
|
68
|
+
- **One formula assigned to a range fills with relative adjustment**: `A1:A3` = `=B1`
|
|
69
|
+
gives `=B1`, `=B2`, `=B3`. Cheap for a column, and how unintended formulas appear on
|
|
70
|
+
multi-cell targets.
|
|
71
|
+
- Dates are serials (`days since 1899-12-30`, 1900 system). `DateSerial(y,m,d)` gives the
|
|
72
|
+
number; `NumberFormat` gives the look.
|
|
73
|
+
- Formulas are text. Nothing calculates on write; values update on recalc, which is why
|
|
74
|
+
`recalc` exists.
|
|
85
75
|
|
|
86
76
|
## Number formats
|
|
87
77
|
|
|
88
|
-
`Range.NumberFormat` takes
|
|
89
|
-
`
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
- Format is display only
|
|
95
|
-
|
|
96
|
-
- One format per column
|
|
97
|
-
|
|
98
|
-
-
|
|
99
|
-
|
|
100
|
-
- `###`
|
|
101
|
-
|
|
102
|
-
`EntireColumn.AutoFit()`, and check the result with `--display`.
|
|
78
|
+
`Range.NumberFormat` takes codes, not locales: `#,##0`, `#,##0.00`, `0.0%`, `"$"#,##0.00`,
|
|
79
|
+
`mmm-yy`, `d-mmm`, `@`. Use invariant ASCII; the dot is always the decimal point inside a
|
|
80
|
+
code, whatever `Application.DecimalSeparator` says. WPS returns empty
|
|
81
|
+
`DecimalSeparator`/`ThousandsSeparator`: never read locale from the app or build codes from
|
|
82
|
+
locale data.
|
|
83
|
+
|
|
84
|
+
- Format is display only; values keep full precision. Never round data to make it read
|
|
85
|
+
right.
|
|
86
|
+
- One format per column; mixing `#,##0` and `#,##0.00` down a column is the commonest
|
|
87
|
+
visual defect.
|
|
88
|
+
- Precision belongs in the code: `0.0%` for analytical tables, `0%` for dashboards,
|
|
89
|
+
`0.00%` when differences are small.
|
|
90
|
+
- `###` means too narrow, not wrong. Widen with `ColumnWidth` (default ~8.43) or
|
|
91
|
+
`EntireColumn.AutoFit()`, then check with `--display`.
|
|
103
92
|
|
|
104
93
|
## Colour is BGR
|
|
105
94
|
|
|
106
|
-
`Interior.Color` and `Font.Color` are OLE
|
|
107
|
-
spec in this repo is `#RRGGBB`. Convert explicitly:
|
|
95
|
+
`Interior.Color` and `Font.Color` are OLE longs `0xBBGGRR`; specs are `#RRGGBB`:
|
|
108
96
|
|
|
109
97
|
```
|
|
110
98
|
ole = red + green * 256 + blue * 65536 # #RRGGBB -> BGR long
|
|
111
99
|
```
|
|
112
100
|
|
|
113
|
-
`#C00000` becomes `192`;
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
existing colours rather than inventing one.
|
|
101
|
+
`#C00000` becomes `192`; pure blue fill is `16711680`. `ColorIndex = -4142` removes a fill
|
|
102
|
+
(`Interior.Color` then reads `16777215`). Theme colours and tints are not addressable;
|
|
103
|
+
reuse existing workbook colours.
|
|
117
104
|
|
|
118
105
|
## Font, borders, alignment, layout
|
|
119
106
|
|
|
120
107
|
- `Range.Font`: `Name`, `Size`, `Bold`, `Italic`, `Color`, `Underline`, `Strikethrough`.
|
|
121
|
-
One family
|
|
122
|
-
|
|
123
|
-
- `Range.Borders.Item(index)`: 7 left, 8 top, 9 bottom, 10 right; `LineStyle` (1
|
|
124
|
-
`Weight` (2 thin), `Color`. `BorderAround(1, 2)` draws a thin outline in one
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
- Whole-sheet `AutoFit` and `Select`/`Activate`
|
|
134
|
-
|
|
135
|
-
user who is looking at the window.
|
|
108
|
+
One family per sheet: Helvetica Neue → Helvetica → Arial → Aptos, whichever the workbook
|
|
109
|
+
uses.
|
|
110
|
+
- `Range.Borders.Item(index)`: 7 left, 8 top, 9 bottom, 10 right; `LineStyle` (1
|
|
111
|
+
continuous), `Weight` (2 thin), `Color`. `BorderAround(1, 2)` draws a thin outline in one
|
|
112
|
+
call.
|
|
113
|
+
- `HorizontalAlignment` takes `xlHAlign*` (`-4131` left, `-4108` center, `-4152` right);
|
|
114
|
+
`VerticalAlignment` takes `xlVAlign*` (`-4160` top, `-4108` center, `-4104` bottom). The
|
|
115
|
+
tool maps readable names.
|
|
116
|
+
- Also: `Merge()`, `UnMerge()`, `WrapText`, `IndentLevel`, `EntireColumn.ColumnWidth`,
|
|
117
|
+
`Tab.Color`, `Rows.Hidden`.
|
|
118
|
+
- `FreezePanes` lives on `Window` and did not stick on a hidden WPS instance. No freeze
|
|
119
|
+
verb: tell the user, or do it visibly.
|
|
120
|
+
- Whole-sheet `AutoFit` and `Select`/`Activate` change the user's view, can take seconds,
|
|
121
|
+
and `ScreenUpdating` does not hide the flicker.
|
|
136
122
|
|
|
137
123
|
## Objects beside the cells
|
|
138
124
|
|
|
139
|
-
- **Tables**: `$sheet.ListObjects.Add(1, $range, [Type]::Missing, $has_headers)
|
|
140
|
-
|
|
141
|
-
`
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
rather than adding a second one over the same cells.
|
|
125
|
+
- **Tables**: `$sheet.ListObjects.Add(1, $range, [Type]::Missing, $has_headers)`.
|
|
126
|
+
PowerShell cannot reproduce VBA's empty argument positions, so pass `[Type]::Missing` for
|
|
127
|
+
`Destination`. Tables get localized default names (`表1`); name them. `has_headers = 0`
|
|
128
|
+
makes the app generate a header row above the data, shifting values down and making the
|
|
129
|
+
table one row taller than the range. Extend with `ListObject.Resize`, never a second
|
|
130
|
+
table.
|
|
146
131
|
- **Charts**: `$sheet.ChartObjects().Add(left, top, width, height)` → `.Chart` →
|
|
147
|
-
`.SetSourceData($range)` + `.ChartType
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
- **
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
- **Conditional formats**: `Range.FormatConditions`. Appending a condition to a range
|
|
161
|
-
that already has one edits the *existing* set; a "fix" here can silently change rules
|
|
162
|
-
the user depends on. Read first, and keep the range bounded.
|
|
163
|
-
- **Validation**: `Range.Validation` — same rule. Read the existing rule before writing a
|
|
164
|
-
new one.
|
|
132
|
+
`.SetSourceData($range)` + `.ChartType`; `HasTitle`/`ChartTitle.Text` set the title.
|
|
133
|
+
Types: column 51, stacked column 52, bar 57, stacked bar 58, line 4, line with markers
|
|
134
|
+
65, area 1, stacked area 76, pie 5, doughnut -4120, scatter -4169, scatter with lines 74.
|
|
135
|
+
A chart over an empty range renders blank; check the source cells.
|
|
136
|
+
- **Shapes**: `Shapes.AddShape(...)`, `AddTextbox`, `AddPicture`. They float over cells, sit
|
|
137
|
+
outside the used range, and need `TopLeftCell` anchoring to move with data.
|
|
138
|
+
- **Pivots**: `PivotTables`, `PivotFields`. Read and report; never rebuild through COM
|
|
139
|
+
unless asked — a failed attempt loses the layout.
|
|
140
|
+
- **Names**: `$workbook.Names`, `Range.Name`. Deleting their cells breaks names (`#REF!`),
|
|
141
|
+
so a rename or row delete is a contract change.
|
|
142
|
+
- **Conditional formats**: `Range.FormatConditions`. Appending to a range with an existing
|
|
143
|
+
condition edits that set; read first, keep the range bounded.
|
|
144
|
+
- **Validation**: `Range.Validation`; read the existing rule before writing.
|
|
165
145
|
|
|
166
146
|
## Calculation and freshness
|
|
167
147
|
|
|
168
|
-
- `Application.Calculation`: `-4105` automatic, `-4135` manual.
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
- `CalculateFull` recalculates dependencies, not just the active sheet.
|
|
172
|
-
rebuilds the
|
|
173
|
-
slow on
|
|
174
|
-
-
|
|
175
|
-
|
|
176
|
-
succeed.
|
|
148
|
+
- `Application.Calculation`: `-4105` automatic, `-4135` manual. Manual mode shows stale
|
|
149
|
+
numbers after an edit; `recalc` runs `CalculateFull` on every open workbook and reports
|
|
150
|
+
the mode.
|
|
151
|
+
- `CalculateFull` recalculates dependencies, not just the active sheet.
|
|
152
|
+
`CalculateFullRebuild` rebuilds the tree; use it only when a value looks impossible — it
|
|
153
|
+
is slow on large models.
|
|
154
|
+
- Iteration (`Application.Iteration`) is off by default. Circular references that "worked"
|
|
155
|
+
mean it was on; do not enable it to make an edit succeed.
|
|
177
156
|
|
|
178
157
|
## Latency, failures, retries
|
|
179
158
|
|
|
180
|
-
- Every property access is an RPC.
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
-
|
|
187
|
-
- `
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
- **Nothing is transactional.** A call that fails halfway leaves the cells it already
|
|
197
|
-
wrote. The retry protocol is: `read_range` the block, compare with intent, write only
|
|
198
|
-
what is missing or wrong. Replaying the same batch is how a live document gets
|
|
199
|
-
duplicated rows.
|
|
159
|
+
- Every property access is an RPC. `info` plus three reads took 1.2–1.5 s here; formatting
|
|
160
|
+
100 cells one at a time can take tens of seconds. **Batch**: one `write_range` per block,
|
|
161
|
+
one `style_range` per range, one `set_formula` per column. Never loop per cell.
|
|
162
|
+
- Default timeout is 180 s. Raising it is fine for a big paste; below 1 s fails on a busy
|
|
163
|
+
app.
|
|
164
|
+
- Failures you meet:
|
|
165
|
+
- `0x800401E3` — nothing running. Ask the user to open the workbook.
|
|
166
|
+
- `0x8001010A` (RPC_E_SERVERCALL_RETRYLATER) — app busy (dialog, recalculation, dragged
|
|
167
|
+
window). Read again; if it persists, tell the user a dialog is blocking it.
|
|
168
|
+
- "Object required" / stale proxy — usually the workbook was closed. Re-attach by name;
|
|
169
|
+
never reuse the old object.
|
|
170
|
+
- An Excel method raising "does not contain a method named …" in WPS: the WPS model is a
|
|
171
|
+
subset. Fall back to a simpler route (formatting via `Value2`/`NumberFormat`).
|
|
172
|
+
- **Nothing is transactional.** A half-failing call leaves written cells. Retry:
|
|
173
|
+
`read_range` the block, compare with intent, write only what is missing or wrong.
|
|
174
|
+
Replaying a batch duplicates rows.
|
|
200
175
|
|
|
201
176
|
## The one rule that outranks the rest
|
|
202
177
|
|
|
203
|
-
A live edit mutates a document the user is looking at
|
|
204
|
-
**Read and diff before writing.** `read_range` the target with `--formulas`; note
|
|
205
|
-
`
|
|
206
|
-
|
|
207
|
-
work is more important than finishing the task.
|
|
178
|
+
A live edit mutates a document the user is looking at, possibly with unsaved changes.
|
|
179
|
+
**Read and diff before writing.** `read_range` the target with `--formulas`; note
|
|
180
|
+
`saved: false` from `info`; then make the smallest write that satisfies the request. If the
|
|
181
|
+
diff shows unexpected values, stop and ask — unsaved user work outranks finishing the task.
|
|
@@ -1,59 +1,54 @@
|
|
|
1
1
|
# Answering questions about a workbook the user has open
|
|
2
2
|
|
|
3
|
-
Read-only
|
|
4
|
-
|
|
3
|
+
Read-only: no writes, no saves, no restyling. Deliver an answer with cell references the
|
|
4
|
+
user can check, not a changed document.
|
|
5
5
|
|
|
6
6
|
## Reading
|
|
7
7
|
|
|
8
|
-
- `info` first: which workbook,
|
|
9
|
-
|
|
10
|
-
- `read_range --formulas` for the cells that matter.
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
- `read_range --display` when the question is
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
- Read the workbook's
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
you read are the user's unsaved state; say so if the answer would differ from the file.
|
|
8
|
+
- `info` first: which workbook, sheets, used ranges, tables, charts, pivots — and whether
|
|
9
|
+
the thing asked about exists.
|
|
10
|
+
- `read_range --formulas` for the cells that matter. The value says *what*; the formula
|
|
11
|
+
says *why*. A number with no formula is a typed input; a formula with no precedent is
|
|
12
|
+
untrustworthy.
|
|
13
|
+
- `read_range --display` when the question is how something *reads* (`###`, a truncated
|
|
14
|
+
label, a date shown as a serial): displayed text follows the number format, values do
|
|
15
|
+
not.
|
|
16
|
+
- Read the workbook's labels — headers, periods, "Actual" vs "Forecast", units — before
|
|
17
|
+
interpreting a cell. `D14` means nothing without "Q3 advertising spend, USD".
|
|
18
|
+
- The window may be ahead of the file. `info` showing `saved: false` means you are reading
|
|
19
|
+
the user's unsaved state; say so when the answer would differ.
|
|
21
20
|
|
|
22
21
|
## Answering
|
|
23
22
|
|
|
24
|
-
1. **Locate the output by its labels**, not by
|
|
25
|
-
the
|
|
26
|
-
2. **Trace the precedent chain** back
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
3. **Reconcile before asserting.** If a total
|
|
30
|
-
|
|
31
|
-
4. **Compute from
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
data rather than a copy, a formula chain rather than a paste), and do not "fix" either
|
|
40
|
-
without being asked.
|
|
23
|
+
1. **Locate the output by its labels**, not by guessing: find the metric's row/column and
|
|
24
|
+
the period, then read the intersection.
|
|
25
|
+
2. **Trace the precedent chain** back to labelled assumptions or raw inputs. Use
|
|
26
|
+
`read_range --formulas` at each step; stop at typed cells. Reporting an intermediate
|
|
27
|
+
total as the cause is the classic error.
|
|
28
|
+
3. **Reconcile before asserting.** If a total is not the sum of its parts, that is the
|
|
29
|
+
finding: report the gap and the cells; do not average it away.
|
|
30
|
+
4. **Compute from underlying values.** A cell showing `1.2` may hold `1.2345`; use the
|
|
31
|
+
stored value, and say so if the requested precision forces the displayed one.
|
|
32
|
+
5. **Rank drivers** by absolute contribution for "why did it move": the top two or three,
|
|
33
|
+
with cells and amounts, not everything.
|
|
34
|
+
6. **Cite cells**: `` `Summary!D14` shows 1,234 units because `Build!F7:F12` sums to that ``.
|
|
35
|
+
A claim without an address is unverifiable.
|
|
36
|
+
7. Sheets disagree: say which you believe and why (more recent period, source over copy,
|
|
37
|
+
formula chain over paste) and do not "fix" either unasked.
|
|
41
38
|
|
|
42
39
|
## Sensitive reviews
|
|
43
40
|
|
|
44
|
-
Clinical records, payroll
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
personal data, say what you can answer instead.
|
|
41
|
+
Clinical records, payroll/compensation, customer-level data: answer at the level asked and
|
|
42
|
+
no lower. Inspect structure, formats, dependency chains and formulas as evidence; do not
|
|
43
|
+
echo restricted values unless the user needs that figure to act. If the question cannot be
|
|
44
|
+
answered without exposing personal data, say what you can answer instead.
|
|
49
45
|
|
|
50
46
|
## Limits
|
|
51
47
|
|
|
52
|
-
- Do not equate the live window with the saved file,
|
|
53
|
-
|
|
54
|
-
-
|
|
55
|
-
|
|
56
|
-
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
cell, the formula and what it broke.
|
|
48
|
+
- Do not equate the live window with the saved file, or present a read-only answer as
|
|
49
|
+
verified against disk.
|
|
50
|
+
- External links, volatile functions (`NOW()`, `RAND()`) or an unrefreshed pivot cache make
|
|
51
|
+
the number provisional; say so.
|
|
52
|
+
- Protected sheets: reads work; report the protection, do not work around it.
|
|
53
|
+
- `#REF!`, `#DIV/0!` and friends are part of the answer: name the cell, the formula and what
|
|
54
|
+
it broke.
|