@leankylin-sheet/formula-parser 7.0.23 → 7.0.25

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.
@@ -1 +1,2 @@
1
1
  export default function compareRange(exp1: any, exp2: any, type: any): boolean | (boolean | undefined)[] | undefined;
2
+ export function toComparable(value: any): any;
@@ -4,3 +4,13 @@ export function columnLabelToIndex(label: string): number;
4
4
  export function columnIndexToLabel(column: number): string;
5
5
  export function extractLabel(label: string): any[];
6
6
  export function toLabel(row: Object, column: Object): string;
7
+ export function isCellReference(value: any): boolean;
8
+ export function toCellValue(value: any): any;
9
+ export function isReferenceFormula(symbol: string): boolean;
10
+ export class CellReference {
11
+ constructor(label: any, value: any);
12
+ label: any;
13
+ value: any;
14
+ valueOf(): any;
15
+ }
16
+ export const REFERENCE_FORMULAS: string[];
@@ -0,0 +1,2 @@
1
+ export function isDate(value: any): boolean;
2
+ export function dateToSerialNumber(date: Date, date1904?: number | undefined): number;
@@ -1,3 +1,3 @@
1
- export function toNumber(number: string | number): any;
2
- export function invertNumber(number: number): number;
1
+ export function toNumber(number: string | number | Date): any;
2
+ export function invertNumber(number: number | Date): number;
3
3
  export function toNumberNotNaN(number: any): number;
package/dist/index.esm.js CHANGED
@@ -169,10 +169,54 @@ function _nonIterableRest() {
169
169
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
170
170
  }
171
171
 
172
+ var MS_PER_DAY = 24 * 60 * 60 * 1000;
173
+
174
+ /**
175
+ * 1900 日期系统下 Excel 的 0 点(1899-12-31 00:00:00 UTC)。
176
+ */
177
+ var EXCEL_EPOCH_UTC = Date.UTC(1899, 11, 31, 0, 0, 0);
178
+
179
+ /**
180
+ * Excel 虚构的 1900-02-29 之后的第一天(1900-03-01)。
181
+ * 当天及之后的日期需要补 1 天,才能和 Excel 的序列号对齐。
182
+ */
183
+ var EXCEL_LEAP_BUG_BASE = new Date(1900, 2, 1, 0, 0, 0);
184
+
185
+ /**
186
+ * 判断是否为有效的 Date 对象。
187
+ *
188
+ * @param {*} value 待判断的值。
189
+ * @returns {Boolean}
190
+ */
191
+ function isDate(value) {
192
+ return value instanceof Date && !Number.isNaN(value.getTime());
193
+ }
194
+
195
+ /**
196
+ * 把 Date 转成 Excel 日期序列号。
197
+ *
198
+ * 与 core 中 modules/format.ts 的 datenum_local 保持完全一致:
199
+ * 取本地年月日时分秒再按 UTC 计算,避免时区和夏令时带来的偏移;
200
+ * 1900-03-01 及之后的日期补 1 天,对齐 Excel 的 1900 闰年 bug。
201
+ *
202
+ * @param {Date} date 待转换的日期。
203
+ * @param {Number} [date1904] 是否使用 1904 日期系统。
204
+ * @returns {Number} Excel 序列号,整数部分为日期,小数部分为时间。
205
+ */
206
+ function dateToSerialNumber(date, date1904) {
207
+ var epoch = Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds());
208
+ if (date1904) {
209
+ epoch -= 1461 * MS_PER_DAY;
210
+ } else if (date >= EXCEL_LEAP_BUG_BASE) {
211
+ epoch += MS_PER_DAY;
212
+ }
213
+ return (epoch - EXCEL_EPOCH_UTC) / MS_PER_DAY;
214
+ }
215
+
172
216
  /**
173
217
  * Convert value into number.
174
218
  *
175
- * @param {String|Number} number
219
+ * @param {String|Number|Date} number
176
220
  * @returns {*}
177
221
  */
