@univerjs/engine-formula 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/index.js +153 -34
- package/lib/es/index.js +153 -34
- package/lib/index.js +153 -34
- package/lib/umd/index.js +3 -3
- package/package.json +4 -4
package/lib/index.js
CHANGED
|
@@ -9740,6 +9740,89 @@ function baseValueObjectToArrayValueObject(valueObject) {
|
|
|
9740
9740
|
if (valueObject.isArray()) return valueObject;
|
|
9741
9741
|
return ArrayValueObject.createByArray([[valueObject.getValue()]]);
|
|
9742
9742
|
}
|
|
9743
|
+
function getEqualityValueKeys(value) {
|
|
9744
|
+
const keys = [];
|
|
9745
|
+
if (value.isString()) keys.push(normalizeTextForComparison(String(value.getValue())));
|
|
9746
|
+
else if (!value.isNumber()) return keys;
|
|
9747
|
+
const number = value.isNumber() ? value : createCriteriaValueObject(String(value.getValue()), value.getDateSystem());
|
|
9748
|
+
if (number.isNumber() && Number.isFinite(Number(number.getValue()))) keys.push(stripErrorMargin(Number(number.getValue())));
|
|
9749
|
+
return keys;
|
|
9750
|
+
}
|
|
9751
|
+
function buildEqualityIndex(range) {
|
|
9752
|
+
const index = /* @__PURE__ */ new Map();
|
|
9753
|
+
range.iterator((value, row, column) => {
|
|
9754
|
+
if (!value) return;
|
|
9755
|
+
const position = [row, column];
|
|
9756
|
+
for (const key of getEqualityValueKeys(value)) {
|
|
9757
|
+
let matches = index.get(key);
|
|
9758
|
+
if (!matches) {
|
|
9759
|
+
matches = [];
|
|
9760
|
+
index.set(key, matches);
|
|
9761
|
+
}
|
|
9762
|
+
matches.push(position);
|
|
9763
|
+
}
|
|
9764
|
+
});
|
|
9765
|
+
return index;
|
|
9766
|
+
}
|
|
9767
|
+
function getIndexedPositions(index, keys, range) {
|
|
9768
|
+
const buckets = keys.map((key) => index.get(key) ?? []);
|
|
9769
|
+
if (buckets.reduce((count, bucket) => count + bucket.length, 0) >= range.getRowCount() * range.getColumnCount() / 2) return;
|
|
9770
|
+
if (buckets.length === 1) return buckets[0];
|
|
9771
|
+
return Array.from(new Set(buckets.flat())).sort((a, b) => a[0] - b[0] || a[1] - b[1]);
|
|
9772
|
+
}
|
|
9773
|
+
function pickRangePositions(range, positions) {
|
|
9774
|
+
return ArrayValueObject.create({
|
|
9775
|
+
calculateValueList: positions.map(([row, column]) => [range.get(row, column)]),
|
|
9776
|
+
rowCount: positions.length,
|
|
9777
|
+
columnCount: 1,
|
|
9778
|
+
unitId: "",
|
|
9779
|
+
sheetId: "",
|
|
9780
|
+
row: -1,
|
|
9781
|
+
column: -1
|
|
9782
|
+
});
|
|
9783
|
+
}
|
|
9784
|
+
function getExactCriteriaKeys(criteria) {
|
|
9785
|
+
if (!criteria || !criteria.isString() && !criteria.isNumber()) return;
|
|
9786
|
+
const [operator, value] = criteria.isString() ? findCompareToken(String(criteria.getValue()), criteria.getDateSystem()) : ["=", criteria];
|
|
9787
|
+
if (operator !== "=" || value.isDateFormat()) return;
|
|
9788
|
+
if (value.isString() && (value.getValue() === "" || isWildcard(String(value.getValue())))) return;
|
|
9789
|
+
const keys = getEqualityValueKeys(value);
|
|
9790
|
+
return keys.length > 0 ? keys : void 0;
|
|
9791
|
+
}
|
|
9792
|
+
function getCriteriaCacheKey(criteria) {
|
|
9793
|
+
if (criteria.length === 0 || criteria.some((value) => getExactCriteriaKeys(value) === void 0)) return;
|
|
9794
|
+
const values = criteria.map((value) => value.getValue());
|
|
9795
|
+
return values.length === 1 ? values[0] : JSON.stringify(values);
|
|
9796
|
+
}
|
|
9797
|
+
function getCriteriaPositions(pairs, indexes, row, column) {
|
|
9798
|
+
for (const { range, criteriaArray } of pairs) {
|
|
9799
|
+
const keys = getExactCriteriaKeys(criteriaArray.get(row, column));
|
|
9800
|
+
if (!keys) continue;
|
|
9801
|
+
let index = indexes.get(range);
|
|
9802
|
+
if (!index) {
|
|
9803
|
+
index = buildEqualityIndex(range);
|
|
9804
|
+
indexes.set(range, index);
|
|
9805
|
+
}
|
|
9806
|
+
const positions = getIndexedPositions(index, keys, range);
|
|
9807
|
+
if (positions !== void 0) return positions;
|
|
9808
|
+
}
|
|
9809
|
+
}
|
|
9810
|
+
function getConditionalAggregateResult(formulaName, comparison, targetRange) {
|
|
9811
|
+
if (formulaName === "COUNTIFS") {
|
|
9812
|
+
let count = 0;
|
|
9813
|
+
comparison.iterator((value) => {
|
|
9814
|
+
if ((value === null || value === void 0 ? void 0 : value.isBoolean()) && value.getValue() === true) count++;
|
|
9815
|
+
});
|
|
9816
|
+
return NumberValueObject.create(count);
|
|
9817
|
+
}
|
|
9818
|
+
const picked = targetRange === null || targetRange === void 0 ? void 0 : targetRange.pick(comparison);
|
|
9819
|
+
switch (formulaName) {
|
|
9820
|
+
case "SUMIFS": return picked.sum();
|
|
9821
|
+
case "AVERAGEIFS": return picked.sum().divided(picked.count());
|
|
9822
|
+
case "MAXIFS": return picked.getColumnCount() === 0 ? NumberValueObject.create(0) : picked.max();
|
|
9823
|
+
case "MINIFS": return picked.getColumnCount() === 0 ? NumberValueObject.create(0) : picked.min();
|
|
9824
|
+
}
|
|
9825
|
+
}
|
|
9743
9826
|
/**
|
|
9744
9827
|
* Get the paired range and criteria result for COUNTIFS, SUMIFS, etc.
|
|
9745
9828
|
*/
|
|
@@ -9758,50 +9841,48 @@ function getPairedRangeAndCriteriaResult(variants, params) {
|
|
|
9758
9841
|
}
|
|
9759
9842
|
if (rangeAndCriteriaArrays.length === 0) return [];
|
|
9760
9843
|
const results = [];
|
|
9761
|
-
|
|
9762
|
-
|
|
9763
|
-
|
|
9764
|
-
|
|
9765
|
-
*
|
|
9766
|
-
*/
|
|
9844
|
+
const arrayPairs = rangeAndCriteriaArrays.filter((_, index) => {
|
|
9845
|
+
const criteria = variants[index * 2 + 1];
|
|
9846
|
+
return criteria.isArray() && criteria.getRowCount() * criteria.getColumnCount() > 1;
|
|
9847
|
+
});
|
|
9848
|
+
const useEqualityIndex = isNumberSensitive && maxRowLength * maxColumnLength > 1 && arrayPairs.length > 0;
|
|
9849
|
+
const repeatedResults = /* @__PURE__ */ new Map();
|
|
9850
|
+
const equalityIndexes = /* @__PURE__ */ new Map();
|
|
9767
9851
|
rangeAndCriteriaArrays[0].criteriaArray.iterator((_, rowIndex, columnIndex) => {
|
|
9768
9852
|
let finalCompareResult;
|
|
9769
|
-
|
|
9770
|
-
|
|
9853
|
+
let positions;
|
|
9854
|
+
const cacheKey = useEqualityIndex ? getCriteriaCacheKey(arrayPairs.map(({ criteriaArray }) => criteriaArray.get(rowIndex, columnIndex))) : void 0;
|
|
9855
|
+
const cached = cacheKey === void 0 ? void 0 : repeatedResults.get(cacheKey);
|
|
9856
|
+
if (cached) {
|
|
9857
|
+
results[rowIndex] ??= [];
|
|
9858
|
+
results[rowIndex][columnIndex] = cached;
|
|
9859
|
+
return;
|
|
9860
|
+
}
|
|
9861
|
+
if (useEqualityIndex) {
|
|
9862
|
+
positions = getCriteriaPositions(arrayPairs, equalityIndexes, rowIndex, columnIndex);
|
|
9863
|
+
if ((positions === null || positions === void 0 ? void 0 : positions.length) === 0) {
|
|
9864
|
+
results[rowIndex] ??= [];
|
|
9865
|
+
results[rowIndex][columnIndex] = formulaName === "AVERAGEIFS" ? ErrorValueObject.create("#DIV/0!") : NumberValueObject.create(0);
|
|
9866
|
+
return;
|
|
9867
|
+
}
|
|
9868
|
+
}
|
|
9869
|
+
rangeAndCriteriaArrays.forEach(({ range: sourceRange, criteriaArray }) => {
|
|
9870
|
+
const range = positions === void 0 ? sourceRange : pickRangePositions(sourceRange, positions);
|
|
9771
9871
|
const criteriaValueObject = criteriaArray.get(rowIndex, columnIndex);
|
|
9772
|
-
if (!criteriaValueObject)
|
|
9872
|
+
if (!criteriaValueObject) return;
|
|
9773
9873
|
let compareResult = valueObjectCompare(range, criteriaValueObject);
|
|
9774
9874
|
if (isNumberSensitive) compareResult = filterSameValueObjectResult(compareResult, range, criteriaValueObject);
|
|
9775
9875
|
if (finalCompareResult === void 0) {
|
|
9776
9876
|
finalCompareResult = compareResult;
|
|
9777
|
-
|
|
9877
|
+
return;
|
|
9778
9878
|
}
|
|
9779
9879
|
finalCompareResult = booleanObjectIntersection(finalCompareResult, compareResult);
|
|
9780
|
-
}
|
|
9781
|
-
|
|
9782
|
-
|
|
9783
|
-
let count = 0;
|
|
9784
|
-
finalCompareResult.iterator((value) => {
|
|
9785
|
-
if ((value === null || value === void 0 ? void 0 : value.isBoolean()) && value.getValue() === true) count++;
|
|
9786
|
-
});
|
|
9787
|
-
result = NumberValueObject.create(count);
|
|
9788
|
-
} else if (formulaName === "SUMIFS") result = targetRange.pick(finalCompareResult).sum();
|
|
9789
|
-
else if (formulaName === "AVERAGEIFS") {
|
|
9790
|
-
const picked = targetRange.pick(finalCompareResult);
|
|
9791
|
-
const sum = picked.sum();
|
|
9792
|
-
const count = picked.count();
|
|
9793
|
-
result = sum.divided(count);
|
|
9794
|
-
} else if (formulaName === "MAXIFS") {
|
|
9795
|
-
const picked = targetRange.pick(finalCompareResult);
|
|
9796
|
-
if (picked.getColumnCount() === 0) result = NumberValueObject.create(0);
|
|
9797
|
-
else result = picked.max();
|
|
9798
|
-
} else if (formulaName === "MINIFS") {
|
|
9799
|
-
const picked = targetRange.pick(finalCompareResult);
|
|
9800
|
-
if (picked.getColumnCount() === 0) result = NumberValueObject.create(0);
|
|
9801
|
-
else result = picked.min();
|
|
9802
|
-
}
|
|
9880
|
+
});
|
|
9881
|
+
const aggregateRange = positions === void 0 || !targetRange ? targetRange : pickRangePositions(targetRange, positions);
|
|
9882
|
+
const result = getConditionalAggregateResult(formulaName, finalCompareResult, aggregateRange);
|
|
9803
9883
|
if (!results[rowIndex]) results[rowIndex] = [];
|
|
9804
9884
|
results[rowIndex][columnIndex] = result;
|
|
9885
|
+
if (cacheKey !== void 0 && result) repeatedResults.set(cacheKey, result);
|
|
9805
9886
|
});
|
|
9806
9887
|
return results;
|
|
9807
9888
|
}
|
|
@@ -36215,6 +36296,19 @@ var Sumif = class extends BaseFunction {
|
|
|
36215
36296
|
let _criteria = criteria;
|
|
36216
36297
|
if (criteria.isReferenceObject()) _criteria = criteria.toArrayValueObject();
|
|
36217
36298
|
if (_criteria.isArray()) {
|
|
36299
|
+
const criteriaArray = _criteria;
|
|
36300
|
+
const rangeArray = range.toArrayValueObject();
|
|
36301
|
+
const targetArray = sumRange ? sumRange.toArrayValueObject() : rangeArray;
|
|
36302
|
+
if (criteriaArray.getRowCount() * criteriaArray.getColumnCount() > 1 && rangeArray.getRowCount() === targetArray.getRowCount() && rangeArray.getColumnCount() === targetArray.getColumnCount()) {
|
|
36303
|
+
const values = getPairedRangeAndCriteriaResult([rangeArray, criteriaArray], {
|
|
36304
|
+
formulaName: "SUMIFS",
|
|
36305
|
+
maxRowLength: criteriaArray.getRowCount(),
|
|
36306
|
+
maxColumnLength: criteriaArray.getColumnCount(),
|
|
36307
|
+
isNumberSensitive: true,
|
|
36308
|
+
targetRange: targetArray
|
|
36309
|
+
});
|
|
36310
|
+
return criteriaArray.mapValue((_, row, column) => values[row][column]);
|
|
36311
|
+
}
|
|
36218
36312
|
const resultArray = _criteria.mapValue((criteriaObject) => this._handleSingleObject(range, criteriaObject, sumRange));
|
|
36219
36313
|
if (resultArray.getRowCount() === 1 && resultArray.getColumnCount() === 1) return resultArray.get(0, 0);
|
|
36220
36314
|
return resultArray;
|
|
@@ -37200,6 +37294,19 @@ var Averageif = class extends BaseFunction {
|
|
|
37200
37294
|
let _criteria = criteria;
|
|
37201
37295
|
if (criteria.isReferenceObject()) _criteria = criteria.toArrayValueObject();
|
|
37202
37296
|
if (_criteria.isArray()) {
|
|
37297
|
+
const criteriaArray = _criteria;
|
|
37298
|
+
const rangeArray = range.toArrayValueObject();
|
|
37299
|
+
const targetArray = averageRange ? averageRange.toArrayValueObject() : rangeArray;
|
|
37300
|
+
if (criteriaArray.getRowCount() * criteriaArray.getColumnCount() > 1 && rangeArray.getRowCount() === targetArray.getRowCount() && rangeArray.getColumnCount() === targetArray.getColumnCount()) {
|
|
37301
|
+
const values = getPairedRangeAndCriteriaResult([rangeArray, criteriaArray], {
|
|
37302
|
+
formulaName: "AVERAGEIFS",
|
|
37303
|
+
maxRowLength: criteriaArray.getRowCount(),
|
|
37304
|
+
maxColumnLength: criteriaArray.getColumnCount(),
|
|
37305
|
+
isNumberSensitive: true,
|
|
37306
|
+
targetRange: targetArray
|
|
37307
|
+
});
|
|
37308
|
+
return criteriaArray.mapValue((_, row, column) => values[row][column]);
|
|
37309
|
+
}
|
|
37203
37310
|
const resultArray = _criteria.mapValue((criteriaObject) => this._handleSingleObject(range, criteriaObject, averageRange));
|
|
37204
37311
|
if (resultArray.getRowCount() === 1 && resultArray.getColumnCount() === 1) return resultArray.get(0, 0);
|
|
37205
37312
|
return resultArray;
|
|
@@ -37618,6 +37725,18 @@ var Countif = class extends BaseFunction {
|
|
|
37618
37725
|
}
|
|
37619
37726
|
}
|
|
37620
37727
|
if (_criteria.isArray()) {
|
|
37728
|
+
const criteriaArray = _criteria;
|
|
37729
|
+
const rangeArray = range.toArrayValueObject();
|
|
37730
|
+
if (criteriaArray.getRowCount() * criteriaArray.getColumnCount() > 1) {
|
|
37731
|
+
const normalized = criteria.isReferenceObject() ? criteriaArray.mapValue((value) => value.isNull() ? NumberValueObject.create(0) : value) : criteriaArray;
|
|
37732
|
+
const values = getPairedRangeAndCriteriaResult([rangeArray, normalized], {
|
|
37733
|
+
formulaName: "COUNTIFS",
|
|
37734
|
+
maxRowLength: criteriaArray.getRowCount(),
|
|
37735
|
+
maxColumnLength: criteriaArray.getColumnCount(),
|
|
37736
|
+
isNumberSensitive: true
|
|
37737
|
+
});
|
|
37738
|
+
return criteriaArray.mapValue((_, row, column) => values[row][column]);
|
|
37739
|
+
}
|
|
37621
37740
|
const resultArray = _criteria.mapValue((criteriaObject) => this._handleSingleObject(range, criteria.isReferenceObject() && criteriaObject.isNull() ? NumberValueObject.create(0) : criteriaObject));
|
|
37622
37741
|
if (resultArray.getRowCount() === 1 && resultArray.getColumnCount() === 1) return resultArray.get(0, 0);
|
|
37623
37742
|
return resultArray;
|
|
@@ -43600,7 +43719,7 @@ function getObjectValue(result, isUseStrip = false) {
|
|
|
43600
43719
|
//#endregion
|
|
43601
43720
|
//#region package.json
|
|
43602
43721
|
var name = "@univerjs/engine-formula";
|
|
43603
|
-
var version = "1.0.
|
|
43722
|
+
var version = "1.0.3";
|
|
43604
43723
|
|
|
43605
43724
|
//#endregion
|
|
43606
43725
|
//#region src/services/global-computing-status.service.ts
|