@rowsncolumns/fast-formula-parser 6.2.41 → 6.2.42
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/dist/cjs/index.js +250 -121
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +250 -121
- package/dist/esm/index.js.map +1 -1
- package/package.json +3 -3
package/dist/cjs/index.js
CHANGED
|
@@ -10953,6 +10953,66 @@ const Criteria = Object.freeze({
|
|
|
10953
10953
|
return false;
|
|
10954
10954
|
}
|
|
10955
10955
|
},
|
|
10956
|
+
|
|
10957
|
+
/**
|
|
10958
|
+
* Excel's array lift for the criteria slot of the criteria aggregates. When
|
|
10959
|
+
* any accepted criterion value is a multi-cell array or range
|
|
10960
|
+
* (`SUMIF(rng,{"x","y"},sum)`, `SUMIFS(sum,rng,"x",rng2,{">1",">3"})`,
|
|
10961
|
+
* `COUNTIF(rng,rng)`), `evaluate` runs once per broadcast element with that
|
|
10962
|
+
* element parsed as a scalar criterion and the results come back as a 2-D
|
|
10963
|
+
* array — so `SUM(COUNTIF(rng,{…}))` / `SUMPRODUCT(SUMIF(…,{…}))` fold it and a
|
|
10964
|
+
* per-element error (`#DIV/0!` from an empty AVERAGEIF slot) stays in its
|
|
10965
|
+
* slot. Vectors broadcast along a unit dimension; a slot a shorter vector
|
|
10966
|
+
* does not reach is `#N/A`. A 1×1 array is a scalar. With no array criterion
|
|
10967
|
+
* `evaluate` runs exactly once with the parsed scalar criteria.
|
|
10968
|
+
* @param {Array} criteriaValues accepted (unparsed) criterion values
|
|
10969
|
+
* @param {(parsed: Array) => *} evaluate
|
|
10970
|
+
*/
|
|
10971
|
+
lift: (criteriaValues, evaluate) => {
|
|
10972
|
+
const shapes = criteriaValues.map((v) => {
|
|
10973
|
+
if (!Array.isArray(v)) return null;
|
|
10974
|
+
const shape = [v.length, v[0]?.length ?? 0];
|
|
10975
|
+
return shape[0] === 1 && shape[1] === 1 ? null : shape;
|
|
10976
|
+
});
|
|
10977
|
+
const scalarOf = (v) => (Array.isArray(v) ? v[0][0] : v);
|
|
10978
|
+
if (shapes.every((shape) => shape === null)) {
|
|
10979
|
+
return evaluate(criteriaValues.map((v) => Criteria.parse(scalarOf(v))));
|
|
10980
|
+
}
|
|
10981
|
+
let rows = 1;
|
|
10982
|
+
let cols = 1;
|
|
10983
|
+
for (const shape of shapes) {
|
|
10984
|
+
if (!shape) continue;
|
|
10985
|
+
if (shape[0] !== 1) rows = rows === 1 ? shape[0] : Math.max(rows, shape[0]);
|
|
10986
|
+
if (shape[1] !== 1) cols = cols === 1 ? shape[1] : Math.max(cols, shape[1]);
|
|
10987
|
+
}
|
|
10988
|
+
const MISSING = Symbol("missing");
|
|
10989
|
+
const pick = (v, shape, i, j) => {
|
|
10990
|
+
const r = shape[0] === 1 ? 0 : i;
|
|
10991
|
+
const c = shape[1] === 1 ? 0 : j;
|
|
10992
|
+
return r < v.length && c < v[r].length ? v[r][c] : MISSING;
|
|
10993
|
+
};
|
|
10994
|
+
const out = [];
|
|
10995
|
+
for (let i = 0; i < rows; i++) {
|
|
10996
|
+
const row = [];
|
|
10997
|
+
for (let j = 0; j < cols; j++) {
|
|
10998
|
+
const elements = criteriaValues.map((v, k) =>
|
|
10999
|
+
shapes[k] ? pick(v, shapes[k], i, j) : scalarOf(v),
|
|
11000
|
+
);
|
|
11001
|
+
if (elements.includes(MISSING)) {
|
|
11002
|
+
row.push(FormulaError.NA);
|
|
11003
|
+
continue;
|
|
11004
|
+
}
|
|
11005
|
+
try {
|
|
11006
|
+
row.push(evaluate(elements.map((e) => Criteria.parse(e))));
|
|
11007
|
+
} catch (e) {
|
|
11008
|
+
if (e instanceof FormulaError) row.push(e);
|
|
11009
|
+
else throw e;
|
|
11010
|
+
}
|
|
11011
|
+
}
|
|
11012
|
+
out.push(row);
|
|
11013
|
+
}
|
|
11014
|
+
return out;
|
|
11015
|
+
},
|
|
10956
11016
|
});
|
|
10957
11017
|
|
|
10958
11018
|
const Address = {
|
|
@@ -20678,23 +20738,26 @@ const StatisticalFunctions = {
|
|
|
20678
20738
|
range = ranges[0];
|
|
20679
20739
|
averageRange = ranges[1];
|
|
20680
20740
|
|
|
20681
|
-
|
|
20682
|
-
|
|
20683
|
-
|
|
20684
|
-
|
|
20685
|
-
|
|
20686
|
-
|
|
20687
|
-
|
|
20688
|
-
|
|
20689
|
-
|
|
20690
|
-
|
|
20691
|
-
|
|
20692
|
-
|
|
20693
|
-
|
|
20741
|
+
const criteriaValue = H$7.accept(H$7.retrieveArg(context, criteria));
|
|
20742
|
+
|
|
20743
|
+
const averageMatching = (parsed) => {
|
|
20744
|
+
let sum = 0,
|
|
20745
|
+
cnt = 0;
|
|
20746
|
+
range.forEach((row, rowNum) => {
|
|
20747
|
+
row.forEach((value, colNum) => {
|
|
20748
|
+
const valueToAdd = averageRange[rowNum][colNum];
|
|
20749
|
+
throwIfFormulaError(valueToAdd);
|
|
20750
|
+
if (typeof valueToAdd !== "number") return;
|
|
20751
|
+
if (Criteria.matches(parsed, value)) {
|
|
20752
|
+
sum += valueToAdd;
|
|
20753
|
+
cnt++;
|
|
20754
|
+
}
|
|
20755
|
+
});
|
|
20694
20756
|
});
|
|
20695
|
-
|
|
20696
|
-
|
|
20697
|
-
|
|
20757
|
+
if (cnt === 0) throw FormulaError.DIV0;
|
|
20758
|
+
return sum / cnt;
|
|
20759
|
+
};
|
|
20760
|
+
return Criteria.lift([criteriaValue], ([parsed]) => averageMatching(parsed));
|
|
20698
20761
|
},
|
|
20699
20762
|
|
|
20700
20763
|
/**
|
|
@@ -20724,36 +20787,42 @@ const StatisticalFunctions = {
|
|
|
20724
20787
|
assertSameShape(averageRange, criteriaRange);
|
|
20725
20788
|
criteriaPairs.push({
|
|
20726
20789
|
range: criteriaRange,
|
|
20727
|
-
criteria:
|
|
20790
|
+
criteria: H$7.accept(H$7.retrieveArg(context, args[i + 1])),
|
|
20728
20791
|
});
|
|
20729
20792
|
}
|
|
20730
20793
|
|
|
20731
|
-
|
|
20732
|
-
|
|
20794
|
+
const averageMatching = (parsedCriteria) => {
|
|
20795
|
+
let sum = 0;
|
|
20796
|
+
let count = 0;
|
|
20733
20797
|
|
|
20734
|
-
|
|
20735
|
-
|
|
20736
|
-
|
|
20737
|
-
|
|
20738
|
-
|
|
20739
|
-
|
|
20798
|
+
averageRange.forEach((row, rowNum) => {
|
|
20799
|
+
row.forEach((valueToAdd, colNum) => {
|
|
20800
|
+
throwIfFormulaError(valueToAdd);
|
|
20801
|
+
if (typeof valueToAdd !== "number") {
|
|
20802
|
+
return;
|
|
20803
|
+
}
|
|
20740
20804
|
|
|
20741
|
-
|
|
20742
|
-
|
|
20743
|
-
|
|
20805
|
+
const meetsAllCriteria = criteriaPairs.every(({ range }, k) =>
|
|
20806
|
+
Criteria.matches(parsedCriteria[k], range[rowNum][colNum]),
|
|
20807
|
+
);
|
|
20744
20808
|
|
|
20745
|
-
|
|
20746
|
-
|
|
20747
|
-
|
|
20748
|
-
|
|
20809
|
+
if (meetsAllCriteria) {
|
|
20810
|
+
sum += valueToAdd;
|
|
20811
|
+
count++;
|
|
20812
|
+
}
|
|
20813
|
+
});
|
|
20749
20814
|
});
|
|
20750
|
-
});
|
|
20751
20815
|
|
|
20752
|
-
|
|
20753
|
-
|
|
20754
|
-
|
|
20816
|
+
if (count === 0) {
|
|
20817
|
+
throw FormulaError.DIV0;
|
|
20818
|
+
}
|
|
20755
20819
|
|
|
20756
|
-
|
|
20820
|
+
return sum / count;
|
|
20821
|
+
};
|
|
20822
|
+
return Criteria.lift(
|
|
20823
|
+
criteriaPairs.map((pair) => pair.criteria),
|
|
20824
|
+
averageMatching,
|
|
20825
|
+
);
|
|
20757
20826
|
},
|
|
20758
20827
|
|
|
20759
20828
|
LARGE: (array, kth) => {
|
|
@@ -20825,34 +20894,40 @@ const StatisticalFunctions = {
|
|
|
20825
20894
|
assertSameShape(maxRange, criteriaRange);
|
|
20826
20895
|
criteriaPairs.push({
|
|
20827
20896
|
range: criteriaRange,
|
|
20828
|
-
criteria:
|
|
20897
|
+
criteria: H$7.accept(H$7.retrieveArg(context, args[i + 1])),
|
|
20829
20898
|
});
|
|
20830
20899
|
}
|
|
20831
20900
|
|
|
20832
|
-
|
|
20833
|
-
|
|
20901
|
+
const maxMatching = (parsedCriteria) => {
|
|
20902
|
+
let max = Number.NEGATIVE_INFINITY;
|
|
20903
|
+
let matchFound = false;
|
|
20834
20904
|
|
|
20835
|
-
|
|
20836
|
-
|
|
20837
|
-
|
|
20838
|
-
|
|
20839
|
-
|
|
20840
|
-
|
|
20905
|
+
maxRange.forEach((row, rowNum) => {
|
|
20906
|
+
row.forEach((valueToAdd, colNum) => {
|
|
20907
|
+
throwIfFormulaError(valueToAdd);
|
|
20908
|
+
if (typeof valueToAdd !== "number") {
|
|
20909
|
+
return;
|
|
20910
|
+
}
|
|
20841
20911
|
|
|
20842
|
-
|
|
20843
|
-
|
|
20844
|
-
|
|
20912
|
+
const meetsAllCriteria = criteriaPairs.every(({ range }, k) =>
|
|
20913
|
+
Criteria.matches(parsedCriteria[k], range[rowNum][colNum]),
|
|
20914
|
+
);
|
|
20845
20915
|
|
|
20846
|
-
|
|
20847
|
-
|
|
20848
|
-
|
|
20916
|
+
if (meetsAllCriteria) {
|
|
20917
|
+
if (valueToAdd > max) {
|
|
20918
|
+
max = valueToAdd;
|
|
20919
|
+
}
|
|
20920
|
+
matchFound = true;
|
|
20849
20921
|
}
|
|
20850
|
-
|
|
20851
|
-
}
|
|
20922
|
+
});
|
|
20852
20923
|
});
|
|
20853
|
-
});
|
|
20854
20924
|
|
|
20855
|
-
|
|
20925
|
+
return matchFound ? max : 0;
|
|
20926
|
+
};
|
|
20927
|
+
return Criteria.lift(
|
|
20928
|
+
criteriaPairs.map((pair) => pair.criteria),
|
|
20929
|
+
maxMatching,
|
|
20930
|
+
);
|
|
20856
20931
|
},
|
|
20857
20932
|
|
|
20858
20933
|
MINA: (...params) => {
|
|
@@ -20903,34 +20978,40 @@ const StatisticalFunctions = {
|
|
|
20903
20978
|
assertSameShape(minRange, criteriaRange);
|
|
20904
20979
|
criteriaPairs.push({
|
|
20905
20980
|
range: criteriaRange,
|
|
20906
|
-
criteria:
|
|
20981
|
+
criteria: H$7.accept(H$7.retrieveArg(context, args[i + 1])),
|
|
20907
20982
|
});
|
|
20908
20983
|
}
|
|
20909
20984
|
|
|
20910
|
-
|
|
20911
|
-
|
|
20985
|
+
const minMatching = (parsedCriteria) => {
|
|
20986
|
+
let min = Number.POSITIVE_INFINITY;
|
|
20987
|
+
let matchFound = false;
|
|
20912
20988
|
|
|
20913
|
-
|
|
20914
|
-
|
|
20915
|
-
|
|
20916
|
-
|
|
20917
|
-
|
|
20918
|
-
|
|
20989
|
+
minRange.forEach((row, rowNum) => {
|
|
20990
|
+
row.forEach((valueToAdd, colNum) => {
|
|
20991
|
+
throwIfFormulaError(valueToAdd);
|
|
20992
|
+
if (typeof valueToAdd !== "number") {
|
|
20993
|
+
return;
|
|
20994
|
+
}
|
|
20919
20995
|
|
|
20920
|
-
|
|
20921
|
-
|
|
20922
|
-
|
|
20996
|
+
const meetsAllCriteria = criteriaPairs.every(({ range }, k) =>
|
|
20997
|
+
Criteria.matches(parsedCriteria[k], range[rowNum][colNum]),
|
|
20998
|
+
);
|
|
20923
20999
|
|
|
20924
|
-
|
|
20925
|
-
|
|
20926
|
-
|
|
21000
|
+
if (meetsAllCriteria) {
|
|
21001
|
+
if (valueToAdd < min) {
|
|
21002
|
+
min = valueToAdd;
|
|
21003
|
+
}
|
|
21004
|
+
matchFound = true;
|
|
20927
21005
|
}
|
|
20928
|
-
|
|
20929
|
-
}
|
|
21006
|
+
});
|
|
20930
21007
|
});
|
|
20931
|
-
});
|
|
20932
21008
|
|
|
20933
|
-
|
|
21009
|
+
return matchFound ? min : 0;
|
|
21010
|
+
};
|
|
21011
|
+
return Criteria.lift(
|
|
21012
|
+
criteriaPairs.map((pair) => pair.criteria),
|
|
21013
|
+
minMatching,
|
|
21014
|
+
);
|
|
20934
21015
|
},
|
|
20935
21016
|
|
|
20936
21017
|
NPV: (rate, ...values) => {
|
|
@@ -23231,26 +23312,30 @@ const MathFunctions = {
|
|
|
23231
23312
|
range = ranges[0];
|
|
23232
23313
|
sumRange = ranges[1];
|
|
23233
23314
|
|
|
23234
|
-
|
|
23235
|
-
|
|
23236
|
-
|
|
23237
|
-
|
|
23238
|
-
|
|
23239
|
-
|
|
23240
|
-
|
|
23241
|
-
|
|
23242
|
-
|
|
23243
|
-
|
|
23244
|
-
|
|
23245
|
-
|
|
23246
|
-
|
|
23247
|
-
|
|
23248
|
-
|
|
23249
|
-
|
|
23315
|
+
const criteriaValue = H$6.accept(H$6.retrieveArg(context, criteria));
|
|
23316
|
+
|
|
23317
|
+
const sumMatching = (parsed) => {
|
|
23318
|
+
let sum = 0;
|
|
23319
|
+
const rowCount = range.length;
|
|
23320
|
+
for (let r = 0; r < rowCount; r++) {
|
|
23321
|
+
const row = range[r];
|
|
23322
|
+
const sumRow = sumRange[r];
|
|
23323
|
+
const colCount = row.length;
|
|
23324
|
+
for (let c = 0; c < colCount; c++) {
|
|
23325
|
+
const valueToAdd = sumRow[c];
|
|
23326
|
+
if (valueToAdd instanceof FormulaError) {
|
|
23327
|
+
throw valueToAdd;
|
|
23328
|
+
}
|
|
23329
|
+
if (typeof valueToAdd !== "number") continue;
|
|
23330
|
+
if (Criteria.matches(parsed, row[c])) {
|
|
23331
|
+
sum += valueToAdd;
|
|
23332
|
+
}
|
|
23250
23333
|
}
|
|
23251
23334
|
}
|
|
23252
|
-
|
|
23253
|
-
|
|
23335
|
+
return sum;
|
|
23336
|
+
};
|
|
23337
|
+
// An array criterion spills one total per element (SUMPRODUCT(SUMIF(rng,{…},sum))).
|
|
23338
|
+
return Criteria.lift([criteriaValue], ([parsed]) => sumMatching(parsed));
|
|
23254
23339
|
},
|
|
23255
23340
|
|
|
23256
23341
|
/**
|
|
@@ -23285,37 +23370,43 @@ const MathFunctions = {
|
|
|
23285
23370
|
}
|
|
23286
23371
|
criteriaPairs.push({
|
|
23287
23372
|
range: criteriaRange,
|
|
23288
|
-
criteria:
|
|
23373
|
+
criteria: H$6.accept(H$6.retrieveArg(context, args[i + 1])),
|
|
23289
23374
|
});
|
|
23290
23375
|
}
|
|
23291
23376
|
|
|
23292
|
-
|
|
23293
|
-
|
|
23294
|
-
|
|
23295
|
-
|
|
23296
|
-
|
|
23297
|
-
|
|
23298
|
-
|
|
23299
|
-
|
|
23300
|
-
|
|
23301
|
-
|
|
23302
|
-
|
|
23303
|
-
|
|
23304
|
-
|
|
23305
|
-
|
|
23306
|
-
|
|
23307
|
-
|
|
23308
|
-
|
|
23309
|
-
|
|
23310
|
-
|
|
23377
|
+
const sumMatching = (parsedCriteria) => {
|
|
23378
|
+
let sum = 0;
|
|
23379
|
+
const rowCount = sumRange.length;
|
|
23380
|
+
for (let r = 0; r < rowCount; r++) {
|
|
23381
|
+
const row = sumRange[r];
|
|
23382
|
+
const colCount = row.length;
|
|
23383
|
+
for (let c = 0; c < colCount; c++) {
|
|
23384
|
+
const valueToAdd = row[c];
|
|
23385
|
+
if (valueToAdd instanceof FormulaError) {
|
|
23386
|
+
throw valueToAdd;
|
|
23387
|
+
}
|
|
23388
|
+
if (typeof valueToAdd !== "number") {
|
|
23389
|
+
continue;
|
|
23390
|
+
}
|
|
23391
|
+
let allCriteriaMet = true;
|
|
23392
|
+
for (let i = 0; i < criteriaPairs.length; i++) {
|
|
23393
|
+
if (!Criteria.matches(parsedCriteria[i], criteriaPairs[i].range[r][c])) {
|
|
23394
|
+
allCriteriaMet = false;
|
|
23395
|
+
break;
|
|
23396
|
+
}
|
|
23397
|
+
}
|
|
23398
|
+
if (allCriteriaMet) {
|
|
23399
|
+
sum += valueToAdd;
|
|
23311
23400
|
}
|
|
23312
|
-
}
|
|
23313
|
-
if (allCriteriaMet) {
|
|
23314
|
-
sum += valueToAdd;
|
|
23315
23401
|
}
|
|
23316
23402
|
}
|
|
23317
|
-
|
|
23318
|
-
|
|
23403
|
+
return sum;
|
|
23404
|
+
};
|
|
23405
|
+
// Array criteria spill one total per broadcast element.
|
|
23406
|
+
return Criteria.lift(
|
|
23407
|
+
criteriaPairs.map((pair) => pair.criteria),
|
|
23408
|
+
sumMatching,
|
|
23409
|
+
);
|
|
23319
23410
|
},
|
|
23320
23411
|
|
|
23321
23412
|
SUMPRODUCT: (array1, ...arrays) => {
|
|
@@ -23908,7 +23999,23 @@ const LogicalFunctions = {
|
|
|
23908
23999
|
// never raw `undefined` (misreported as "Function IFNA is not
|
|
23909
24000
|
// implemented.").
|
|
23910
24001
|
const blankToZero = (v) => (v === undefined || v === null ? 0 : v);
|
|
23911
|
-
|
|
24002
|
+
const isNa = (cell) => cell instanceof FormulaError && FormulaError.NA.equals(cell);
|
|
24003
|
+
|
|
24004
|
+
// Excel lifts IFNA element-wise over an array / multi-cell range value, like IFERROR:
|
|
24005
|
+
// only the #N/A elements take the fallback, every other value or error passes through
|
|
24006
|
+
// (`IFNA(K1:K3,0)` → {#DIV/0!;0;0}, `SUM(IFNA(rng,0))` sums the non-#N/A cells).
|
|
24007
|
+
const hasValueProp = value && typeof value === 'object' && Object.prototype.hasOwnProperty.call(value, 'value');
|
|
24008
|
+
if (hasValueProp && value.isArray) {
|
|
24009
|
+
const arrayValue = value.value;
|
|
24010
|
+
const handleCell = (cell) => (isNa(cell) ? blankToZero(H$4.accept(valueIfNa)) : blankToZero(cell));
|
|
24011
|
+
if (Array.isArray(arrayValue)) {
|
|
24012
|
+
return arrayValue.map((row) => (Array.isArray(row) ? row.map(handleCell) : handleCell(row)));
|
|
24013
|
+
}
|
|
24014
|
+
return handleCell(arrayValue);
|
|
24015
|
+
}
|
|
24016
|
+
|
|
24017
|
+
const actualValue = hasValueProp ? value.value : value;
|
|
24018
|
+
return isNa(actualValue)
|
|
23912
24019
|
? blankToZero(H$4.accept(valueIfNa))
|
|
23913
24020
|
: blankToZero(H$4.accept(value));
|
|
23914
24021
|
},
|
|
@@ -50565,6 +50672,16 @@ class Parser extends EmbeddedActionsParser {
|
|
|
50565
50672
|
) {
|
|
50566
50673
|
return arr[0][0];
|
|
50567
50674
|
}
|
|
50675
|
+
// Excel refuses a ragged constant (`{1,2;3}`) at entry — every row must have the width
|
|
50676
|
+
// of the first. A parse-level `#ERROR!`, like any other syntax error the host stores as
|
|
50677
|
+
// the cell value (rowsncolumns/spreadsheet#939 G-02).
|
|
50678
|
+
const width = arr[0].length;
|
|
50679
|
+
const ragged = arr.findIndex((row) => row.length !== width);
|
|
50680
|
+
if (ragged !== -1) {
|
|
50681
|
+
throw FormulaError.ERROR(
|
|
50682
|
+
`Array constant rows must have the same length: row 1 has ${width} element(s), row ${ragged + 1} has ${arr[ragged].length}`
|
|
50683
|
+
);
|
|
50684
|
+
}
|
|
50568
50685
|
const array = this.utils.toArray(arr);
|
|
50569
50686
|
return context.async
|
|
50570
50687
|
? this.utils.settleArrayItems(array, $.position)
|
|
@@ -52984,8 +53101,13 @@ const normalizeNumberResult = (value, precision, epsilon, excelPrecision) => {
|
|
|
52984
53101
|
* @param {*} value
|
|
52985
53102
|
* @return {boolean}
|
|
52986
53103
|
*/
|
|
53104
|
+
// A name's definition text: `=…` (the OOXML `<definedName>` content), or a bare `LAMBDA(…)` —
|
|
53105
|
+
// the shape Excel's Name Manager and the host's "Text or Formula" names store a lambda in, which
|
|
53106
|
+
// the call path (`Dbl(21)`) already accepts without the leading `=` (spreadsheet#939 G-07).
|
|
53107
|
+
const BARE_LAMBDA_TEXT = /^(_xlfn\.)?LAMBDA\s*\(/i;
|
|
52987
53108
|
const isNamedFormulaText = (value) =>
|
|
52988
|
-
typeof value === "string" &&
|
|
53109
|
+
typeof value === "string" &&
|
|
53110
|
+
(value.trimStart().startsWith("=") || BARE_LAMBDA_TEXT.test(value.trimStart()));
|
|
52989
53111
|
|
|
52990
53112
|
class FormulaParser {
|
|
52991
53113
|
/**
|
|
@@ -53354,7 +53476,8 @@ class FormulaParser {
|
|
|
53354
53476
|
if (this.namedFormulaStack.has(key)) {
|
|
53355
53477
|
return FormulaError.REF;
|
|
53356
53478
|
}
|
|
53357
|
-
const
|
|
53479
|
+
const trimmed = text.trim();
|
|
53480
|
+
const source = (trimmed.startsWith("=") ? trimmed.slice(1) : trimmed).trim();
|
|
53358
53481
|
if (source.length === 0) {
|
|
53359
53482
|
return FormulaError.NAME;
|
|
53360
53483
|
}
|
|
@@ -53363,12 +53486,18 @@ class FormulaParser {
|
|
|
53363
53486
|
this.namedFormulaParser.namedFormulaStack = this.namedFormulaStack;
|
|
53364
53487
|
}
|
|
53365
53488
|
this.namedFormulaStack.add(key);
|
|
53489
|
+
// A name bound to a LAMBDA (`Dbl` = `=LAMBDA(x,x*2)`) is the lambda VALUE wherever the
|
|
53490
|
+
// name is read — `MAP(A1:A3,Dbl)`, `LET(f,Dbl,f(3))` — so the definition parser must hand
|
|
53491
|
+
// it back instead of turning it into `#CALC!`; the referencing cell's own
|
|
53492
|
+
// `checkFormulaResult` still makes a bare `=Dbl` `#CALC!` (spreadsheet#939 G-07).
|
|
53493
|
+
this.namedFormulaParser.keepLambdaResult = true;
|
|
53366
53494
|
try {
|
|
53367
53495
|
return this.namedFormulaParser.parse(source, this.position, true);
|
|
53368
53496
|
} catch (e) {
|
|
53369
53497
|
if (e instanceof FormulaError) return e;
|
|
53370
53498
|
return FormulaError.NAME;
|
|
53371
53499
|
} finally {
|
|
53500
|
+
this.namedFormulaParser.keepLambdaResult = false;
|
|
53372
53501
|
this.namedFormulaStack.delete(key);
|
|
53373
53502
|
}
|
|
53374
53503
|
}
|