178
222
  function toNumber(number) {
@@ -180,6 +224,10 @@ function toNumber(number) {
180
224
  if (number === true) {
181
225
  return 1;
182
226
  }
227
+ // DATE/TODAY/NOW 等函数返回 Date 对象,按 Excel 序列号参与运算
228
+ if (isDate(number)) {
229
+ return dateToSerialNumber(number);
230
+ }
183
231
  if (typeof number === 'number') {
184
232
  result = number;
185
233
  } else if (typeof number === 'string') {
@@ -191,7 +239,7 @@ function toNumber(number) {
191
239
  /**
192
240
  * Invert provided number.
193
241
  *
194
- * @param {Number} number
242
+ * @param {Number|Date} number Provided number.
195
243
  * @returns {Number} Returns inverted number.
196
244
  */
197
245
  function invertNumber(number) {
@@ -203,6 +251,9 @@ function toNumberNotNaN(number) {
203
251
  if (number === true) {
204
252
  return 1;
205
253
  }
254
+ if (isDate(number)) {
255
+ return dateToSerialNumber(number);
256
+ }
206
257
  if (typeof number === 'number') {
207
258
  result = number;
208
259
  } else if (typeof number === 'string') {
@@ -278,9 +329,14 @@ function func$1() {
278
329
  params[_key] = arguments[_key];
279
330
  }
280
331
  return params.reduce(function (acc, value) {
281
- return acc + value.toString();
332
+ return acc + toString(value);
282
333
  }, '');
283
334
  }
335
+
336
+ // Date 拼接时取 Excel 序列号,避免出现 "Tue Oct 20 2026 ..." 这类 JS 默认格式
337
+ function toString(value) {
338
+ return isDate(value) ? String(dateToSerialNumber(value)) : value.toString();
339
+ }
284
340
  func$1.SYMBOL = SYMBOL$1;
285
341
 
286
342
  var SYMBOL$2 = '/';
@@ -334,9 +390,23 @@ function compare(exp1, exp2, type) {
334
390
  return tsValue(exp1) === tsValue(exp2);
335
391
  }
336
392
  }
337
- function tsValue(value) {
393
+
394
+ /**
395
+ * 比较前的取值归一化:Date 统一转成 Excel 序列号,
396
+ * 这样 =TODAY()>A1、=TODAY()=TODAY() 才能按日期天数比较。
397
+ *
398
+ * @param {*} value 待归一化的值。
399
+ * @returns {*}
400
+ */
401
+ function toComparable(value) {
402
+ if (isDate(value)) {
403
+ return dateToSerialNumber(value);
404
+ }
338
405
  return value !== null && value !== void 0 ? value : 0;
339
406
  }
407
+ function tsValue(value) {
408
+ return toComparable(value);
409
+ }
340
410
 
341
411
  var SYMBOL$3 = '=';
342
412
  function func$3(exp1, exp2) {
@@ -344,6 +414,172 @@ function func$3(exp1, exp2) {
344
414
  }
345
415
  func$3.SYMBOL = SYMBOL$3;
346
416
 
417
+ /**
418
+ * Convert row label to index.
419
+ *
420
+ * @param {String} label Row label (eq. '1', '5')
421
+ * @returns {Number} Returns -1 if label is not recognized otherwise proper row index.
422
+ */
423
+ function rowLabelToIndex(label) {
424
+ var result = parseInt(label, 10);
425
+ if (isNaN(result)) {
426
+ result = -1;
427
+ } else {
428
+ result = Math.max(result - 1, -1);
429
+ }
430
+ return result;
431
+ }
432
+
433
+ /**
434
+ * Convert row index to label.
435
+ *
436
+ * @param {Number} row Row index.
437
+ * @returns {String} Returns row label (eq. '1', '7').
438
+ */
439
+ function rowIndexToLabel(row) {
440
+ var result = "";
441
+ if (row >= 0) {
442
+ result = "".concat(row + 1);
443
+ }
444
+ return result;
445
+ }
446
+ var COLUMN_LABEL_BASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
447
+ var COLUMN_LABEL_BASE_LENGTH = COLUMN_LABEL_BASE.length;
448
+
449
+ /**
450
+ * Convert column label to index.
451
+ *
452
+ * @param {String} label Column label (eq. 'ABB', 'CNQ')
453
+ * @returns {Number} Returns -1 if label is not recognized otherwise proper column index.
454
+ */
455
+ function columnLabelToIndex(label) {
456
+ var result = 0;
457
+ if (typeof label === "string") {
458
+ label = label.toUpperCase();
459
+ for (var i = 0, j = label.length - 1; i < label.length; i += 1, j -= 1) {
460
+ result += Math.pow(COLUMN_LABEL_BASE_LENGTH, j) * (COLUMN_LABEL_BASE.indexOf(label[i]) + 1);
461
+ }
462
+ }
463
+ --result;
464
+ return result;
465
+ }
466
+
467
+ /**
468
+ * Convert column index to label.
469
+ *
470
+ * @param {Number} column Column index.
471
+ * @returns {String} Returns column label (eq. 'ABB', 'CNQ').
472
+ */
473
+ function columnIndexToLabel(column) {
474
+ var result = "";
475
+ while (column >= 0) {
476
+ result = String.fromCharCode(column % COLUMN_LABEL_BASE_LENGTH + 97) + result;
477
+ column = Math.floor(column / COLUMN_LABEL_BASE_LENGTH) - 1;
478
+ }
479
+ return result.toUpperCase();
480
+ }
481
+ var simpleSheetName = "[A-Za-z0-9_\u4E00-\u9FFF]+";
482
+ var quotedSheetName = "'(?:(?!').|'')*'";
483
+ var sheetNameRegexp = "(".concat(simpleSheetName, "|").concat(quotedSheetName, ")!");
484
+ var LABEL_EXTRACT_REGEXP = new RegExp("^(?:".concat(sheetNameRegexp, ")?([$])?([A-Za-z]*)([$])?([0-9]*)$"));
485
+
486
+ /**
487
+ * Extract cell coordinates.
488
+ *
489
+ * @param {String} label Cell coordinates (eq. 'A1', '$B6', '$N$98').
490
+ * @returns {Array} Returns an array of objects.
491
+ */
492
+ function extractLabel(label) {
493
+ if (typeof label !== "string" || !LABEL_EXTRACT_REGEXP.test(label)) {
494
+ return [];
495
+ }
496
+ var _label$toUpperCase$ma = label.toUpperCase().match(LABEL_EXTRACT_REGEXP),
497
+ _label$toUpperCase$ma2 = _slicedToArray(_label$toUpperCase$ma, 6),
498
+ sheetNameStr = _label$toUpperCase$ma2[1],
499
+ columnAbs = _label$toUpperCase$ma2[2],
500
+ column = _label$toUpperCase$ma2[3],
501
+ rowAbs = _label$toUpperCase$ma2[4],
502
+ row = _label$toUpperCase$ma2[5];
503
+ if (column == null && row == null) return [];
504
+ var sheetName = sheetNameStr == null ? null : label.slice(0, sheetNameStr.length).replace(/^'|'$/g, "").replace(/''/g, "'");
505
+ return [{
506
+ index: rowLabelToIndex(row),
507
+ label: row,
508
+ isAbsolute: rowAbs === "$"
509
+ }, {
510
+ index: columnLabelToIndex(column),
511
+ label: column,
512
+ isAbsolute: columnAbs === "$"
513
+ }, sheetName];
514
+ }
515
+
516
+ /**
517
+ * Convert row and column indexes into cell label.
518
+ *
519
+ * @param {Object} row Object with `index` and `isAbsolute` properties.
520
+ * @param {Object} column Object with `index` and `isAbsolute` properties.
521
+ * @returns {String} Returns cell label.
522
+ */
523
+ function toLabel(row, column) {
524
+ var rowLabel = (row.isAbsolute ? "$" : "") + rowIndexToLabel(row.index);
525
+ var columnLabel = (column.isAbsolute ? "$" : "") + columnIndexToLabel(column.index);
526
+ return columnLabel + rowLabel;
527
+ }
528
+
529
+ /**
530
+ * Cell reference wrapper which keeps both the cell value and its label
531
+ * (eq. `A1`, `Sheet1!$B$3`). Functions like ROW/COLUMN need the position
532
+ * info instead of the value, so the parser must not unwrap it too early.
533
+ */
534
+ var CellReference = /*#__PURE__*/function () {
535
+ function CellReference(label, value) {
536
+ _classCallCheck(this, CellReference);
537
+ this.label = label;
538
+ this.value = value;
539
+ }
540
+ return _createClass(CellReference, [{
541
+ key: "valueOf",
542
+ value: function valueOf() {
543
+ return this.value;
544
+ }
545
+ }]);
546
+ }();
547
+
548
+ /**
549
+ * Check whether the value is a cell reference wrapper.
550
+ *
551
+ * @param {*} value
552
+ * @returns {Boolean}
553
+ */
554
+ function isCellReference(value) {
555
+ return value instanceof CellReference;
556
+ }
557
+
558
+ /**
559
+ * Get the real value out of a cell reference wrapper.
560
+ *
561
+ * @param {*} value
562
+ * @returns {*}
563
+ */
564
+ function toCellValue(value) {
565
+ return isCellReference(value) ? value.value : value;
566
+ }
567
+
568
+ /**
569
+ * Functions whose arguments are cell references instead of cell values
570
+ */
571
+ var REFERENCE_FORMULAS = ["ROW", "COLUMN"];
572
+
573
+ /**
574
+ * Check whether the function needs cell references (labels) as params.
575
+ *
576
+ * @param {String} symbol Function name.
577
+ * @returns {Boolean}
578
+ */
579
+ function isReferenceFormula(symbol) {
580
+ return REFERENCE_FORMULAS.includes(String(symbol).toUpperCase());
581
+ }
582
+
347
583
  var SUPPORTED_FORMULAS = Object.keys(formulajs);
348
584
 
349
585
  var SYMBOL$4 = SUPPORTED_FORMULAS;
@@ -353,11 +589,15 @@ function func$4(symbol) {
353
589
  for (var _len = arguments.length, _params = new Array(_len), _key = 0; _key < _len; _key++) {
354
590
  _params[_key] = arguments[_key];
355
591
  }
592
+ if (isReferenceFormula(symbol)) {
593
+ return referenceResult(symbol, _params);
594
+ }
356
595
  var params = _params === null || _params === void 0 ? void 0 : _params.map(function (item) {
357
- if (errors_formula_map[item]) {
358
- return errors_formula_map[item];
596
+ var value = toCellValue(item);
597
+ if (errors_formula_map[value]) {
598
+ return errors_formula_map[value];
359
599
  } else {
360
- return item;
600
+ return value;
361
601
  }
362
602
  });
363
603
  var symbolParts = symbol.split(".");
@@ -395,6 +635,33 @@ function func$4(symbol) {
395
635
  }
396
636
  func$4.isFactory = true;
397
637
  func$4.SYMBOL = SYMBOL$4;
638
+
639
+ /**
640
+ * 计算 ROW/COLUMN 一类以单元格引用(而不是单元格的值)作为入参的函数
641
+ *
642
+ * @param {String} fnName Function name.
643
+ * @param {Array} params Function params, may contain cell references.
644
+ * @returns {*}
645
+ */
646
+ function referenceResult(fnName, params) {
647
+ var first = params[0];
648
+ if (isCellReference(first)) {
649
+ var _extractLabel = extractLabel(first.label),
650
+ _extractLabel2 = _slicedToArray(_extractLabel, 2),
651
+ row = _extractLabel2[0],
652
+ column = _extractLabel2[1];
653
+ var index = fnName === "ROW" ? row === null || row === void 0 ? void 0 : row.index : column === null || column === void 0 ? void 0 : column.index;
654
+ if (typeof index === "number" && index >= 0) {
655
+ return index + 1;
656
+ }
657
+ } else if (errors_formula_map[first]) {
658
+ return errors_formula_map[first];
659
+ } else if (typeof first === "number") {
660
+ // 兼容直接传入行号/列号的情况,如 ROW(3)
661
+ return first;
662
+ }
663
+ return errors_formula_map[ERROR_VALUE];
664
+ }
398
665
  function tsParams(fnName, params) {
399
666
  if (fnName === "SUMPRODUCT") {
400
667
  var _params2;
@@ -536,7 +803,12 @@ func$a.SYMBOL = SYMBOL$a;
536
803
 
537
804
  var SYMBOL$b = '<>';
538
805
  function func$b(exp1, exp2) {
539
- return exp1 !== exp2;
806
+ return normalize(exp1) !== normalize(exp2);
807
+ }
808
+
809
+ // Date 按 Excel 序列号比较,=TODAY()<>TODAY() 才是 FALSE
810
+ function normalize(value) {
811
+ return isDate(value) ? dateToSerialNumber(value) : value;
540
812
  }
541
813
  func$b.SYMBOL = SYMBOL$b;
542
814
 
@@ -600,13 +872,13 @@ registerOperation(func$a.SYMBOL, func$a);
600
872
  registerOperation(func$b.SYMBOL, func$b);
601
873
  registerOperation(func$9.SYMBOL, func$9);
602
874
 
603
- var simpleSheetName = "[A-Za-z0-9_\u4E00-\u9FFF]+";
604
- var quotedSheetName = "'(?:(?!').|'')*'";
605
- var sheetNameRegexp = "(?:".concat(simpleSheetName, "|").concat(quotedSheetName, ")!");
606
- var ABSOLUTE_CELL = new RegExp("^(?:".concat(sheetNameRegexp, ")?(?:[$][A-Za-z]+[$][0-9]+)"));
607
- var MIXED_CELL_COL = new RegExp("^(?:".concat(sheetNameRegexp, ")?(?:[$][A-Za-z]+[0-9]*)"));
608
- var MIXED_CELL_ROW = new RegExp("^(?:".concat(sheetNameRegexp, ")?(?:[A-Za-z]*[$][0-9]+)"));
609
- var RELATIVE_CELL = new RegExp("^(?:".concat(sheetNameRegexp, ")?(?:(?:[A-Za-z]+[0-9]*)|(?:[A-Za-z]*[0-9]+))(?!\\d)(?!\\.)"));
875
+ var simpleSheetName$1 = "[A-Za-z0-9_\u4E00-\u9FFF]+";
876
+ var quotedSheetName$1 = "'(?:(?!').|'')*'";
877
+ var sheetNameRegexp$1 = "(?:".concat(simpleSheetName$1, "|").concat(quotedSheetName$1, ")!");
878
+ var ABSOLUTE_CELL = new RegExp("^(?:".concat(sheetNameRegexp$1, ")?(?:[$][A-Za-z]+[$][0-9]+)"));
879
+ var MIXED_CELL_COL = new RegExp("^(?:".concat(sheetNameRegexp$1, ")?(?:[$][A-Za-z]+[0-9]*)"));
880
+ var MIXED_CELL_ROW = new RegExp("^(?:".concat(sheetNameRegexp$1, ")?(?:[A-Za-z]*[$][0-9]+)"));
881
+ var RELATIVE_CELL = new RegExp("^(?:".concat(sheetNameRegexp$1, ")?(?:(?:[A-Za-z]+[0-9]*)|(?:[A-Za-z]*[0-9]+))(?!\\d)(?!\\.)"));
610
882
  var NUMONLY = /^(?:[0-9]+$)/;
611
883
  var stackCache;
612
884
  var o = function o(k, v, _o, l) {
@@ -2021,118 +2293,6 @@ function trimEdges(string) {
2021
2293
  return string;
2022
2294
  }
2023
2295
 
2024
- /**
2025
- * Convert row label to index.
2026
- *
2027
- * @param {String} label Row label (eq. '1', '5')
2028
- * @returns {Number} Returns -1 if label is not recognized otherwise proper row index.
2029
- */
2030
- function rowLabelToIndex(label) {
2031
- var result = parseInt(label, 10);
2032
- if (isNaN(result)) {
2033
- result = -1;
2034
- } else {
2035
- result = Math.max(result - 1, -1);
2036
- }
2037
- return result;
2038
- }
2039
-
2040
- /**
2041
- * Convert row index to label.
2042
- *
2043
- * @param {Number} row Row index.
2044
- * @returns {String} Returns row label (eq. '1', '7').
2045
- */
2046
- function rowIndexToLabel(row) {
2047
- var result = "";
2048
- if (row >= 0) {
2049
- result = "".concat(row + 1);
2050
- }
2051
- return result;
2052
- }
2053
- var COLUMN_LABEL_BASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
2054
- var COLUMN_LABEL_BASE_LENGTH = COLUMN_LABEL_BASE.length;
2055
-
2056
- /**
2057
- * Convert column label to index.
2058
- *
2059
- * @param {String} label Column label (eq. 'ABB', 'CNQ')
2060
- * @returns {Number} Returns -1 if label is not recognized otherwise proper column index.
2061
- */
2062
- function columnLabelToIndex(label) {
2063
- var result = 0;
2064
- if (typeof label === "string") {
2065
- label = label.toUpperCase();
2066
- for (var i = 0, j = label.length - 1; i < label.length; i += 1, j -= 1) {
2067
- result += Math.pow(COLUMN_LABEL_BASE_LENGTH, j) * (COLUMN_LABEL_BASE.indexOf(label[i]) + 1);
2068
- }
2069
- }
2070
- --result;
2071
- return result;
2072
- }
2073
-
2074
- /**
2075
- * Convert column index to label.
2076
- *
2077
- * @param {Number} column Column index.
2078
- * @returns {String} Returns column label (eq. 'ABB', 'CNQ').
2079
- */
2080
- function columnIndexToLabel(column) {
2081
- var result = "";
2082
- while (column >= 0) {
2083
- result = String.fromCharCode(column % COLUMN_LABEL_BASE_LENGTH + 97) + result;
2084
- column = Math.floor(column / COLUMN_LABEL_BASE_LENGTH) - 1;
2085
- }
2086
- return result.toUpperCase();
2087
- }
2088
- var simpleSheetName$1 = "[A-Za-z0-9_\u4E00-\u9FFF]+";
2089
- var quotedSheetName$1 = "'(?:(?!').|'')*'";
2090
- var sheetNameRegexp$1 = "(".concat(simpleSheetName$1, "|").concat(quotedSheetName$1, ")!");
2091
- var LABEL_EXTRACT_REGEXP = new RegExp("^(?:".concat(sheetNameRegexp$1, ")?([$])?([A-Za-z]*)([$])?([0-9]*)$"));
2092
-
2093
- /**
2094
- * Extract cell coordinates.
2095
- *
2096
- * @param {String} label Cell coordinates (eq. 'A1', '$B6', '$N$98').
2097
- * @returns {Array} Returns an array of objects.
2098
- */
2099
- function extractLabel(label) {
2100
- if (typeof label !== "string" || !LABEL_EXTRACT_REGEXP.test(label)) {
2101
- return [];
2102
- }
2103
- var _label$toUpperCase$ma = label.toUpperCase().match(LABEL_EXTRACT_REGEXP),
2104
- _label$toUpperCase$ma2 = _slicedToArray(_label$toUpperCase$ma, 6),
2105
- sheetNameStr = _label$toUpperCase$ma2[1],
2106
- columnAbs = _label$toUpperCase$ma2[2],
2107
- column = _label$toUpperCase$ma2[3],
2108
- rowAbs = _label$toUpperCase$ma2[4],
2109
- row = _label$toUpperCase$ma2[5];
2110
- if (column == null && row == null) return [];
2111
- var sheetName = sheetNameStr == null ? null : label.slice(0, sheetNameStr.length).replace(/^'|'$/g, "").replace(/''/g, "'");
2112
- return [{
2113
- index: rowLabelToIndex(row),
2114
- label: row,
2115
- isAbsolute: rowAbs === "$"
2116
- }, {
2117
- index: columnLabelToIndex(column),
2118
- label: column,
2119
- isAbsolute: columnAbs === "$"
2120
- }, sheetName];
2121
- }
2122
-
2123
- /**
2124
- * Convert row and column indexes into cell label.
2125
- *
2126
- * @param {Object} row Object with `index` and `isAbsolute` properties.
2127
- * @param {Object} column Object with `index` and `isAbsolute` properties.
2128
- * @returns {String} Returns cell label.
2129
- */
2130
- function toLabel(row, column) {
2131
- var rowLabel = (row.isAbsolute ? "$" : "") + rowIndexToLabel(row.index);
2132
- var columnLabel = (column.isAbsolute ? "$" : "") + columnIndexToLabel(column.index);
2133
- return columnLabel + rowLabel;
2134
- }
2135
-
2136
2296
  /**
2137
2297
  * @class Parser
2138
2298
  */
@@ -2143,16 +2303,24 @@ var Parser$1 = /*#__PURE__*/function (_Emitter) {
2143
2303
  _this = _callSuper(this, Parser$1);
2144
2304
  _this.parser = new Parser();
2145
2305
  _this.parser.yy = {
2146
- toNumber: toNumber,
2306
+ toNumber: function toNumber$1(value) {
2307
+ return toNumber(toCellValue(value));
2308
+ },
2147
2309
  trimEdges: trimEdges,
2148
- invertNumber: invertNumber,
2310
+ invertNumber: function invertNumber$1(value) {
2311
+ return invertNumber(toCellValue(value));
2312
+ },
2149
2313
  throwError: function throwError(errorName) {
2150
2314
  return _this._throwError(errorName);
2151
2315
  },
2152
2316
  callVariable: function callVariable(variable) {
2153
2317
  return _this._callVariable(variable);
2154
2318
  },
2155
- evaluateByOperator: evaluateByOperator,
2319
+ // ROW/COLUMN 的入参需要引用(label),不能解包成值
2320
+ evaluateByOperator: function evaluateByOperator$1(operator) {
2321
+ var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
2322
+ return evaluateByOperator(operator, isReferenceFormula(operator) ? params : params.map(toCellValue));
2323
+ },
2156
2324
  callFunction: function callFunction(name, params) {
2157
2325
  return _this._callFunction(name, params);
2158
2326
  },
@@ -2205,6 +2373,9 @@ var Parser$1 = /*#__PURE__*/function (_Emitter) {
2205
2373
  if (result instanceof Error) {
2206
2374
  error$1 = error(result.message) || error(ERROR);
2207
2375
  result = null;
2376
+ } else {
2377
+ // `=A1` 这类表达式的结果是引用包装对象,对外只返回值本身
2378
+ result = toCellValue(result);
2208
2379
  }
2209
2380
  return {
2210
2381
  error: error$1,
@@ -2309,15 +2480,18 @@ var Parser$1 = /*#__PURE__*/function (_Emitter) {
2309
2480
  value: function _callFunction(name) {
2310
2481
  var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
2311
2482
  var fn = this.getFunction(name);
2483
+ var args = params.map(toCellValue);
2312
2484
  var value;
2313
2485
  if (fn) {
2314
- value = fn(params);
2486
+ value = fn(args);
2315
2487
  }
2316
- this.emit("callFunction", name, params, function (newValue) {
2488
+ this.emit("callFunction", name, args, function (newValue) {
2317
2489
  if (newValue !== void 0) {
2318
2490
  value = newValue;
2319
2491
  }
2320
2492
  });
2493
+
2494
+ // `params` 里可能带着单元格引用(ROW/COLUMN 需要),由 formula-function 自行解包
2321
2495
  return value === void 0 ? evaluateByOperator(name, params) : value;
2322
2496
  }
2323
2497
 
@@ -2353,7 +2527,9 @@ var Parser$1 = /*#__PURE__*/function (_Emitter) {
2353
2527
  }, this.options, function (_value) {
2354
2528
  value = _value;
2355
2529
  });
2356
- return value;
2530
+
2531
+ // 同时保留 label,供 ROW/COLUMN 等需要引用位置的函数使用
2532
+ return new CellReference(label, value);
2357
2533
  }
2358
2534
 
2359
2535
  /**
package/dist/index.js CHANGED
@@ -197,10 +197,54 @@ function _nonIterableRest() {
197
197
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
198
198
  }
199
199
 
200
+ var MS_PER_DAY = 24 * 60 * 60 * 1000;
201
+
202
+ /**
203
+ * 1900 日期系统下 Excel 的 0 点(1899-12-31 00:00:00 UTC)。
204
+ */
205
+ var EXCEL_EPOCH_UTC = Date.UTC(1899, 11, 31, 0, 0, 0);
206
+
207
+ /**
208
+ * Excel 虚构的 1900-02-29 之后的第一天(1900-03-01)。
209
+ * 当天及之后的日期需要补 1 天,才能和 Excel 的序列号对齐。
210
+ */
211
+ var EXCEL_LEAP_BUG_BASE = new Date(1900, 2, 1, 0, 0, 0);
212
+
213
+ /**
214
+ * 判断是否为有效的 Date 对象。
215
+ *
216
+ * @param {*} value 待判断的值。
217
+ * @returns {Boolean}
218
+ */
219
+ function isDate(value) {
220
+ return value instanceof Date && !Number.isNaN(value.getTime());
221
+ }
222
+
223
+ /**
224
+ * 把 Date 转成 Excel 日期序列号。
225
+ *
226
+ * 与 core 中 modules/format.ts 的 datenum_local 保持完全一致:
227
+ * 取本地年月日时分秒再按 UTC 计算,避免时区和夏令时带来的偏移;
228
+ * 1900-03-01 及之后的日期补 1 天,对齐 Excel 的 1900 闰年 bug。
229
+ *
230
+ * @param {Date} date 待转换的日期。
231
+ * @param {Number} [date1904] 是否使用 1904 日期系统。
232
+ * @returns {Number} Excel 序列号,整数部分为日期,小数部分为时间。
233
+ */
234
+ function dateToSerialNumber(date, date1904) {
235
+ var epoch = Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds());
236
+ if (date1904) {
237
+ epoch -= 1461 * MS_PER_DAY;
238
+ } else if (date >= EXCEL_LEAP_BUG_BASE) {
239
+ epoch += MS_PER_DAY;
240
+ }
241
+ return (epoch - EXCEL_EPOCH_UTC) / MS_PER_DAY;
242
+ }
243
+
200
244
  /**
201
245
  * Convert value into number.
202
246
  *
203
- * @param {String|Number} number
247
+ * @param {String|Number|Date} number
204
248
  * @returns {*}
205
249
  */
206
250
  function toNumber(number) {
@@ -208,6 +252,10 @@ function toNumber(number) {
208
252
  if (number === true) {
209
253
  return 1;
210
254
  }
255
+ // DATE/TODAY/NOW 等函数返回 Date 对象,按 Excel 序列号参与运算
256
+ if (isDate(number)) {
257
+ return dateToSerialNumber(number);
258
+ }
211
259
  if (typeof number === 'number') {
212
260
  result = number;
213
261
  } else if (typeof number === 'string') {
@@ -219,7 +267,7 @@ function toNumber(number) {
219
267
  /**
220
268
  * Invert provided number.
221
269
  *
222
- * @param {Number} number
270
+ * @param {Number|Date} number Provided number.
223
271
  * @returns {Number} Returns inverted number.
224
272
  */
225
273
  function invertNumber(number) {
@@ -231,6 +279,9 @@ function toNumberNotNaN(number) {
231
279
  if (number === true) {
232
280
  return 1;
233
281
  }
282
+ if (isDate(number)) {
283
+ return dateToSerialNumber(number);
284
+ }
234
285
  if (typeof number === 'number') {
235
286
  result = number;
236
287
  } else if (typeof number === 'string') {
@@ -306,9 +357,14 @@ function func$1() {
306
357
  params[_key] = arguments[_key];
307
358
  }
308
359
  return params.reduce(function (acc, value) {
309
- return acc + value.toString();
360
+ return acc + toString(value);
310
361
  }, '');
311
362
  }
363
+
364
+ // Date 拼接时取 Excel 序列号,避免出现 "Tue Oct 20 2026 ..." 这类 JS 默认格式
365
+ function toString(value) {
366
+ return isDate(value) ? String(dateToSerialNumber(value)) : value.toString();
367
+ }
312
368
  func$1.SYMBOL = SYMBOL$1;
313
369
 
314
370
  var SYMBOL$2 = '/';
@@ -362,9 +418,23 @@ function compare(exp1, exp2, type) {
362
418
  return tsValue(exp1) === tsValue(exp2);
363
419
  }
364
420
  }
365
- function tsValue(value) {
421
+
422
+ /**
423
+ * 比较前的取值归一化:Date 统一转成 Excel 序列号,
424
+ * 这样 =TODAY()>A1、=TODAY()=TODAY() 才能按日期天数比较。
425
+ *
426
+ * @param {*} value 待归一化的值。
427
+ * @returns {*}
428
+ */
429
+ function toComparable(value) {
430
+ if (isDate(value)) {
431
+ return dateToSerialNumber(value);
432
+ }
366
433
  return value !== null && value !== void 0 ? value : 0;
367
434
  }
435
+ function tsValue(value) {
436
+ return toComparable(value);
437
+ }
368
438
 
369
439
  var SYMBOL$3 = '=';
370
440
  function func$3(exp1, exp2) {
@@ -372,6 +442,172 @@ function func$3(exp1, exp2) {
372
442
  }
373
443
  func$3.SYMBOL = SYMBOL$3;
374
444
 
445
+ /**
446
+ * Convert row label to index.
447
+ *
448
+ * @param {String} label Row label (eq. '1', '5')
449
+ * @returns {Number} Returns -1 if label is not recognized otherwise proper row index.
450
+ */
451
+ function rowLabelToIndex(label) {
452
+ var result = parseInt(label, 10);
453
+ if (isNaN(result)) {
454
+ result = -1;
455
+ } else {
456
+ result = Math.max(result - 1, -1);
457
+ }
458
+ return result;
459
+ }
460
+
461
+ /**
462
+ * Convert row index to label.
463
+ *
464
+ * @param {Number} row Row index.
465
+ * @returns {String} Returns row label (eq. '1', '7').
466
+ */
467
+ function rowIndexToLabel(row) {
468
+ var result = "";
469
+ if (row >= 0) {
470
+ result = "".concat(row + 1);
471
+ }
472
+ return result;
473
+ }
474
+ var COLUMN_LABEL_BASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
475
+ var COLUMN_LABEL_BASE_LENGTH = COLUMN_LABEL_BASE.length;
476
+
477
+ /**
478
+ * Convert column label to index.
479
+ *
480
+ * @param {String} label Column label (eq. 'ABB', 'CNQ')
481
+ * @returns {Number} Returns -1 if label is not recognized otherwise proper column index.
482
+ */
483
+ function columnLabelToIndex(label) {
484
+ var result = 0;
485
+ if (typeof label === "string") {
486
+ label = label.toUpperCase();
487
+ for (var i = 0, j = label.length - 1; i < label.length; i += 1, j -= 1) {
488
+ result += Math.pow(COLUMN_LABEL_BASE_LENGTH, j) * (COLUMN_LABEL_BASE.indexOf(label[i]) + 1);
489
+ }
490
+ }
491
+ --result;
492
+ return result;
493
+ }
494
+
495
+ /**
496
+ * Convert column index to label.
497
+ *
498
+ * @param {Number} column Column index.
499
+ * @returns {String} Returns column label (eq. 'ABB', 'CNQ').
500
+ */
501
+ function columnIndexToLabel(column) {
502
+ var result = "";
503
+ while (column >= 0) {
504
+ result = String.fromCharCode(column % COLUMN_LABEL_BASE_LENGTH + 97) + result;
505
+ column = Math.floor(column / COLUMN_LABEL_BASE_LENGTH) - 1;
506
+ }
507
+ return result.toUpperCase();
508
+ }
509
+ var simpleSheetName = "[A-Za-z0-9_\u4E00-\u9FFF]+";
510
+ var quotedSheetName = "'(?:(?!').|'')*'";
511
+ var sheetNameRegexp = "(".concat(simpleSheetName, "|").concat(quotedSheetName, ")!");
512
+ var LABEL_EXTRACT_REGEXP = new RegExp("^(?:".concat(sheetNameRegexp, ")?([$])?([A-Za-z]*)([$])?([0-9]*)$"));
513
+
514
+ /**
515
+ * Extract cell coordinates.
516
+ *
517
+ * @param {String} label Cell coordinates (eq. 'A1', '$B6', '$N$98').
518
+ * @returns {Array} Returns an array of objects.
519
+ */
520
+ function extractLabel(label) {
521
+ if (typeof label !== "string" || !LABEL_EXTRACT_REGEXP.test(label)) {
522
+ return [];
523
+ }
524
+ var _label$toUpperCase$ma = label.toUpperCase().match(LABEL_EXTRACT_REGEXP),
525
+ _label$toUpperCase$ma2 = _slicedToArray(_label$toUpperCase$ma, 6),
526
+ sheetNameStr = _label$toUpperCase$ma2[1],
527
+ columnAbs = _label$toUpperCase$ma2[2],
528
+ column = _label$toUpperCase$ma2[3],
529
+ rowAbs = _label$toUpperCase$ma2[4],
530
+ row = _label$toUpperCase$ma2[5];
531
+ if (column == null && row == null) return [];
532
+ var sheetName = sheetNameStr == null ? null : label.slice(0, sheetNameStr.length).replace(/^'|'$/g, "").replace(/''/g, "'");
533
+ return [{
534
+ index: rowLabelToIndex(row),
535
+ label: row,
536
+ isAbsolute: rowAbs === "$"
537
+ }, {
538
+ index: columnLabelToIndex(column),
539
+ label: column,
540
+ isAbsolute: columnAbs === "$"
541
+ }, sheetName];
542
+ }
543
+
544
+ /**
545
+ * Convert row and column indexes into cell label.
546
+ *
547
+ * @param {Object} row Object with `index` and `isAbsolute` properties.
548
+ * @param {Object} column Object with `index` and `isAbsolute` properties.
549
+ * @returns {String} Returns cell label.
550
+ */
551
+ function toLabel(row, column) {
552
+ var rowLabel = (row.isAbsolute ? "$" : "") + rowIndexToLabel(row.index);
553
+ var columnLabel = (column.isAbsolute ? "$" : "") + columnIndexToLabel(column.index);
554
+ return columnLabel + rowLabel;
555
+ }
556
+
557
+ /**
558
+ * Cell reference wrapper which keeps both the cell value and its label
559
+ * (eq. `A1`, `Sheet1!$B$3`). Functions like ROW/COLUMN need the position
560
+ * info instead of the value, so the parser must not unwrap it too early.
561
+ */
562
+ var CellReference = /*#__PURE__*/function () {
563
+ function CellReference(label, value) {
564
+ _classCallCheck(this, CellReference);
565
+ this.label = label;
566
+ this.value = value;
567
+ }
568
+ return _createClass(CellReference, [{
569
+ key: "valueOf",
570
+ value: function valueOf() {
571
+ return this.value;
572
+ }
573
+ }]);
574
+ }();
575
+
576
+ /**
577
+ * Check whether the value is a cell reference wrapper.
578
+ *
579
+ * @param {*} value
580
+ * @returns {Boolean}
581
+ */
582
+ function isCellReference(value) {
583
+ return value instanceof CellReference;
584
+ }
585
+
586
+ /**
587
+ * Get the real value out of a cell reference wrapper.
588
+ *
589
+ * @param {*} value
590
+ * @returns {*}
591
+ */
592
+ function toCellValue(value) {
593
+ return isCellReference(value) ? value.value : value;
594
+ }
595
+
596
+ /**
597
+ * Functions whose arguments are cell references instead of cell values
598
+ */
599
+ var REFERENCE_FORMULAS = ["ROW", "COLUMN"];
600
+
601
+ /**
602
+ * Check whether the function needs cell references (labels) as params.
603
+ *
604
+ * @param {String} symbol Function name.
605
+ * @returns {Boolean}
606
+ */
607
+ function isReferenceFormula(symbol) {
608
+ return REFERENCE_FORMULAS.includes(String(symbol).toUpperCase());
609
+ }
610
+
375
611
  var SUPPORTED_FORMULAS = Object.keys(formulajs__namespace);
376
612
 
377
613
  var SYMBOL$4 = SUPPORTED_FORMULAS;
@@ -381,11 +617,15 @@ function func$4(symbol) {
381
617
  for (var _len = arguments.length, _params = new Array(_len), _key = 0; _key < _len; _key++) {
382
618
  _params[_key] = arguments[_key];
383
619
  }
620
+ if (isReferenceFormula(symbol)) {
621
+ return referenceResult(symbol, _params);
622
+ }
384
623
  var params = _params === null || _params === void 0 ? void 0 : _params.map(function (item) {
385
- if (errors_formula_map[item]) {
386
- return errors_formula_map[item];
624
+ var value = toCellValue(item);
625
+ if (errors_formula_map[value]) {
626
+ return errors_formula_map[value];
387
627
  } else {
388
- return item;
628
+ return value;
389
629
  }
390
630
  });
391
631
  var symbolParts = symbol.split(".");
@@ -423,6 +663,33 @@ function func$4(symbol) {
423
663
  }
424
664
  func$4.isFactory = true;
425
665
  func$4.SYMBOL = SYMBOL$4;
666
+
667
+ /**
668
+ * 计算 ROW/COLUMN 一类以单元格引用(而不是单元格的值)作为入参的函数
669
+ *
670
+ * @param {String} fnName Function name.
671
+ * @param {Array} params Function params, may contain cell references.
672
+ * @returns {*}
673
+ */
674
+ function referenceResult(fnName, params) {
675
+ var first = params[0];
676
+ if (isCellReference(first)) {
677
+ var _extractLabel = extractLabel(first.label),
678
+ _extractLabel2 = _slicedToArray(_extractLabel, 2),
679
+ row = _extractLabel2[0],
680
+ column = _extractLabel2[1];
681
+ var index = fnName === "ROW" ? row === null || row === void 0 ? void 0 : row.index : column === null || column === void 0 ? void 0 : column.index;
682
+ if (typeof index === "number" && index >= 0) {
683
+ return index + 1;
684
+ }
685
+ } else if (errors_formula_map[first]) {
686
+ return errors_formula_map[first];
687
+ } else if (typeof first === "number") {
688
+ // 兼容直接传入行号/列号的情况,如 ROW(3)
689
+ return first;
690
+ }
691
+ return errors_formula_map[ERROR_VALUE];
692
+ }
426
693
  function tsParams(fnName, params) {
427
694
  if (fnName === "SUMPRODUCT") {
428
695
  var _params2;
@@ -564,7 +831,12 @@ func$a.SYMBOL = SYMBOL$a;
564
831
 
565
832
  var SYMBOL$b = '<>';
566
833
  function func$b(exp1, exp2) {
567
- return exp1 !== exp2;
834
+ return normalize(exp1) !== normalize(exp2);
835
+ }
836
+
837
+ // Date 按 Excel 序列号比较,=TODAY()<>TODAY() 才是 FALSE
838
+ function normalize(value) {
839
+ return isDate(value) ? dateToSerialNumber(value) : value;
568
840
  }
569
841
  func$b.SYMBOL = SYMBOL$b;
570
842
 
@@ -628,13 +900,13 @@ registerOperation(func$a.SYMBOL, func$a);
628
900
  registerOperation(func$b.SYMBOL, func$b);
629
901
  registerOperation(func$9.SYMBOL, func$9);
630
902
 
631
- var simpleSheetName = "[A-Za-z0-9_\u4E00-\u9FFF]+";
632
- var quotedSheetName = "'(?:(?!').|'')*'";
633
- var sheetNameRegexp = "(?:".concat(simpleSheetName, "|").concat(quotedSheetName, ")!");
634
- var ABSOLUTE_CELL = new RegExp("^(?:".concat(sheetNameRegexp, ")?(?:[$][A-Za-z]+[$][0-9]+)"));
635
- var MIXED_CELL_COL = new RegExp("^(?:".concat(sheetNameRegexp, ")?(?:[$][A-Za-z]+[0-9]*)"));
636
- var MIXED_CELL_ROW = new RegExp("^(?:".concat(sheetNameRegexp, ")?(?:[A-Za-z]*[$][0-9]+)"));
637
- var RELATIVE_CELL = new RegExp("^(?:".concat(sheetNameRegexp, ")?(?:(?:[A-Za-z]+[0-9]*)|(?:[A-Za-z]*[0-9]+))(?!\\d)(?!\\.)"));
903
+ var simpleSheetName$1 = "[A-Za-z0-9_\u4E00-\u9FFF]+";
904
+ var quotedSheetName$1 = "'(?:(?!').|'')*'";
905
+ var sheetNameRegexp$1 = "(?:".concat(simpleSheetName$1, "|").concat(quotedSheetName$1, ")!");
906
+ var ABSOLUTE_CELL = new RegExp("^(?:".concat(sheetNameRegexp$1, ")?(?:[$][A-Za-z]+[$][0-9]+)"));
907
+ var MIXED_CELL_COL = new RegExp("^(?:".concat(sheetNameRegexp$1, ")?(?:[$][A-Za-z]+[0-9]*)"));
908
+ var MIXED_CELL_ROW = new RegExp("^(?:".concat(sheetNameRegexp$1, ")?(?:[A-Za-z]*[$][0-9]+)"));
909
+ var RELATIVE_CELL = new RegExp("^(?:".concat(sheetNameRegexp$1, ")?(?:(?:[A-Za-z]+[0-9]*)|(?:[A-Za-z]*[0-9]+))(?!\\d)(?!\\.)"));
638
910
  var NUMONLY = /^(?:[0-9]+$)/;
639
911
  var stackCache;
640
912
  var o = function o(k, v, _o, l) {
@@ -2049,118 +2321,6 @@ function trimEdges(string) {
2049
2321
  return string;
2050
2322
  }
2051
2323
 
2052
- /**
2053
- * Convert row label to index.
2054
- *
2055
- * @param {String} label Row label (eq. '1', '5')
2056
- * @returns {Number} Returns -1 if label is not recognized otherwise proper row index.
2057
- */
2058
- function rowLabelToIndex(label) {
2059
- var result = parseInt(label, 10);
2060
- if (isNaN(result)) {
2061
- result = -1;
2062
- } else {
2063
- result = Math.max(result - 1, -1);
2064
- }
2065
- return result;
2066
- }
2067
-
2068
- /**
2069
- * Convert row index to label.
2070
- *
2071
- * @param {Number} row Row index.
2072
- * @returns {String} Returns row label (eq. '1', '7').
2073
- */
2074
- function rowIndexToLabel(row) {
2075
- var result = "";
2076
- if (row >= 0) {
2077
- result = "".concat(row + 1);
2078
- }
2079
- return result;
2080
- }
2081
- var COLUMN_LABEL_BASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
2082
- var COLUMN_LABEL_BASE_LENGTH = COLUMN_LABEL_BASE.length;
2083
-
2084
- /**
2085
- * Convert column label to index.
2086
- *
2087
- * @param {String} label Column label (eq. 'ABB', 'CNQ')
2088
- * @returns {Number} Returns -1 if label is not recognized otherwise proper column index.
2089
- */
2090
- function columnLabelToIndex(label) {
2091
- var result = 0;
2092
- if (typeof label === "string") {
2093
- label = label.toUpperCase();
2094
- for (var i = 0, j = label.length - 1; i < label.length; i += 1, j -= 1) {
2095
- result += Math.pow(COLUMN_LABEL_BASE_LENGTH, j) * (COLUMN_LABEL_BASE.indexOf(label[i]) + 1);
2096
- }
2097
- }
2098
- --result;
2099
- return result;
2100
- }
2101
-
2102
- /**
2103
- * Convert column index to label.
2104
- *
2105
- * @param {Number} column Column index.
2106
- * @returns {String} Returns column label (eq. 'ABB', 'CNQ').
2107
- */
2108
- function columnIndexToLabel(column) {
2109
- var result = "";
2110
- while (column >= 0) {
2111
- result = String.fromCharCode(column % COLUMN_LABEL_BASE_LENGTH + 97) + result;
2112
- column = Math.floor(column / COLUMN_LABEL_BASE_LENGTH) - 1;
2113
- }
2114
- return result.toUpperCase();
2115
- }
2116
- var simpleSheetName$1 = "[A-Za-z0-9_\u4E00-\u9FFF]+";
2117
- var quotedSheetName$1 = "'(?:(?!').|'')*'";
2118
- var sheetNameRegexp$1 = "(".concat(simpleSheetName$1, "|").concat(quotedSheetName$1, ")!");
2119
- var LABEL_EXTRACT_REGEXP = new RegExp("^(?:".concat(sheetNameRegexp$1, ")?([$])?([A-Za-z]*)([$])?([0-9]*)$"));
2120
-
2121
- /**
2122
- * Extract cell coordinates.
2123
- *
2124
- * @param {String} label Cell coordinates (eq. 'A1', '$B6', '$N$98').
2125
- * @returns {Array} Returns an array of objects.
2126
- */
2127
- function extractLabel(label) {
2128
- if (typeof label !== "string" || !LABEL_EXTRACT_REGEXP.test(label)) {
2129
- return [];
2130
- }
2131
- var _label$toUpperCase$ma = label.toUpperCase().match(LABEL_EXTRACT_REGEXP),
2132
- _label$toUpperCase$ma2 = _slicedToArray(_label$toUpperCase$ma, 6),
2133
- sheetNameStr = _label$toUpperCase$ma2[1],
2134
- columnAbs = _label$toUpperCase$ma2[2],
2135
- column = _label$toUpperCase$ma2[3],
2136
- rowAbs = _label$toUpperCase$ma2[4],
2137
- row = _label$toUpperCase$ma2[5];
2138
- if (column == null && row == null) return [];
2139
- var sheetName = sheetNameStr == null ? null : label.slice(0, sheetNameStr.length).replace(/^'|'$/g, "").replace(/''/g, "'");
2140
- return [{
2141
- index: rowLabelToIndex(row),
2142
- label: row,
2143
- isAbsolute: rowAbs === "$"
2144
- }, {
2145
- index: columnLabelToIndex(column),
2146
- label: column,
2147
- isAbsolute: columnAbs === "$"
2148
- }, sheetName];
2149
- }
2150
-
2151
- /**
2152
- * Convert row and column indexes into cell label.
2153
- *
2154
- * @param {Object} row Object with `index` and `isAbsolute` properties.
2155
- * @param {Object} column Object with `index` and `isAbsolute` properties.
2156
- * @returns {String} Returns cell label.
2157
- */
2158
- function toLabel(row, column) {
2159
- var rowLabel = (row.isAbsolute ? "$" : "") + rowIndexToLabel(row.index);
2160
- var columnLabel = (column.isAbsolute ? "$" : "") + columnIndexToLabel(column.index);
2161
- return columnLabel + rowLabel;
2162
- }
2163
-
2164
2324
  /**
2165
2325
  * @class Parser
2166
2326
  */
@@ -2171,16 +2331,24 @@ var Parser$1 = /*#__PURE__*/function (_Emitter) {
2171
2331
  _this = _callSuper(this, Parser$1);
2172
2332
  _this.parser = new Parser();
2173
2333
  _this.parser.yy = {
2174
- toNumber: toNumber,
2334
+ toNumber: function toNumber$1(value) {
2335
+ return toNumber(toCellValue(value));
2336
+ },
2175
2337
  trimEdges: trimEdges,
2176
- invertNumber: invertNumber,
2338
+ invertNumber: function invertNumber$1(value) {
2339
+ return invertNumber(toCellValue(value));
2340
+ },
2177
2341
  throwError: function throwError(errorName) {
2178
2342
  return _this._throwError(errorName);
2179
2343
  },
2180
2344
  callVariable: function callVariable(variable) {
2181
2345
  return _this._callVariable(variable);
2182
2346
  },
2183
- evaluateByOperator: evaluateByOperator,
2347
+ // ROW/COLUMN 的入参需要引用(label),不能解包成值
2348
+ evaluateByOperator: function evaluateByOperator$1(operator) {
2349
+ var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
2350
+ return evaluateByOperator(operator, isReferenceFormula(operator) ? params : params.map(toCellValue));
2351
+ },
2184
2352
  callFunction: function callFunction(name, params) {
2185
2353
  return _this._callFunction(name, params);
2186
2354
  },
@@ -2233,6 +2401,9 @@ var Parser$1 = /*#__PURE__*/function (_Emitter) {
2233
2401
  if (result instanceof Error) {
2234
2402
  error$1 = error(result.message) || error(ERROR);
2235
2403
  result = null;
2404
+ } else {
2405
+ // `=A1` 这类表达式的结果是引用包装对象,对外只返回值本身
2406
+ result = toCellValue(result);
2236
2407
  }
2237
2408
  return {
2238
2409
  error: error$1,
@@ -2337,15 +2508,18 @@ var Parser$1 = /*#__PURE__*/function (_Emitter) {
2337
2508
  value: function _callFunction(name) {
2338
2509
  var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
2339
2510
  var fn = this.getFunction(name);
2511
+ var args = params.map(toCellValue);
2340
2512
  var value;
2341
2513
  if (fn) {
2342
- value = fn(params);
2514
+ value = fn(args);
2343
2515
  }
2344
- this.emit("callFunction", name, params, function (newValue) {
2516
+ this.emit("callFunction", name, args, function (newValue) {
2345
2517
  if (newValue !== void 0) {
2346
2518
  value = newValue;
2347
2519
  }
2348
2520
  });
2521
+
2522
+ // `params` 里可能带着单元格引用(ROW/COLUMN 需要),由 formula-function 自行解包
2349
2523
  return value === void 0 ? evaluateByOperator(name, params) : value;
2350
2524
  }
2351
2525
 
@@ -2381,7 +2555,9 @@ var Parser$1 = /*#__PURE__*/function (_Emitter) {
2381
2555
  }, this.options, function (_value) {
2382
2556
  value = _value;
2383
2557
  });
2384
- return value;
2558
+
2559
+ // 同时保留 label,供 ROW/COLUMN 等需要引用位置的函数使用
2560
+ return new CellReference(label, value);
2385
2561
  }
2386
2562
 
2387
2563
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leankylin-sheet/formula-parser",
3
- "version": "7.0.23",
3
+ "version": "7.0.25",
4
4
  "description": "Formula parser",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",