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