@sheetxl/primitives 0.7.28-beta.4 → 0.8.0-beta.10
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/browser/esm/index.mjs +101 -55
- package/node/esm/index.mjs +115 -67
- package/package.json +3 -4
- package/types/src/ErrorPolicy.d.ts +48 -57
- package/types/src/Flatten.d.ts +6 -3
- package/types/src/FormulaContext.d.ts +47 -7
- package/types/src/IFormulaContext.d.ts +223 -11
- package/types/src/IFunction.d.ts +368 -39
- package/types/src/IFunctionArguments.d.ts +214 -0
- package/types/src/IRange.d.ts +199 -40
- package/types/src/IRangeStats.d.ts +34 -3
- package/types/src/IRuntime.d.ts +24 -1
- package/types/src/Lazy.d.ts +76 -0
- package/types/src/NoFilter.d.ts +34 -0
- package/types/src/NoLift.d.ts +31 -0
- package/types/src/Repeating.d.ts +24 -4
- package/types/src/ReportType.d.ts +42 -0
- package/types/src/Scalar.d.ts +1 -1
- package/types/src/ValueKind.d.ts +43 -0
- package/types/src/Volatile.d.ts +12 -0
- package/types/src/WildCard.d.ts +13 -9
- package/types/src/index.d.ts +7 -0
- package/browser/cjs/index.cjs +0 -1
|
@@ -3,6 +3,7 @@ import { FormulaError } from './FormulaError';
|
|
|
3
3
|
import { IRange } from './IRange';
|
|
4
4
|
import { IReferenceRange } from './IReferenceRange';
|
|
5
5
|
import { IFunction } from './IFunction';
|
|
6
|
+
import { IFunctionArguments } from './IFunctionArguments';
|
|
6
7
|
import { IFormulaContext } from './IFormulaContext';
|
|
7
8
|
import { IRuntime } from './IRuntime';
|
|
8
9
|
import { LocaleProfile } from './LocaleProfile';
|
|
@@ -20,6 +21,8 @@ import { LocaleProfile } from './LocaleProfile';
|
|
|
20
21
|
export declare class StubbedFormulaContext implements IFormulaContext {
|
|
21
22
|
/** @inheritdoc IFormulaContext.createRange */
|
|
22
23
|
createRange<TS extends Scalar = Scalar>(rows?: number, columns?: number, values?: Scalar | Scalar[][] | ((value: TS, coords: IRange.CellCoords, range: IRange<TS>) => TS)): IRange;
|
|
24
|
+
/** @inheritdoc IFormulaContext.flattenAreas */
|
|
25
|
+
flattenAreas(value: IRange | IRange[]): IRange;
|
|
23
26
|
/** @inheritdoc IFormulaContext.getReference */
|
|
24
27
|
getReference(coords?: Readonly<IRange.Coords>, r1c1?: boolean): IReferenceRange;
|
|
25
28
|
/** @inheritdoc IFormulaContext.getResizedReference */
|
|
@@ -36,6 +39,8 @@ export declare class StubbedFormulaContext implements IFormulaContext {
|
|
|
36
39
|
getSerialDate(year: number, month: number, day: number, hour?: number, minute?: number, second?: number, millis?: number): number;
|
|
37
40
|
/** @inheritdoc IFormulaContext.getNow */
|
|
38
41
|
getNow(): number;
|
|
42
|
+
/** @inheritdoc IFormulaContext.getRandom */
|
|
43
|
+
getRandom(): number;
|
|
39
44
|
/** @inheritdoc IFormulaContext.getValueAt */
|
|
40
45
|
getValueAt(row: number, column: number, sheetName?: string, options?: IRange.ValueOptions): Scalar | null;
|
|
41
46
|
/** @inheritdoc IFormulaContext.getEntireCoords */
|
|
@@ -46,6 +51,8 @@ export declare class StubbedFormulaContext implements IFormulaContext {
|
|
|
46
51
|
getRow(): number;
|
|
47
52
|
/** @inheritdoc IFormulaContext.getColumn */
|
|
48
53
|
getColumn(): number;
|
|
54
|
+
/** @inheritdoc IFormulaContext.isImplicitIntersect */
|
|
55
|
+
isImplicitIntersect(): boolean;
|
|
49
56
|
/** @inheritdoc IFormulaContext.getFormulaAt */
|
|
50
57
|
getFormulaAt(row: number, column: number, sheetName?: string): string | null;
|
|
51
58
|
/** @inheritdoc IFormulaContext.getSpillAt */
|
|
@@ -59,7 +66,7 @@ export declare class StubbedFormulaContext implements IFormulaContext {
|
|
|
59
66
|
/** @inheritdoc IFormulaContext.formatResults */
|
|
60
67
|
formatResults(numFmt: string): void;
|
|
61
68
|
/** @inheritdoc IFormulaContext.filterHidden */
|
|
62
|
-
filterHidden(range: IRange,
|
|
69
|
+
filterHidden(range: IRange, options?: IFormulaContext.FilterHiddenOptions): IRange;
|
|
63
70
|
/** @inheritdoc IFormulaContext.filterTotals */
|
|
64
71
|
filterTotals(range: IRange): IRange;
|
|
65
72
|
/** @inheritdoc IFormulaContext.getFunction */
|
|
@@ -82,7 +89,14 @@ export declare class StubbedFormulaContext implements IFormulaContext {
|
|
|
82
89
|
* plausibly and wrongly, where throwing names the actual mistake (evaluating criteria outside an
|
|
83
90
|
* installed scope).
|
|
84
91
|
*/
|
|
85
|
-
createCriteria(criteria: Scalar): IFormulaContext.CriteriaEvaluator;
|
|
92
|
+
createCriteria(criteria: Scalar, options?: IFormulaContext.CriteriaOptions): IFormulaContext.CriteriaEvaluator;
|
|
93
|
+
/**
|
|
94
|
+
* Unimplemented. See {@link IFormulaContext.createGrouping}.
|
|
95
|
+
*
|
|
96
|
+
* @remarks
|
|
97
|
+
* Grouping needs Excel's key equality, which this stub does not have.
|
|
98
|
+
*/
|
|
99
|
+
createGrouping(keys: IRange, options?: IFormulaContext.GroupingOptions): IFormulaContext.Grouping;
|
|
86
100
|
/**
|
|
87
101
|
* Parses the canonical English boolean and error literals.
|
|
88
102
|
* See {@link IFormulaContext.parseAsLiteral}.
|
|
@@ -127,6 +141,8 @@ export declare class StubbedFormulaContext implements IFormulaContext {
|
|
|
127
141
|
compare(a: Scalar, b: Scalar, options?: Intl.CollatorOptions): number;
|
|
128
142
|
/** @inheritdoc IFormulaContext.getRuntime */
|
|
129
143
|
getRuntime(): IRuntime;
|
|
144
|
+
/** @inheritdoc IFormulaContext.getArgs */
|
|
145
|
+
getArgs(): IFunctionArguments;
|
|
130
146
|
}
|
|
131
147
|
/**
|
|
132
148
|
* The single, shared {@link IFormulaContext} that formula implementations use (via
|
|
@@ -144,6 +160,18 @@ export declare class ScopedFormulaContext implements IFormulaContext {
|
|
|
144
160
|
_setScope(scope: Partial<IFormulaContext> | null): void;
|
|
145
161
|
/** @hidden */
|
|
146
162
|
_getScope(): Partial<IFormulaContext>;
|
|
163
|
+
/**
|
|
164
|
+
* @hidden Installed ONCE by the runtime marshaller; answers {@link getArgs} for whichever call
|
|
165
|
+
* is currently dispatching, or `null` when none is.
|
|
166
|
+
*
|
|
167
|
+
* @remarks
|
|
168
|
+
* A provider rather than a stack because the marshaller already pools one view per dispatch
|
|
169
|
+
* DEPTH and knows the current depth. Reading a function pointer costs nothing for the ~99% of
|
|
170
|
+
* calls whose body never asks.
|
|
171
|
+
*/
|
|
172
|
+
protected _argsFn: (() => IFunctionArguments | null) | null;
|
|
173
|
+
/** @hidden */
|
|
174
|
+
_setArgsProvider(provider: (() => IFunctionArguments | null) | null): void;
|
|
147
175
|
/** @inheritdoc IFormulaContext.getNumberFormat */
|
|
148
176
|
getNumberFormat(formatText: string, value: Scalar): string | null;
|
|
149
177
|
/** @inheritdoc IFormulaContext.getEntireCoords */
|
|
@@ -156,7 +184,9 @@ export declare class ScopedFormulaContext implements IFormulaContext {
|
|
|
156
184
|
parseAsNumber(textOrNumber: Scalar, options?: IFormulaContext.ParseNumberOptions): number;
|
|
157
185
|
parseAsNumber(textOrNumber: Scalar | undefined, options?: IFormulaContext.ParseNumberOptions): number | undefined;
|
|
158
186
|
/** @inheritdoc IFormulaContext.createCriteria */
|
|
159
|
-
createCriteria(criteria: Scalar): IFormulaContext.CriteriaEvaluator;
|
|
187
|
+
createCriteria(criteria: Scalar, options?: IFormulaContext.CriteriaOptions): IFormulaContext.CriteriaEvaluator;
|
|
188
|
+
/** @inheritdoc IFormulaContext.createGrouping */
|
|
189
|
+
createGrouping(keys: IRange, options?: IFormulaContext.GroupingOptions): IFormulaContext.Grouping;
|
|
160
190
|
/** @inheritdoc IFormulaContext.parseAsLiteral */
|
|
161
191
|
parseAsLiteral(text: string): boolean | FormulaError.Known | undefined;
|
|
162
192
|
/** @inheritdoc IFormulaContext.toText */
|
|
@@ -173,12 +203,18 @@ export declare class ScopedFormulaContext implements IFormulaContext {
|
|
|
173
203
|
getSerialDate(year: number, month: number, day: number, hour?: number, minute?: number, second?: number, millis?: number): number;
|
|
174
204
|
/** @inheritdoc IFormulaContext.getNow */
|
|
175
205
|
getNow(): number;
|
|
206
|
+
/** @inheritdoc IFormulaContext.getRandom */
|
|
207
|
+
getRandom(): number;
|
|
176
208
|
/** @inheritdoc IFormulaContext.createRange */
|
|
177
209
|
createRange<TS extends Scalar = Scalar>(rows?: number, columns?: number, values?: Scalar | Scalar[][] | ((value: TS, coords: IRange.CellCoords, range: IRange<TS>) => TS)): IRange;
|
|
210
|
+
/** @inheritdoc IFormulaContext.flattenAreas */
|
|
211
|
+
flattenAreas(value: IRange | IRange[]): IRange;
|
|
178
212
|
/** @inheritdoc IFormulaContext.getRow */
|
|
179
213
|
getRow(): number;
|
|
180
214
|
/** @inheritdoc IFormulaContext.getColumn */
|
|
181
215
|
getColumn(): number;
|
|
216
|
+
/** @inheritdoc IFormulaContext.isImplicitIntersect */
|
|
217
|
+
isImplicitIntersect(): boolean;
|
|
182
218
|
/** @inheritdoc IFormulaContext.getReference */
|
|
183
219
|
getReference(coords?: Readonly<IRange.Coords>, r1c1?: boolean): IReferenceRange;
|
|
184
220
|
/** @inheritdoc IFormulaContext.getResizedReference */
|
|
@@ -198,7 +234,7 @@ export declare class ScopedFormulaContext implements IFormulaContext {
|
|
|
198
234
|
/** @inheritdoc IFormulaContext.formatResults */
|
|
199
235
|
formatResults(numFmt: string): void;
|
|
200
236
|
/** @inheritdoc IFormulaContext.filterHidden */
|
|
201
|
-
filterHidden(range: IRange,
|
|
237
|
+
filterHidden(range: IRange, options?: IFormulaContext.FilterHiddenOptions): IRange;
|
|
202
238
|
/** @inheritdoc IFormulaContext.filterTotals */
|
|
203
239
|
filterTotals(range: IRange): IRange;
|
|
204
240
|
/** @inheritdoc IFormulaContext.getFunction */
|
|
@@ -209,19 +245,23 @@ export declare class ScopedFormulaContext implements IFormulaContext {
|
|
|
209
245
|
compare(a: Scalar, b: Scalar, options?: Intl.CollatorOptions): number;
|
|
210
246
|
/** @inheritdoc IFormulaContext.getRuntime */
|
|
211
247
|
getRuntime(): IRuntime;
|
|
248
|
+
/** @inheritdoc IFormulaContext.getArgs */
|
|
249
|
+
getArgs(): IFunctionArguments;
|
|
212
250
|
get [Symbol.toStringTag](): string;
|
|
213
251
|
toString(): string;
|
|
214
252
|
}
|
|
215
253
|
/**
|
|
216
254
|
* A plain en-US profile, for stubs and for environments without `Intl`.
|
|
217
255
|
*
|
|
218
|
-
* @
|
|
219
|
-
*
|
|
220
|
-
* `makeLocaleProfile` in `@sheetxl/sdk`.
|
|
256
|
+
* @internal
|
|
257
|
+
* @hidden
|
|
221
258
|
*/
|
|
222
259
|
export declare const DEFAULT_LOCALE_PROFILE: LocaleProfile;
|
|
223
260
|
/**
|
|
224
261
|
* The shared {@link IFormulaContext} for formula implementations. See {@link ScopedFormulaContext}.
|
|
262
|
+
*
|
|
263
|
+
* @internal
|
|
264
|
+
* @hidden
|
|
225
265
|
*/
|
|
226
266
|
export declare const FormulaContext: IFormulaContext;
|
|
227
267
|
//# sourceMappingURL=FormulaContext.d.ts.map
|
|
@@ -3,6 +3,7 @@ import { FormulaError } from './FormulaError';
|
|
|
3
3
|
import { IRange } from './IRange';
|
|
4
4
|
import { IReferenceRange } from './IReferenceRange';
|
|
5
5
|
import { IFunction } from './IFunction';
|
|
6
|
+
import { IFunctionArguments } from './IFunctionArguments';
|
|
6
7
|
import { IRuntime } from './IRuntime';
|
|
7
8
|
/**
|
|
8
9
|
* Everything a formula function is allowed to know about the world outside its arguments.
|
|
@@ -27,14 +28,16 @@ import { IRuntime } from './IRuntime';
|
|
|
27
28
|
*
|
|
28
29
|
* | Category | Key methods |
|
|
29
30
|
* |---|---|
|
|
30
|
-
* | Evaluation lifecycle | `markVolatile`, `getRow`, `getColumn`, `getEntireCoords` |
|
|
31
|
+
* | Evaluation lifecycle | `markVolatile`, `getRow`, `getColumn`, `getEntireCoords`, `getRandom` |
|
|
32
|
+
* | Argument reflection | `getArgs` |
|
|
31
33
|
* | Output hints | `formatResults` |
|
|
32
|
-
* | Range construction | `createRange`, `filterHidden` |
|
|
34
|
+
* | Range construction | `createRange`, `flattenAreas`, `filterHidden` |
|
|
33
35
|
* | Dynamic references | `getReference`, `getValueAt`, `getFormulaAt`, `getSpillAt` |
|
|
34
36
|
* | Function lookup | `getFunction` |
|
|
35
37
|
* | Dates | `getNow`, `toSerialDate`, `fromSerialDate`, `getDateParts`, `getSerialDate`, `parseAsDate`, `parseAsSerialDate`, `isValidDate` |
|
|
36
38
|
* | Coercion | `parseAsNumber`, `parseAsLiteral`, `toText`, `compare` |
|
|
37
39
|
* | Criteria | `createCriteria` |
|
|
40
|
+
* | Grouping | `createGrouping` |
|
|
38
41
|
* | Sheet introspection | `getSheetCount`, `getSheetIndex`, `getAddress`, `getNumberFormat` |
|
|
39
42
|
*
|
|
40
43
|
* ### Implementors
|
|
@@ -52,6 +55,25 @@ export interface IFormulaContext {
|
|
|
52
55
|
* invoked per cell. Default is `null` (an empty range).
|
|
53
56
|
*/
|
|
54
57
|
createRange<TS extends Scalar = Scalar>(rows?: number, columns?: number, values?: Scalar | Scalar[][] | ((value: TS, coords: IRange.CellCoords, range: IRange<TS>) => TS)): IRange;
|
|
58
|
+
/**
|
|
59
|
+
* One range over every cell of a `ReportType` slot's argument — the AREAS of a reference union
|
|
60
|
+
* folded into a single column, or the range returned unchanged.
|
|
61
|
+
*
|
|
62
|
+
* @param value The argument as it arrived: a range, or one range per area.
|
|
63
|
+
*
|
|
64
|
+
* @remarks
|
|
65
|
+
* A union `(A1:A5,B1:B2)` reaches a {@link IFunction.ParameterTypeJSON.reportType} slot as one
|
|
66
|
+
* `IRange` per area. Functions that answer over it do so because they walk MEMBERS and a union
|
|
67
|
+
* simply has more of them — `LARGE((DA1:DA5,DK1:DK2),2)` is the second largest of all seven
|
|
68
|
+
* cells. This is that walk, and it is a helper rather than a marshalling step on purpose: Excel
|
|
69
|
+
* flattens in exactly the same place, a shared reducer its bodies opt into, which is why the
|
|
70
|
+
* same union is flattened by `LARGE`, refused by `SUMPRODUCT` and answered `#REF!` by `ROWS`.
|
|
71
|
+
*
|
|
72
|
+
* The result is a single column in area order, row-major within each area. SHAPE IS NOT
|
|
73
|
+
* PRESERVED — a union has none. A body that needs an extent must ask
|
|
74
|
+
* {@link IFunctionArguments.getAreaCountAt} and answer for itself.
|
|
75
|
+
*/
|
|
76
|
+
flattenAreas(value: IRange | IRange[]): IRange;
|
|
55
77
|
/**
|
|
56
78
|
* Returns coordinates as an address string.
|
|
57
79
|
*
|
|
@@ -92,6 +114,20 @@ export interface IFormulaContext {
|
|
|
92
114
|
* Returns the 0-based column of the cell being evaluated.
|
|
93
115
|
*/
|
|
94
116
|
getColumn(): number;
|
|
117
|
+
/**
|
|
118
|
+
* Whether the call being evaluated is in Excel's VALUE mode, where a multi-cell reference at a
|
|
119
|
+
* slot that reads ONE value is implicitly intersected with the formula's cell (the `@` rule);
|
|
120
|
+
* `false` is ARRAY mode, where such a slot reads the reference's first cell.
|
|
121
|
+
*
|
|
122
|
+
* @remarks
|
|
123
|
+
* Only a body that accepts a whole reference at a single-value slot and reads it itself asks
|
|
124
|
+
* (`LINEST`'s `const`). The engine decides the mode from the formula around the call — a
|
|
125
|
+
* scalar-valued root, an aggregator or a lookup above it are value mode; a spilling root, an
|
|
126
|
+
* operator or lifting slot over an array-valued operand, a `LAMBDA` body and an array-entered
|
|
127
|
+
* block are array mode — and the mode is inherited through every call that does not set it.
|
|
128
|
+
* Outside a calculation this is `false`.
|
|
129
|
+
*/
|
|
130
|
+
isImplicitIntersect(): boolean;
|
|
95
131
|
/**
|
|
96
132
|
* Resolves a range reference at runtime, returning an {@link IReferenceRange}.
|
|
97
133
|
*
|
|
@@ -184,16 +220,30 @@ export interface IFormulaContext {
|
|
|
184
220
|
*/
|
|
185
221
|
getSheetIndex(sheet?: string | IReferenceRange): number;
|
|
186
222
|
/**
|
|
187
|
-
* Returns a
|
|
223
|
+
* Returns a range as it reads without its hidden rows or columns.
|
|
188
224
|
*
|
|
189
225
|
* @param range The range to filter.
|
|
190
|
-
* @param
|
|
191
|
-
* @returns
|
|
226
|
+
* @param options See {@link IFormulaContext.FilterHiddenOptions}.
|
|
227
|
+
* @returns `range` itself when nothing in it is hidden; otherwise the same range reading with
|
|
228
|
+
* the hidden rows or columns skipped ({@link IRange.IteratorOptions.processRowSkip}).
|
|
192
229
|
*
|
|
193
230
|
* @remarks
|
|
194
231
|
* Use this for functions that ignore hidden data, such as `SUBTOTAL`.
|
|
232
|
+
*
|
|
233
|
+
* Nothing is copied. The shape of `range` is kept, and a reference stays a reference: a hidden
|
|
234
|
+
* cell is not visited and reads as empty, so every position still means the cell it meant, and
|
|
235
|
+
* an aggregate that ignores blanks ignores it. A computed array has no rows or columns to hide
|
|
236
|
+
* and is returned as it is.
|
|
237
|
+
*
|
|
238
|
+
* A hidden row is a hidden row, whoever hid it: a filter and the user leave the same mark, and
|
|
239
|
+
* nothing here tells them apart. What a filter adds is a state of the range's SHEET, which
|
|
240
|
+
* {@link IFormulaContext.FilterHiddenOptions.onlyWhileFiltered} reads.
|
|
241
|
+
*
|
|
242
|
+
* A formula that calls `SUBTOTAL` or `AGGREGATE` is recalculated when a row or column is hidden
|
|
243
|
+
* or shown, and when a filter is set or cleared. One that reaches this only through a custom
|
|
244
|
+
* function is not: it reads the state when it is next calculated.
|
|
195
245
|
*/
|
|
196
|
-
filterHidden(range: IRange,
|
|
246
|
+
filterHidden(range: IRange, options?: IFormulaContext.FilterHiddenOptions): IRange;
|
|
197
247
|
/**
|
|
198
248
|
* Returns a copy of a range with any cell whose formula is a nested total removed.
|
|
199
249
|
*
|
|
@@ -275,6 +325,7 @@ export interface IFormulaContext {
|
|
|
275
325
|
*
|
|
276
326
|
* @param criteria The criteria, exactly as the user wrote it — a comparison (`">10"`, `"<>x"`),
|
|
277
327
|
* a wildcard pattern (`"a*"`), or a literal of any type.
|
|
328
|
+
* @param options How the criteria is matched. See {@link IFormulaContext.CriteriaOptions}.
|
|
278
329
|
* @returns A predicate to test cell values with. Call it once per cell.
|
|
279
330
|
*
|
|
280
331
|
* @remarks
|
|
@@ -296,7 +347,34 @@ export interface IFormulaContext {
|
|
|
296
347
|
* const count = range.reduce((total, value) => matches(value) ? total + 1 : total, 0);
|
|
297
348
|
* ```
|
|
298
349
|
*/
|
|
299
|
-
createCriteria(criteria: Scalar): IFormulaContext.CriteriaEvaluator;
|
|
350
|
+
createCriteria(criteria: Scalar, options?: IFormulaContext.CriteriaOptions): IFormulaContext.CriteriaEvaluator;
|
|
351
|
+
/**
|
|
352
|
+
* Groups the records of a range — its rows — by their values.
|
|
353
|
+
*
|
|
354
|
+
* @param keys The key columns. Each row is one record, and records with equal values in every
|
|
355
|
+
* column form one group.
|
|
356
|
+
* @param options Which records take part. See {@link IFormulaContext.GroupingOptions}.
|
|
357
|
+
* @returns The groups, numbered in the order they first appear.
|
|
358
|
+
*
|
|
359
|
+
* @remarks
|
|
360
|
+
* Two keys are equal by the rule `UNIQUE` uses: text ignores case, and types never mix, so `1`,
|
|
361
|
+
* `"1"` and `TRUE` are three groups. A blank key is a key of its own, distinct from `""`, and an
|
|
362
|
+
* error is a key like any other value. Every row is a record, blank rows included.
|
|
363
|
+
*
|
|
364
|
+
* Group ONCE and ask the grouping for each group's members. The grouping does the work a
|
|
365
|
+
* per-group scan would repeat, so it stays proportional to the data rather than to the data
|
|
366
|
+
* times the number of groups.
|
|
367
|
+
*
|
|
368
|
+
* @example
|
|
369
|
+
* ```typescript
|
|
370
|
+
* const grouping = FormulaContext.createGrouping(regions);
|
|
371
|
+
* for (let g = 0; g < grouping.getGroupCount(); g++) {
|
|
372
|
+
* const [region] = grouping.getKeys(g);
|
|
373
|
+
* const sales = grouping.getMembers(amounts, [g]);
|
|
374
|
+
* }
|
|
375
|
+
* ```
|
|
376
|
+
*/
|
|
377
|
+
createGrouping(keys: IRange, options?: IFormulaContext.GroupingOptions): IFormulaContext.Grouping;
|
|
300
378
|
/**
|
|
301
379
|
* Reads a typed literal in the workbook's language — the parse side of {@link toText}.
|
|
302
380
|
*
|
|
@@ -384,6 +462,30 @@ export interface IFormulaContext {
|
|
|
384
462
|
* ```
|
|
385
463
|
*/
|
|
386
464
|
getNow(): number;
|
|
465
|
+
/**
|
|
466
|
+
* Returns a random number in `[0, 1)`, like `Math.random()`.
|
|
467
|
+
*
|
|
468
|
+
* @remarks
|
|
469
|
+
* Always draw through this, never `Math.random()`. The source is the runtime's, so a test or a
|
|
470
|
+
* replay can seed it, and the engine sees the draw: a draw is a PER-CELL read — two cells calling
|
|
471
|
+
* the same function in one pass differ — where `getNow` is one value for the whole pass, and the
|
|
472
|
+
* engine only shares an evaluation across the cells of a block when nothing per-cell was read.
|
|
473
|
+
* Pair it with `Volatile<T>` so the function draws again on the next pass.
|
|
474
|
+
*
|
|
475
|
+
* Under a seeded runtime ({@link IRuntime.getRandomSeed}) each draw is keyed by the cell, the
|
|
476
|
+
* pass and which draw it is within that cell, so a function that draws more than once gets
|
|
477
|
+
* distinct values and a cell gets the same ones however the pass was ordered. Take the draws
|
|
478
|
+
* where they are used rather than hoisting them, and the values follow the cells rather than
|
|
479
|
+
* the code path.
|
|
480
|
+
*
|
|
481
|
+
* @example
|
|
482
|
+
* ```typescript
|
|
483
|
+
* export function RAND(): Volatile<number> {
|
|
484
|
+
* return FormulaContext.getRandom();
|
|
485
|
+
* }
|
|
486
|
+
* ```
|
|
487
|
+
*/
|
|
488
|
+
getRandom(): number;
|
|
387
489
|
/**
|
|
388
490
|
* Returns `true` if the value is a usable date — either a `Date` or a number in the
|
|
389
491
|
* workbook's serial date range.
|
|
@@ -445,14 +547,12 @@ export interface IFormulaContext {
|
|
|
445
547
|
* Fields may fall outside their normal range and carry, which is what makes `DATE` and
|
|
446
548
|
* `TIME` arithmetic work: month 13 is January of the next year, hour 50 is two days plus
|
|
447
549
|
* two hours, and `getSerialDate(1900, 1, 0)` is serial 0. The `day` carries in SERIAL
|
|
448
|
-
* space, so it runs through the phantom `1900-02-29
|
|
449
|
-
* `probe-date-1900-day-overflow.ps1`.
|
|
550
|
+
* space, so it runs through the phantom `1900-02-29`.
|
|
450
551
|
*
|
|
451
552
|
* **This validates nothing, and that is deliberate — a caller MUST choose its own
|
|
452
553
|
* policy.** No range check, no clamping, no bounds on any field, and no `DATE`-style
|
|
453
554
|
* `0..1899 -> +1900` year offset. Those belong to `DATE`'s ARGUMENTS, not to the
|
|
454
|
-
* calendar, and
|
|
455
|
-
* (`probe-date-arg-layer.ps1`, 2026-08-20):
|
|
555
|
+
* calendar, and three things prove it:
|
|
456
556
|
*
|
|
457
557
|
* * **The day policy is the caller's.** `DATE` and `DATEDIF`'s `md`/`yd` re-anchoring
|
|
458
558
|
* want the raw carry above — `DATEDIF("2020-01-31","2020-03-01","md")` is `-1`
|
|
@@ -482,6 +582,22 @@ export interface IFormulaContext {
|
|
|
482
582
|
* Mostly for diagnostics; the built-in `INFO` function is built on it.
|
|
483
583
|
*/
|
|
484
584
|
getRuntime(): IRuntime;
|
|
585
|
+
/**
|
|
586
|
+
* The current call's arguments — how many the caller supplied, in which positions, of what kind,
|
|
587
|
+
* and what each value was BEFORE coercion.
|
|
588
|
+
*
|
|
589
|
+
* @remarks
|
|
590
|
+
* Argument REFLECTION, for the one thing a declaration cannot say: what happened at *this* call.
|
|
591
|
+
* It exists to serve Excel's declared `any`, which means "no contract, the body decides" — every
|
|
592
|
+
* other Excel type maps onto a type we already have and the marshaller handles it.
|
|
593
|
+
*
|
|
594
|
+
* The returned view is valid ONLY while the body that asked for it is running. Views are pooled
|
|
595
|
+
* by dispatch depth, so retaining one across an `await`, a callback, or a nested evaluation hands
|
|
596
|
+
* you another call's arguments.
|
|
597
|
+
*
|
|
598
|
+
* @throws If called outside a function dispatch — there are no arguments to reflect on.
|
|
599
|
+
*/
|
|
600
|
+
getArgs(): IFunctionArguments;
|
|
485
601
|
}
|
|
486
602
|
/**
|
|
487
603
|
* {@inheritDoc IFormulaContext}
|
|
@@ -492,6 +608,28 @@ export interface IFormulaContext {
|
|
|
492
608
|
* {@link IFormulaContext}
|
|
493
609
|
*/
|
|
494
610
|
export declare namespace IFormulaContext {
|
|
611
|
+
/**
|
|
612
|
+
* Options for {@link IFormulaContext.filterHidden}.
|
|
613
|
+
*/
|
|
614
|
+
interface FilterHiddenOptions {
|
|
615
|
+
/**
|
|
616
|
+
* Which axis to filter on.
|
|
617
|
+
* @defaultValue `IRange.AxisSelection.Row`
|
|
618
|
+
*/
|
|
619
|
+
axes?: IRange.AxisSelection;
|
|
620
|
+
/**
|
|
621
|
+
* Skip the hidden rows or columns only while the range's sheet is filtered: while some
|
|
622
|
+
* AutoFilter or table on that sheet holds a condition, whether or not it hides a row. Until
|
|
623
|
+
* then `range` is returned as it is, hidden rows included.
|
|
624
|
+
*
|
|
625
|
+
* @remarks
|
|
626
|
+
* This is `SUBTOTAL` 1-11 (Excel: they "include manually hidden rows", which is what an
|
|
627
|
+
* unfiltered sheet reads as). `SUBTOTAL` 101-111 and `AGGREGATE` leave it off and skip
|
|
628
|
+
* always.
|
|
629
|
+
* @defaultValue false
|
|
630
|
+
*/
|
|
631
|
+
onlyWhileFiltered?: boolean;
|
|
632
|
+
}
|
|
495
633
|
/**
|
|
496
634
|
* Options for {@link IFormulaContext.parseAsNumber}.
|
|
497
635
|
*/
|
|
@@ -505,6 +643,80 @@ export declare namespace IFormulaContext {
|
|
|
505
643
|
* there.
|
|
506
644
|
*/
|
|
507
645
|
type CriteriaEvaluator = (value: Scalar) => boolean;
|
|
646
|
+
/**
|
|
647
|
+
* How a criteria is matched — see {@link IFormulaContext.createCriteria}.
|
|
648
|
+
*/
|
|
649
|
+
interface CriteriaOptions {
|
|
650
|
+
/**
|
|
651
|
+
* Where a TEXT criteria has to line up with the cell: `'whole'` (the default) for the whole
|
|
652
|
+
* cell, `'start'` for a prefix.
|
|
653
|
+
*
|
|
654
|
+
* @remarks
|
|
655
|
+
* The `D` functions' criteria table is the prefix form and the `*IF` family is not: the
|
|
656
|
+
* criterion `appl` takes the row whose value is `Apple` at `DSUM` and no row at all at
|
|
657
|
+
* `COUNTIF`, and the empty criterion — a prefix of everything — takes every TEXT cell at
|
|
658
|
+
* `DSUM` where `COUNTIF` takes only a cell that IS an empty string.
|
|
659
|
+
*
|
|
660
|
+
* It applies to a criteria that stays TEXT and to nothing else. An OPERATOR turns it off
|
|
661
|
+
* (`=appl` selects no row), and so does a criteria that reads as a number, a boolean or an
|
|
662
|
+
* error — `1` does not reach a cell holding `12`.
|
|
663
|
+
*/
|
|
664
|
+
anchor?: 'whole' | 'start';
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* Options for {@link IFormulaContext.createGrouping}.
|
|
668
|
+
*/
|
|
669
|
+
interface GroupingOptions {
|
|
670
|
+
/**
|
|
671
|
+
* One column, as tall as the keys, selecting the records that take part. A record is kept
|
|
672
|
+
* when its member is `TRUE` or a nonzero number, and left out otherwise.
|
|
673
|
+
*/
|
|
674
|
+
filter?: IRange;
|
|
675
|
+
}
|
|
676
|
+
/**
|
|
677
|
+
* The records of a range divided into groups — see {@link IFormulaContext.createGrouping}.
|
|
678
|
+
*/
|
|
679
|
+
interface Grouping {
|
|
680
|
+
/**
|
|
681
|
+
* The number of records kept by the filter.
|
|
682
|
+
*/
|
|
683
|
+
getRecordCount(): number;
|
|
684
|
+
/**
|
|
685
|
+
* The number of groups.
|
|
686
|
+
*/
|
|
687
|
+
getGroupCount(): number;
|
|
688
|
+
/**
|
|
689
|
+
* The number of records in a group.
|
|
690
|
+
*/
|
|
691
|
+
getSize(group: number): number;
|
|
692
|
+
/**
|
|
693
|
+
* A group's key, one value per key column, as spelled by the group's first record. A blank
|
|
694
|
+
* key is `null`.
|
|
695
|
+
*/
|
|
696
|
+
getKeys(group: number): readonly Scalar[];
|
|
697
|
+
/**
|
|
698
|
+
* The group a record belongs to, or `-1` when the filter left it out.
|
|
699
|
+
*
|
|
700
|
+
* @param record The record's row within the keys.
|
|
701
|
+
*/
|
|
702
|
+
getGroup(record: number): number;
|
|
703
|
+
/**
|
|
704
|
+
* The row of a group's first record within the keys.
|
|
705
|
+
*
|
|
706
|
+
* @remarks
|
|
707
|
+
* With {@link getGroup} on another grouping of the same records, this maps a group of one
|
|
708
|
+
* grouping onto the group of another — a finer grouping's group onto its parent's.
|
|
709
|
+
*/
|
|
710
|
+
getFirstRecord(group: number): number;
|
|
711
|
+
/**
|
|
712
|
+
* The members of `values` that belong to some groups, as one column in record order.
|
|
713
|
+
*
|
|
714
|
+
* @param values One column, as tall as the keys.
|
|
715
|
+
* @param groups The groups to take members from. Omit it for every kept record.
|
|
716
|
+
* @returns An array, never a reference. A blank member stays blank.
|
|
717
|
+
*/
|
|
718
|
+
getMembers(values: IRange, groups?: readonly number[]): IRange;
|
|
719
|
+
}
|
|
508
720
|
/**
|
|
509
721
|
* A serial date split into fields — see {@link IFormulaContext.getDateParts}.
|
|
510
722
|
*
|