@devmm/puredocs-excel-formula 1.0.1 → 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/dist/index.cjs +554 -63
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +554 -63
- package/dist/index.js.map +1 -1
- package/package.json +45 -45
- package/LICENSE +0 -21
package/dist/index.js
CHANGED
|
@@ -2356,9 +2356,11 @@ function datedif(a, c) {
|
|
|
2356
2356
|
function registerLookup(r) {
|
|
2357
2357
|
r.register("VLOOKUP", vlookup, 3, 4);
|
|
2358
2358
|
r.register("HLOOKUP", hlookup, 3, 4);
|
|
2359
|
+
r.register("XLOOKUP", xlookup, 3, 6);
|
|
2359
2360
|
r.register("LOOKUP", lookup, 2, 3);
|
|
2360
2361
|
r.register("INDEX", index_, 2, 3);
|
|
2361
2362
|
r.register("MATCH", match, 2, 3);
|
|
2363
|
+
r.register("XMATCH", xmatch, 2, 4);
|
|
2362
2364
|
r.register("CHOOSE", choose, 2);
|
|
2363
2365
|
r.register("ADDRESS", address, 2, 5);
|
|
2364
2366
|
r.register("ROW", row, 0, 1);
|
|
@@ -2432,6 +2434,121 @@ function hlookup(a, c) {
|
|
|
2432
2434
|
}
|
|
2433
2435
|
return best >= 0 ? tbl.get(rowIdx, best) : FormulaValue.errorNA;
|
|
2434
2436
|
}
|
|
2437
|
+
function wildcardRegex(pattern) {
|
|
2438
|
+
let out = "";
|
|
2439
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
2440
|
+
const ch = pattern[i];
|
|
2441
|
+
if (ch === "~" && i + 1 < pattern.length) {
|
|
2442
|
+
const next = pattern[++i];
|
|
2443
|
+
out += next.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2444
|
+
} else if (ch === "*") out += ".*";
|
|
2445
|
+
else if (ch === "?") out += ".";
|
|
2446
|
+
else out += ch.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2447
|
+
}
|
|
2448
|
+
return new RegExp(`^${out}$`, "i");
|
|
2449
|
+
}
|
|
2450
|
+
function findMatch(n, get, lookupVal, matchMode, searchMode) {
|
|
2451
|
+
if ((searchMode === 2 || searchMode === -2) && matchMode !== 2) {
|
|
2452
|
+
const at = searchMode === 2 ? get : (j) => get(n - 1 - j);
|
|
2453
|
+
let lo = 0, hi = n - 1, lastLE = -1, firstGE = -1;
|
|
2454
|
+
while (lo <= hi) {
|
|
2455
|
+
const mid2 = lo + hi >>> 1;
|
|
2456
|
+
const cmp = FormulaValue.compare(at(mid2), lookupVal);
|
|
2457
|
+
if (cmp === 0) return searchMode === 2 ? mid2 : n - 1 - mid2;
|
|
2458
|
+
if (cmp < 0) {
|
|
2459
|
+
lastLE = mid2;
|
|
2460
|
+
lo = mid2 + 1;
|
|
2461
|
+
} else {
|
|
2462
|
+
firstGE = mid2;
|
|
2463
|
+
hi = mid2 - 1;
|
|
2464
|
+
}
|
|
2465
|
+
}
|
|
2466
|
+
const idx = matchMode === -1 ? lastLE : matchMode === 1 ? firstGE : -1;
|
|
2467
|
+
return idx < 0 ? -1 : searchMode === 2 ? idx : n - 1 - idx;
|
|
2468
|
+
}
|
|
2469
|
+
const reverse = searchMode === -1;
|
|
2470
|
+
const order = reverse ? Array.from({ length: n }, (_, k) => n - 1 - k) : Array.from({ length: n }, (_, k) => k);
|
|
2471
|
+
if (matchMode === 2) {
|
|
2472
|
+
const re = wildcardRegex(lookupVal.asText());
|
|
2473
|
+
for (const i of order) if (re.test(get(i).asText())) return i;
|
|
2474
|
+
return -1;
|
|
2475
|
+
}
|
|
2476
|
+
if (matchMode === 0) {
|
|
2477
|
+
for (const i of order) if (FormulaValue.areEqual(get(i), lookupVal)) return i;
|
|
2478
|
+
return -1;
|
|
2479
|
+
}
|
|
2480
|
+
let best = -1;
|
|
2481
|
+
let bestVal = null;
|
|
2482
|
+
for (const i of order) {
|
|
2483
|
+
const v = get(i);
|
|
2484
|
+
const cmp = FormulaValue.compare(v, lookupVal);
|
|
2485
|
+
if (cmp === 0) return i;
|
|
2486
|
+
if (matchMode === -1 && cmp < 0) {
|
|
2487
|
+
if (bestVal === null || FormulaValue.compare(v, bestVal) > 0) {
|
|
2488
|
+
best = i;
|
|
2489
|
+
bestVal = v;
|
|
2490
|
+
}
|
|
2491
|
+
} else if (matchMode === 1 && cmp > 0) {
|
|
2492
|
+
if (bestVal === null || FormulaValue.compare(v, bestVal) < 0) {
|
|
2493
|
+
best = i;
|
|
2494
|
+
bestVal = v;
|
|
2495
|
+
}
|
|
2496
|
+
}
|
|
2497
|
+
}
|
|
2498
|
+
return best;
|
|
2499
|
+
}
|
|
2500
|
+
function xlookup(a, c) {
|
|
2501
|
+
const lookupVal = a[0].evaluate(c);
|
|
2502
|
+
if (lookupVal.isError) return lookupVal;
|
|
2503
|
+
const lookupRaw = a[1].evaluate(c);
|
|
2504
|
+
if (lookupRaw.isError) return lookupRaw;
|
|
2505
|
+
const returnRaw = a[2].evaluate(c);
|
|
2506
|
+
if (returnRaw.isError) return returnRaw;
|
|
2507
|
+
const matchMode = a.length > 4 ? num2(a, c, 4) : { ok: true, n: 0 };
|
|
2508
|
+
if (!matchMode.ok) return matchMode.e;
|
|
2509
|
+
const searchMode = a.length > 5 ? num2(a, c, 5) : { ok: true, n: 1 };
|
|
2510
|
+
if (!searchMode.ok) return searchMode.e;
|
|
2511
|
+
const mm = Math.trunc(matchMode.n), sm = Math.trunc(searchMode.n);
|
|
2512
|
+
const la = lookupRaw.isArray ? lookupRaw.arrayVal : ArrayValue.fromScalar(lookupRaw);
|
|
2513
|
+
if (la.rows > 1 && la.columns > 1) return FormulaValue.errorValue;
|
|
2514
|
+
const vertical = !(la.rows === 1 && la.columns > 1);
|
|
2515
|
+
const n = vertical ? la.rows : la.columns;
|
|
2516
|
+
const get = vertical ? (i) => la.get(i, 0) : (i) => la.get(0, i);
|
|
2517
|
+
const idx = findMatch(n, get, lookupVal, mm, sm);
|
|
2518
|
+
if (idx < 0) {
|
|
2519
|
+
return a.length > 3 ? a[3].evaluate(c) : FormulaValue.errorNA;
|
|
2520
|
+
}
|
|
2521
|
+
const ret = returnRaw.isArray ? returnRaw.arrayVal : ArrayValue.fromScalar(returnRaw);
|
|
2522
|
+
if (vertical) {
|
|
2523
|
+
if (ret.rows !== n) return FormulaValue.errorValue;
|
|
2524
|
+
if (ret.columns === 1) return ret.get(idx, 0);
|
|
2525
|
+
const out2 = new ArrayValue(1, ret.columns);
|
|
2526
|
+
for (let col = 0; col < ret.columns; col++) out2.set(0, col, ret.get(idx, col));
|
|
2527
|
+
return FormulaValue.array(out2);
|
|
2528
|
+
}
|
|
2529
|
+
if (ret.columns !== n) return FormulaValue.errorValue;
|
|
2530
|
+
if (ret.rows === 1) return ret.get(0, idx);
|
|
2531
|
+
const out = new ArrayValue(ret.rows, 1);
|
|
2532
|
+
for (let r = 0; r < ret.rows; r++) out.set(r, 0, ret.get(r, idx));
|
|
2533
|
+
return FormulaValue.array(out);
|
|
2534
|
+
}
|
|
2535
|
+
function xmatch(a, c) {
|
|
2536
|
+
const lookupVal = a[0].evaluate(c);
|
|
2537
|
+
if (lookupVal.isError) return lookupVal;
|
|
2538
|
+
const lookupRaw = a[1].evaluate(c);
|
|
2539
|
+
if (lookupRaw.isError) return lookupRaw;
|
|
2540
|
+
const matchMode = a.length > 2 ? num2(a, c, 2) : { ok: true, n: 0 };
|
|
2541
|
+
if (!matchMode.ok) return matchMode.e;
|
|
2542
|
+
const searchMode = a.length > 3 ? num2(a, c, 3) : { ok: true, n: 1 };
|
|
2543
|
+
if (!searchMode.ok) return searchMode.e;
|
|
2544
|
+
const la = lookupRaw.isArray ? lookupRaw.arrayVal : ArrayValue.fromScalar(lookupRaw);
|
|
2545
|
+
if (la.rows > 1 && la.columns > 1) return FormulaValue.errorValue;
|
|
2546
|
+
const vertical = !(la.rows === 1 && la.columns > 1);
|
|
2547
|
+
const n = vertical ? la.rows : la.columns;
|
|
2548
|
+
const get = vertical ? (i) => la.get(i, 0) : (i) => la.get(0, i);
|
|
2549
|
+
const idx = findMatch(n, get, lookupVal, Math.trunc(matchMode.n), Math.trunc(searchMode.n));
|
|
2550
|
+
return idx < 0 ? FormulaValue.errorNA : FormulaValue.number(idx + 1);
|
|
2551
|
+
}
|
|
2435
2552
|
function index_(a, c) {
|
|
2436
2553
|
const arrVal = a[0].evaluate(c);
|
|
2437
2554
|
if (arrVal.isError) return arrVal;
|
|
@@ -2965,6 +3082,24 @@ function registerFinance(r) {
|
|
|
2965
3082
|
r.register("PV", pv, 3, 5);
|
|
2966
3083
|
r.register("NPV", npv, 2);
|
|
2967
3084
|
r.register("IRR", irr, 1, 2);
|
|
3085
|
+
r.register("RATE", rate, 3, 6);
|
|
3086
|
+
r.register("NPER", nper, 3, 5);
|
|
3087
|
+
r.register("XNPV", xnpv, 3, 3);
|
|
3088
|
+
r.register("XIRR", xirr, 2, 3);
|
|
3089
|
+
r.register("IPMT", ipmt, 4, 6);
|
|
3090
|
+
r.register("PPMT", ppmt, 4, 6);
|
|
3091
|
+
}
|
|
3092
|
+
function pmtValue(r, n, pv2, fv2, type) {
|
|
3093
|
+
if (r === 0) return -(pv2 + fv2) / n;
|
|
3094
|
+
const pow = Math.pow(1 + r, n);
|
|
3095
|
+
let payment = (-fv2 - pv2 * pow) * r / (pow - 1);
|
|
3096
|
+
if (type === 1) payment /= 1 + r;
|
|
3097
|
+
return payment;
|
|
3098
|
+
}
|
|
3099
|
+
function fvValue(r, n, pmt2, pv2, type) {
|
|
3100
|
+
if (r === 0) return -(pv2 + pmt2 * n);
|
|
3101
|
+
const pow = Math.pow(1 + r, n);
|
|
3102
|
+
return -(pv2 * pow + pmt2 * (1 + r * type) * (pow - 1) / r);
|
|
2968
3103
|
}
|
|
2969
3104
|
function arg(a, c, idx, dflt) {
|
|
2970
3105
|
if (idx >= a.length) return { ok: true, n: dflt };
|
|
@@ -2972,65 +3107,59 @@ function arg(a, c, idx, dflt) {
|
|
|
2972
3107
|
return r.ok ? { ok: true, n: r.value } : { ok: false, e: r.error };
|
|
2973
3108
|
}
|
|
2974
3109
|
function pmt(a, c) {
|
|
2975
|
-
const
|
|
2976
|
-
if (!
|
|
2977
|
-
const
|
|
2978
|
-
if (!
|
|
3110
|
+
const rate2 = arg(a, c, 0, 0);
|
|
3111
|
+
if (!rate2.ok) return rate2.e;
|
|
3112
|
+
const nper2 = arg(a, c, 1, 0);
|
|
3113
|
+
if (!nper2.ok) return nper2.e;
|
|
2979
3114
|
const pvv = arg(a, c, 2, 0);
|
|
2980
3115
|
if (!pvv.ok) return pvv.e;
|
|
2981
3116
|
const fvv = arg(a, c, 3, 0);
|
|
2982
3117
|
if (!fvv.ok) return fvv.e;
|
|
2983
3118
|
const type = arg(a, c, 4, 0);
|
|
2984
3119
|
if (!type.ok) return type.e;
|
|
2985
|
-
const r =
|
|
3120
|
+
const r = rate2.n, n = nper2.n, present = pvv.n, future = fvv.n, t = type.n;
|
|
2986
3121
|
if (n === 0) return FormulaValue.errorNum;
|
|
2987
|
-
|
|
2988
|
-
const pow = Math.pow(1 + r, n);
|
|
2989
|
-
let payment = (-future - present * pow) * r / (pow - 1);
|
|
2990
|
-
if (t === 1) payment /= 1 + r;
|
|
2991
|
-
return FormulaValue.number(payment);
|
|
3122
|
+
return FormulaValue.number(pmtValue(r, n, present, future, t));
|
|
2992
3123
|
}
|
|
2993
3124
|
function fv(a, c) {
|
|
2994
|
-
const
|
|
2995
|
-
if (!
|
|
2996
|
-
const
|
|
2997
|
-
if (!
|
|
3125
|
+
const rate2 = arg(a, c, 0, 0);
|
|
3126
|
+
if (!rate2.ok) return rate2.e;
|
|
3127
|
+
const nper2 = arg(a, c, 1, 0);
|
|
3128
|
+
if (!nper2.ok) return nper2.e;
|
|
2998
3129
|
const pmtv = arg(a, c, 2, 0);
|
|
2999
3130
|
if (!pmtv.ok) return pmtv.e;
|
|
3000
3131
|
const pvv = arg(a, c, 3, 0);
|
|
3001
3132
|
if (!pvv.ok) return pvv.e;
|
|
3002
3133
|
const type = arg(a, c, 4, 0);
|
|
3003
3134
|
if (!type.ok) return type.e;
|
|
3004
|
-
const r =
|
|
3005
|
-
|
|
3006
|
-
const pow = Math.pow(1 + r, n);
|
|
3007
|
-
return FormulaValue.number(-(present * pow + payment * (1 + r * t) * (pow - 1) / r));
|
|
3135
|
+
const r = rate2.n, n = nper2.n, payment = pmtv.n, present = pvv.n, t = type.n;
|
|
3136
|
+
return FormulaValue.number(fvValue(r, n, payment, present, t));
|
|
3008
3137
|
}
|
|
3009
3138
|
function pv(a, c) {
|
|
3010
|
-
const
|
|
3011
|
-
if (!
|
|
3012
|
-
const
|
|
3013
|
-
if (!
|
|
3139
|
+
const rate2 = arg(a, c, 0, 0);
|
|
3140
|
+
if (!rate2.ok) return rate2.e;
|
|
3141
|
+
const nper2 = arg(a, c, 1, 0);
|
|
3142
|
+
if (!nper2.ok) return nper2.e;
|
|
3014
3143
|
const pmtv = arg(a, c, 2, 0);
|
|
3015
3144
|
if (!pmtv.ok) return pmtv.e;
|
|
3016
3145
|
const fvv = arg(a, c, 3, 0);
|
|
3017
3146
|
if (!fvv.ok) return fvv.e;
|
|
3018
3147
|
const type = arg(a, c, 4, 0);
|
|
3019
3148
|
if (!type.ok) return type.e;
|
|
3020
|
-
const r =
|
|
3149
|
+
const r = rate2.n, n = nper2.n, payment = pmtv.n, future = fvv.n, t = type.n;
|
|
3021
3150
|
if (r === 0) return FormulaValue.number(-(future + payment * n));
|
|
3022
3151
|
const pow = Math.pow(1 + r, n);
|
|
3023
3152
|
return FormulaValue.number(-(future + payment * (1 + r * t) * (pow - 1) / r) / pow);
|
|
3024
3153
|
}
|
|
3025
3154
|
function npv(a, c) {
|
|
3026
|
-
const
|
|
3027
|
-
if (!
|
|
3028
|
-
if (
|
|
3155
|
+
const rate2 = FormulaHelper.evalDouble(a[0], c);
|
|
3156
|
+
if (!rate2.ok) return rate2.error;
|
|
3157
|
+
if (rate2.value === -1) return FormulaValue.errorDiv0;
|
|
3029
3158
|
const flows = FormulaHelper.collectNumbers(a.slice(1), c);
|
|
3030
3159
|
if (!flows.ok) return flows.error;
|
|
3031
3160
|
let total = 0;
|
|
3032
3161
|
for (let i = 0; i < flows.values.length; i++) {
|
|
3033
|
-
total += flows.values[i] / Math.pow(1 +
|
|
3162
|
+
total += flows.values[i] / Math.pow(1 + rate2.value, i + 1);
|
|
3034
3163
|
}
|
|
3035
3164
|
return FormulaValue.number(total);
|
|
3036
3165
|
}
|
|
@@ -3045,27 +3174,220 @@ function irr(a, c) {
|
|
|
3045
3174
|
if (!g.ok) return g.error;
|
|
3046
3175
|
guess = g.value;
|
|
3047
3176
|
}
|
|
3048
|
-
const npvAt = (
|
|
3177
|
+
const npvAt = (rate3) => {
|
|
3049
3178
|
let sum2 = 0;
|
|
3050
|
-
for (let i = 0; i < flows.length; i++) sum2 += flows[i] / Math.pow(1 +
|
|
3179
|
+
for (let i = 0; i < flows.length; i++) sum2 += flows[i] / Math.pow(1 + rate3, i);
|
|
3051
3180
|
return sum2;
|
|
3052
3181
|
};
|
|
3053
|
-
let
|
|
3182
|
+
let rate2 = guess;
|
|
3183
|
+
for (let iter = 0; iter < 100; iter++) {
|
|
3184
|
+
const f = npvAt(rate2);
|
|
3185
|
+
if (Math.abs(f) < 1e-7) return FormulaValue.number(rate2);
|
|
3186
|
+
const h = 1e-6;
|
|
3187
|
+
const deriv = (npvAt(rate2 + h) - f) / h;
|
|
3188
|
+
if (deriv === 0) break;
|
|
3189
|
+
const next = rate2 - f / deriv;
|
|
3190
|
+
if (!isFinite(next) || next <= -1) break;
|
|
3191
|
+
if (Math.abs(next - rate2) < 1e-9) {
|
|
3192
|
+
rate2 = next;
|
|
3193
|
+
break;
|
|
3194
|
+
}
|
|
3195
|
+
rate2 = next;
|
|
3196
|
+
}
|
|
3197
|
+
if (Math.abs(npvAt(rate2)) < 1e-6) return FormulaValue.number(rate2);
|
|
3198
|
+
return FormulaValue.errorNum;
|
|
3199
|
+
}
|
|
3200
|
+
function tvm(r, n, pmt2, pv2, fv2, type) {
|
|
3201
|
+
if (r === 0) return pv2 + pmt2 * n + fv2;
|
|
3202
|
+
const pow = Math.pow(1 + r, n);
|
|
3203
|
+
return pv2 * pow + pmt2 * (1 + r * type) * (pow - 1) / r + fv2;
|
|
3204
|
+
}
|
|
3205
|
+
function rate(a, c) {
|
|
3206
|
+
const nper2 = arg(a, c, 0, 0);
|
|
3207
|
+
if (!nper2.ok) return nper2.e;
|
|
3208
|
+
const pmtv = arg(a, c, 1, 0);
|
|
3209
|
+
if (!pmtv.ok) return pmtv.e;
|
|
3210
|
+
const pvv = arg(a, c, 2, 0);
|
|
3211
|
+
if (!pvv.ok) return pvv.e;
|
|
3212
|
+
const fvv = arg(a, c, 3, 0);
|
|
3213
|
+
if (!fvv.ok) return fvv.e;
|
|
3214
|
+
const type = arg(a, c, 4, 0);
|
|
3215
|
+
if (!type.ok) return type.e;
|
|
3216
|
+
const gs = arg(a, c, 5, 0.1);
|
|
3217
|
+
if (!gs.ok) return gs.e;
|
|
3218
|
+
const n = nper2.n, pmt2 = pmtv.n, pv2 = pvv.n, fv2 = fvv.n, t = type.n;
|
|
3219
|
+
if (n === 0) return FormulaValue.errorNum;
|
|
3220
|
+
let r = gs.n;
|
|
3054
3221
|
for (let iter = 0; iter < 100; iter++) {
|
|
3055
|
-
const f =
|
|
3056
|
-
if (Math.abs(f) < 1e-
|
|
3222
|
+
const f = tvm(r, n, pmt2, pv2, fv2, t);
|
|
3223
|
+
if (Math.abs(f) < 1e-8) return FormulaValue.number(r);
|
|
3057
3224
|
const h = 1e-6;
|
|
3058
|
-
const deriv = (
|
|
3225
|
+
const deriv = (tvm(r + h, n, pmt2, pv2, fv2, t) - f) / h;
|
|
3059
3226
|
if (deriv === 0) break;
|
|
3060
|
-
const next =
|
|
3227
|
+
const next = r - f / deriv;
|
|
3061
3228
|
if (!isFinite(next) || next <= -1) break;
|
|
3062
|
-
if (Math.abs(next -
|
|
3063
|
-
|
|
3229
|
+
if (Math.abs(next - r) < 1e-10) {
|
|
3230
|
+
r = next;
|
|
3064
3231
|
break;
|
|
3065
3232
|
}
|
|
3066
|
-
|
|
3233
|
+
r = next;
|
|
3067
3234
|
}
|
|
3068
|
-
if (Math.abs(
|
|
3235
|
+
if (Math.abs(tvm(r, n, pmt2, pv2, fv2, t)) < 1e-6) return FormulaValue.number(r);
|
|
3236
|
+
return FormulaValue.errorNum;
|
|
3237
|
+
}
|
|
3238
|
+
function nper(a, c) {
|
|
3239
|
+
const rate2 = arg(a, c, 0, 0);
|
|
3240
|
+
if (!rate2.ok) return rate2.e;
|
|
3241
|
+
const pmtv = arg(a, c, 1, 0);
|
|
3242
|
+
if (!pmtv.ok) return pmtv.e;
|
|
3243
|
+
const pvv = arg(a, c, 2, 0);
|
|
3244
|
+
if (!pvv.ok) return pvv.e;
|
|
3245
|
+
const fvv = arg(a, c, 3, 0);
|
|
3246
|
+
if (!fvv.ok) return fvv.e;
|
|
3247
|
+
const type = arg(a, c, 4, 0);
|
|
3248
|
+
if (!type.ok) return type.e;
|
|
3249
|
+
const r = rate2.n, pmt2 = pmtv.n, pv2 = pvv.n, fv2 = fvv.n, t = type.n;
|
|
3250
|
+
if (r === 0) {
|
|
3251
|
+
if (pmt2 === 0) return FormulaValue.errorNum;
|
|
3252
|
+
return FormulaValue.number(-(pv2 + fv2) / pmt2);
|
|
3253
|
+
}
|
|
3254
|
+
const adj = pmt2 * (1 + r * t);
|
|
3255
|
+
const num5 = adj - fv2 * r;
|
|
3256
|
+
const den = adj + pv2 * r;
|
|
3257
|
+
if (den === 0 || num5 / den <= 0) return FormulaValue.errorNum;
|
|
3258
|
+
const result = Math.log(num5 / den) / Math.log(1 + r);
|
|
3259
|
+
if (!isFinite(result)) return FormulaValue.errorNum;
|
|
3260
|
+
return FormulaValue.number(result);
|
|
3261
|
+
}
|
|
3262
|
+
function interestForPeriod(r, per, n, pv2, fv2, t) {
|
|
3263
|
+
const pay = pmtValue(r, n, pv2, fv2, t);
|
|
3264
|
+
if (t === 1) {
|
|
3265
|
+
if (per === 1) return 0;
|
|
3266
|
+
return fvValue(r, per - 2, pay, pv2, 1) * r / (1 + r);
|
|
3267
|
+
}
|
|
3268
|
+
return fvValue(r, per - 1, pay, pv2, 0) * r;
|
|
3269
|
+
}
|
|
3270
|
+
function ipmt(a, c) {
|
|
3271
|
+
const rate2 = arg(a, c, 0, 0);
|
|
3272
|
+
if (!rate2.ok) return rate2.e;
|
|
3273
|
+
const perv = arg(a, c, 1, 0);
|
|
3274
|
+
if (!perv.ok) return perv.e;
|
|
3275
|
+
const nper2 = arg(a, c, 2, 0);
|
|
3276
|
+
if (!nper2.ok) return nper2.e;
|
|
3277
|
+
const pvv = arg(a, c, 3, 0);
|
|
3278
|
+
if (!pvv.ok) return pvv.e;
|
|
3279
|
+
const fvv = arg(a, c, 4, 0);
|
|
3280
|
+
if (!fvv.ok) return fvv.e;
|
|
3281
|
+
const type = arg(a, c, 5, 0);
|
|
3282
|
+
if (!type.ok) return type.e;
|
|
3283
|
+
const r = rate2.n, per = perv.n, n = nper2.n, pv2 = pvv.n, fv2 = fvv.n, t = type.n;
|
|
3284
|
+
if (n === 0 || per < 1 || per > n) return FormulaValue.errorNum;
|
|
3285
|
+
return FormulaValue.number(interestForPeriod(r, per, n, pv2, fv2, t));
|
|
3286
|
+
}
|
|
3287
|
+
function ppmt(a, c) {
|
|
3288
|
+
const rate2 = arg(a, c, 0, 0);
|
|
3289
|
+
if (!rate2.ok) return rate2.e;
|
|
3290
|
+
const perv = arg(a, c, 1, 0);
|
|
3291
|
+
if (!perv.ok) return perv.e;
|
|
3292
|
+
const nper2 = arg(a, c, 2, 0);
|
|
3293
|
+
if (!nper2.ok) return nper2.e;
|
|
3294
|
+
const pvv = arg(a, c, 3, 0);
|
|
3295
|
+
if (!pvv.ok) return pvv.e;
|
|
3296
|
+
const fvv = arg(a, c, 4, 0);
|
|
3297
|
+
if (!fvv.ok) return fvv.e;
|
|
3298
|
+
const type = arg(a, c, 5, 0);
|
|
3299
|
+
if (!type.ok) return type.e;
|
|
3300
|
+
const r = rate2.n, per = perv.n, n = nper2.n, pv2 = pvv.n, fv2 = fvv.n, t = type.n;
|
|
3301
|
+
if (n === 0 || per < 1 || per > n) return FormulaValue.errorNum;
|
|
3302
|
+
const pay = pmtValue(r, n, pv2, fv2, t);
|
|
3303
|
+
return FormulaValue.number(pay - interestForPeriod(r, per, n, pv2, fv2, t));
|
|
3304
|
+
}
|
|
3305
|
+
function flatNumbers(node, c) {
|
|
3306
|
+
const v = node.evaluate(c);
|
|
3307
|
+
if (v.isError) return { ok: false, e: v };
|
|
3308
|
+
const out = [];
|
|
3309
|
+
const push = (item) => {
|
|
3310
|
+
if (item.isError) return item;
|
|
3311
|
+
const d = item.tryAsDouble();
|
|
3312
|
+
if (!d.ok) return FormulaValue.errorValue;
|
|
3313
|
+
out.push(d.value);
|
|
3314
|
+
return null;
|
|
3315
|
+
};
|
|
3316
|
+
if (v.isArray) {
|
|
3317
|
+
for (const item of v.arrayVal.values()) {
|
|
3318
|
+
const err = push(item);
|
|
3319
|
+
if (err) return { ok: false, e: err };
|
|
3320
|
+
}
|
|
3321
|
+
} else {
|
|
3322
|
+
const err = push(v);
|
|
3323
|
+
if (err) return { ok: false, e: err };
|
|
3324
|
+
}
|
|
3325
|
+
return { ok: true, values: out };
|
|
3326
|
+
}
|
|
3327
|
+
function xnpvAt(rate2, values, days2) {
|
|
3328
|
+
let sum2 = 0;
|
|
3329
|
+
for (let i = 0; i < values.length; i++) {
|
|
3330
|
+
sum2 += values[i] / Math.pow(1 + rate2, days2[i] / 365);
|
|
3331
|
+
}
|
|
3332
|
+
return sum2;
|
|
3333
|
+
}
|
|
3334
|
+
function xnpv(a, c) {
|
|
3335
|
+
const rateRes = FormulaHelper.evalDouble(a[0], c);
|
|
3336
|
+
if (!rateRes.ok) return rateRes.error;
|
|
3337
|
+
const rate2 = rateRes.value;
|
|
3338
|
+
if (rate2 <= -1) return FormulaValue.errorNum;
|
|
3339
|
+
const valsRes = flatNumbers(a[1], c);
|
|
3340
|
+
if (!valsRes.ok) return valsRes.e;
|
|
3341
|
+
const datesRes = flatNumbers(a[2], c);
|
|
3342
|
+
if (!datesRes.ok) return datesRes.e;
|
|
3343
|
+
const values = valsRes.values;
|
|
3344
|
+
const dates = datesRes.values;
|
|
3345
|
+
if (values.length === 0 || values.length !== dates.length) return FormulaValue.errorNum;
|
|
3346
|
+
const base = Math.trunc(dates[0]);
|
|
3347
|
+
const days2 = dates.map((d) => Math.trunc(d) - base);
|
|
3348
|
+
if (days2.some((d) => d < 0)) return FormulaValue.errorNum;
|
|
3349
|
+
return FormulaValue.number(xnpvAt(rate2, values, days2));
|
|
3350
|
+
}
|
|
3351
|
+
function xirr(a, c) {
|
|
3352
|
+
const valsRes = flatNumbers(a[0], c);
|
|
3353
|
+
if (!valsRes.ok) return valsRes.e;
|
|
3354
|
+
const datesRes = flatNumbers(a[1], c);
|
|
3355
|
+
if (!datesRes.ok) return datesRes.e;
|
|
3356
|
+
const values = valsRes.values;
|
|
3357
|
+
const dates = datesRes.values;
|
|
3358
|
+
if (values.length < 2 || values.length !== dates.length) return FormulaValue.errorNum;
|
|
3359
|
+
let guess = 0.1;
|
|
3360
|
+
if (a.length > 2) {
|
|
3361
|
+
const g = FormulaHelper.evalDouble(a[2], c);
|
|
3362
|
+
if (!g.ok) return g.error;
|
|
3363
|
+
guess = g.value;
|
|
3364
|
+
}
|
|
3365
|
+
const base = Math.trunc(dates[0]);
|
|
3366
|
+
const days2 = dates.map((d) => Math.trunc(d) - base);
|
|
3367
|
+
if (days2.some((d) => d < 0)) return FormulaValue.errorNum;
|
|
3368
|
+
const derivAt = (rate3) => {
|
|
3369
|
+
let sum2 = 0;
|
|
3370
|
+
for (let i = 0; i < values.length; i++) {
|
|
3371
|
+
const e = days2[i] / 365;
|
|
3372
|
+
sum2 += -e * values[i] / Math.pow(1 + rate3, e + 1);
|
|
3373
|
+
}
|
|
3374
|
+
return sum2;
|
|
3375
|
+
};
|
|
3376
|
+
let rate2 = guess;
|
|
3377
|
+
for (let iter = 0; iter < 100; iter++) {
|
|
3378
|
+
const f = xnpvAt(rate2, values, days2);
|
|
3379
|
+
if (Math.abs(f) < 1e-7) return FormulaValue.number(rate2);
|
|
3380
|
+
const deriv = derivAt(rate2);
|
|
3381
|
+
if (deriv === 0) break;
|
|
3382
|
+
const next = rate2 - f / deriv;
|
|
3383
|
+
if (!isFinite(next) || next <= -1) break;
|
|
3384
|
+
if (Math.abs(next - rate2) < 1e-9) {
|
|
3385
|
+
rate2 = next;
|
|
3386
|
+
break;
|
|
3387
|
+
}
|
|
3388
|
+
rate2 = next;
|
|
3389
|
+
}
|
|
3390
|
+
if (Math.abs(xnpvAt(rate2, values, days2)) < 1e-6) return FormulaValue.number(rate2);
|
|
3069
3391
|
return FormulaValue.errorNum;
|
|
3070
3392
|
}
|
|
3071
3393
|
|
|
@@ -3403,10 +3725,17 @@ function registerArray(r) {
|
|
|
3403
3725
|
r.register("SEQUENCE", sequence, 1, 4);
|
|
3404
3726
|
r.register("UNIQUE", unique, 1, 3);
|
|
3405
3727
|
r.register("SORT", sort, 1, 4);
|
|
3728
|
+
r.register("SORTBY", sortBy, 2);
|
|
3406
3729
|
r.register("FILTER", filter, 2, 3);
|
|
3407
3730
|
r.register("MMULT", mmult, 2, 2);
|
|
3408
3731
|
r.register("TEXTSPLIT", textSplit, 2, 6);
|
|
3732
|
+
r.register("VSTACK", vstack, 1);
|
|
3733
|
+
r.register("HSTACK", hstack, 1);
|
|
3734
|
+
r.register("TOCOL", toCol, 1, 3);
|
|
3735
|
+
r.register("TOROW", toRow, 1, 3);
|
|
3409
3736
|
}
|
|
3737
|
+
var MAX_ROWS = 1048576;
|
|
3738
|
+
var MAX_COLS = 16384;
|
|
3410
3739
|
var asArray2 = (v) => v.isArray ? v.arrayVal : ArrayValue.fromScalar(v);
|
|
3411
3740
|
function fromRows(rows2) {
|
|
3412
3741
|
const nr = rows2.length;
|
|
@@ -3453,26 +3782,53 @@ function sequence(a, c) {
|
|
|
3453
3782
|
}
|
|
3454
3783
|
return FormulaValue.array(arr);
|
|
3455
3784
|
}
|
|
3456
|
-
function
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3785
|
+
function cellKey(v) {
|
|
3786
|
+
switch (v.kind) {
|
|
3787
|
+
case "number":
|
|
3788
|
+
return "n" + (v.numberValue === 0 ? "0" : String(v.numberValue));
|
|
3789
|
+
case "text":
|
|
3790
|
+
return "t" + v.textValue.toUpperCase();
|
|
3791
|
+
// case-insensitive
|
|
3792
|
+
case "boolean":
|
|
3793
|
+
return v.booleanValue ? "b1" : "b0";
|
|
3794
|
+
case "blank":
|
|
3795
|
+
return "B";
|
|
3796
|
+
case "error":
|
|
3797
|
+
return "e" + v.errorCode;
|
|
3798
|
+
default:
|
|
3799
|
+
return "x";
|
|
3800
|
+
}
|
|
3460
3801
|
}
|
|
3461
3802
|
function unique(a, c) {
|
|
3462
3803
|
const v = a[0].evaluate(c);
|
|
3463
3804
|
if (v.isError) return v;
|
|
3464
3805
|
const byCol2 = a.length > 1 ? a[1].evaluate(c).coerceToBool().booleanValue : false;
|
|
3465
3806
|
const exactlyOnce = a.length > 2 ? a[2].evaluate(c).coerceToBool().booleanValue : false;
|
|
3466
|
-
|
|
3467
|
-
const
|
|
3468
|
-
const
|
|
3807
|
+
const base = byCol2 ? asArray2(v).transpose() : asArray2(v);
|
|
3808
|
+
const map = /* @__PURE__ */ new Map();
|
|
3809
|
+
const order = [];
|
|
3810
|
+
for (let r = 0; r < base.rows; r++) {
|
|
3811
|
+
const cells = new Array(base.columns);
|
|
3812
|
+
let key = "";
|
|
3813
|
+
for (let col = 0; col < base.columns; col++) {
|
|
3814
|
+
const cell = base.get(r, col);
|
|
3815
|
+
cells[col] = cell;
|
|
3816
|
+
const k = cellKey(cell);
|
|
3817
|
+
key += k.length + ":" + k;
|
|
3818
|
+
}
|
|
3819
|
+
const hit = map.get(key);
|
|
3820
|
+
if (hit) hit.count++;
|
|
3821
|
+
else {
|
|
3822
|
+
map.set(key, { cells, count: 1 });
|
|
3823
|
+
order.push(key);
|
|
3824
|
+
}
|
|
3825
|
+
}
|
|
3469
3826
|
const result = [];
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
});
|
|
3827
|
+
for (const key of order) {
|
|
3828
|
+
const e = map.get(key);
|
|
3829
|
+
if (exactlyOnce && e.count > 1) continue;
|
|
3830
|
+
result.push(e.cells);
|
|
3831
|
+
}
|
|
3476
3832
|
if (result.length === 0) return FormulaValue.error(8 /* Calc */);
|
|
3477
3833
|
const out = fromRows(result);
|
|
3478
3834
|
return byCol2 ? FormulaValue.array(out.arrayVal.transpose()) : out;
|
|
@@ -3497,6 +3853,58 @@ function sort(a, c) {
|
|
|
3497
3853
|
const out = fromRows(sorted);
|
|
3498
3854
|
return byCol2 ? FormulaValue.array(out.arrayVal.transpose()) : out;
|
|
3499
3855
|
}
|
|
3856
|
+
function sortBy(a, c) {
|
|
3857
|
+
const v = a[0].evaluate(c);
|
|
3858
|
+
if (v.isError) return v;
|
|
3859
|
+
const data = asArray2(v);
|
|
3860
|
+
const keys = [];
|
|
3861
|
+
let i = 1;
|
|
3862
|
+
while (i < a.length) {
|
|
3863
|
+
const byVal = a[i].evaluate(c);
|
|
3864
|
+
if (byVal.isError) return byVal;
|
|
3865
|
+
i++;
|
|
3866
|
+
let dir = 1;
|
|
3867
|
+
if (i < a.length) {
|
|
3868
|
+
const maybeOrder = a[i].evaluate(c);
|
|
3869
|
+
if (maybeOrder.isError) return maybeOrder;
|
|
3870
|
+
if (!maybeOrder.isArray && maybeOrder.isNumeric) {
|
|
3871
|
+
const d = maybeOrder.tryAsDouble();
|
|
3872
|
+
if (d.ok) {
|
|
3873
|
+
dir = d.value < 0 ? -1 : 1;
|
|
3874
|
+
i++;
|
|
3875
|
+
}
|
|
3876
|
+
}
|
|
3877
|
+
}
|
|
3878
|
+
keys.push({ vals: [...asArray2(byVal).values()], dir });
|
|
3879
|
+
}
|
|
3880
|
+
if (keys.length === 0) return FormulaValue.errorValue;
|
|
3881
|
+
const n = keys[0].vals.length;
|
|
3882
|
+
if (keys.some((k) => k.vals.length !== n)) return FormulaValue.errorValue;
|
|
3883
|
+
const byRow2 = n === data.rows;
|
|
3884
|
+
const byColumn = !byRow2 && n === data.columns;
|
|
3885
|
+
if (!byRow2 && !byColumn) return FormulaValue.errorValue;
|
|
3886
|
+
const perm = Array.from({ length: n }, (_, k) => k);
|
|
3887
|
+
perm.sort((x, y) => {
|
|
3888
|
+
for (const key of keys) {
|
|
3889
|
+
const cmp = FormulaValue.compare(key.vals[x], key.vals[y]) * key.dir;
|
|
3890
|
+
if (cmp !== 0) return cmp;
|
|
3891
|
+
}
|
|
3892
|
+
return x - y;
|
|
3893
|
+
});
|
|
3894
|
+
const out = new ArrayValue(data.rows, data.columns);
|
|
3895
|
+
if (byRow2) {
|
|
3896
|
+
for (let r = 0; r < data.rows; r++) {
|
|
3897
|
+
const src = perm[r];
|
|
3898
|
+
for (let col = 0; col < data.columns; col++) out.set(r, col, data.get(src, col));
|
|
3899
|
+
}
|
|
3900
|
+
} else {
|
|
3901
|
+
for (let col = 0; col < data.columns; col++) {
|
|
3902
|
+
const src = perm[col];
|
|
3903
|
+
for (let r = 0; r < data.rows; r++) out.set(r, col, data.get(r, src));
|
|
3904
|
+
}
|
|
3905
|
+
}
|
|
3906
|
+
return FormulaValue.array(out);
|
|
3907
|
+
}
|
|
3500
3908
|
function filter(a, c) {
|
|
3501
3909
|
const v = a[0].evaluate(c);
|
|
3502
3910
|
if (v.isError) return v;
|
|
@@ -3578,6 +3986,89 @@ function textSplit(a, c) {
|
|
|
3578
3986
|
});
|
|
3579
3987
|
return fromRows(rows2);
|
|
3580
3988
|
}
|
|
3989
|
+
function vstack(a, c) {
|
|
3990
|
+
const parts = [];
|
|
3991
|
+
let totalRows = 0, maxCols = 0;
|
|
3992
|
+
for (const node of a) {
|
|
3993
|
+
const arr = asArray2(node.evaluate(c));
|
|
3994
|
+
parts.push(arr);
|
|
3995
|
+
totalRows += arr.rows;
|
|
3996
|
+
if (arr.columns > maxCols) maxCols = arr.columns;
|
|
3997
|
+
}
|
|
3998
|
+
if (totalRows > MAX_ROWS || maxCols > MAX_COLS) return FormulaValue.errorNum;
|
|
3999
|
+
const out = new ArrayValue(totalRows, maxCols);
|
|
4000
|
+
let rowOff = 0;
|
|
4001
|
+
for (const arr of parts) {
|
|
4002
|
+
for (let r = 0; r < arr.rows; r++) {
|
|
4003
|
+
for (let col = 0; col < maxCols; col++) {
|
|
4004
|
+
out.set(rowOff + r, col, col < arr.columns ? arr.get(r, col) : FormulaValue.errorNA);
|
|
4005
|
+
}
|
|
4006
|
+
}
|
|
4007
|
+
rowOff += arr.rows;
|
|
4008
|
+
}
|
|
4009
|
+
return FormulaValue.array(out);
|
|
4010
|
+
}
|
|
4011
|
+
function hstack(a, c) {
|
|
4012
|
+
const parts = [];
|
|
4013
|
+
let totalCols = 0, maxRows = 0;
|
|
4014
|
+
for (const node of a) {
|
|
4015
|
+
const arr = asArray2(node.evaluate(c));
|
|
4016
|
+
parts.push(arr);
|
|
4017
|
+
totalCols += arr.columns;
|
|
4018
|
+
if (arr.rows > maxRows) maxRows = arr.rows;
|
|
4019
|
+
}
|
|
4020
|
+
if (maxRows > MAX_ROWS || totalCols > MAX_COLS) return FormulaValue.errorNum;
|
|
4021
|
+
const out = new ArrayValue(maxRows, totalCols);
|
|
4022
|
+
let colOff = 0;
|
|
4023
|
+
for (const arr of parts) {
|
|
4024
|
+
for (let col = 0; col < arr.columns; col++) {
|
|
4025
|
+
for (let r = 0; r < maxRows; r++) {
|
|
4026
|
+
out.set(r, colOff + col, r < arr.rows ? arr.get(r, col) : FormulaValue.errorNA);
|
|
4027
|
+
}
|
|
4028
|
+
}
|
|
4029
|
+
colOff += arr.columns;
|
|
4030
|
+
}
|
|
4031
|
+
return FormulaValue.array(out);
|
|
4032
|
+
}
|
|
4033
|
+
function flatten(a, c) {
|
|
4034
|
+
const arr = asArray2(a[0].evaluate(c));
|
|
4035
|
+
const ig = num4(a, c, 1, 0);
|
|
4036
|
+
if (!ig.ok) return { ok: false, e: ig.e };
|
|
4037
|
+
const ignore = Math.trunc(ig.n);
|
|
4038
|
+
const byCol2 = a.length > 2 ? a[2].evaluate(c).coerceToBool().booleanValue : false;
|
|
4039
|
+
const skip = (x) => (ignore & 1) !== 0 && x.isBlank || (ignore & 2) !== 0 && x.isError;
|
|
4040
|
+
const values = [];
|
|
4041
|
+
if (byCol2) {
|
|
4042
|
+
for (let col = 0; col < arr.columns; col++)
|
|
4043
|
+
for (let r = 0; r < arr.rows; r++) {
|
|
4044
|
+
const x = arr.get(r, col);
|
|
4045
|
+
if (!skip(x)) values.push(x);
|
|
4046
|
+
}
|
|
4047
|
+
} else {
|
|
4048
|
+
for (let r = 0; r < arr.rows; r++)
|
|
4049
|
+
for (let col = 0; col < arr.columns; col++) {
|
|
4050
|
+
const x = arr.get(r, col);
|
|
4051
|
+
if (!skip(x)) values.push(x);
|
|
4052
|
+
}
|
|
4053
|
+
}
|
|
4054
|
+
return { ok: true, values };
|
|
4055
|
+
}
|
|
4056
|
+
function toCol(a, c) {
|
|
4057
|
+
const f = flatten(a, c);
|
|
4058
|
+
if (!f.ok) return f.e;
|
|
4059
|
+
if (f.values.length === 0) return FormulaValue.errorNA;
|
|
4060
|
+
const out = new ArrayValue(f.values.length, 1);
|
|
4061
|
+
for (let i = 0; i < f.values.length; i++) out.set(i, 0, f.values[i]);
|
|
4062
|
+
return FormulaValue.array(out);
|
|
4063
|
+
}
|
|
4064
|
+
function toRow(a, c) {
|
|
4065
|
+
const f = flatten(a, c);
|
|
4066
|
+
if (!f.ok) return f.e;
|
|
4067
|
+
if (f.values.length === 0) return FormulaValue.errorNA;
|
|
4068
|
+
const out = new ArrayValue(1, f.values.length);
|
|
4069
|
+
for (let i = 0; i < f.values.length; i++) out.set(0, i, f.values[i]);
|
|
4070
|
+
return FormulaValue.array(out);
|
|
4071
|
+
}
|
|
3581
4072
|
|
|
3582
4073
|
// src/function-registry.ts
|
|
3583
4074
|
var _default, _functions, _FunctionRegistry_instances, registerBuiltIns_fn;
|
|
@@ -4380,8 +4871,8 @@ writeResult_fn = function(e) {
|
|
|
4380
4871
|
for (let dc = 0; dc < cols && !collides; dc++) {
|
|
4381
4872
|
if (dr === 0 && dc === 0) continue;
|
|
4382
4873
|
const r = e.row + dr, c = e.col + dc;
|
|
4383
|
-
const
|
|
4384
|
-
if (__privateMethod(this, _RecalcEngine_instances, isOccupied_fn).call(this,
|
|
4874
|
+
const cellKey2 = keyOf(e.sheet, cellRefFromRowCol(r, c));
|
|
4875
|
+
if (__privateMethod(this, _RecalcEngine_instances, isOccupied_fn).call(this, cellKey2, e.sheetName, cellRefFromRowCol(r, c), anchorKey, prevSpill)) {
|
|
4385
4876
|
collides = true;
|
|
4386
4877
|
}
|
|
4387
4878
|
}
|
|
@@ -4402,9 +4893,9 @@ writeResult_fn = function(e) {
|
|
|
4402
4893
|
__privateGet(this, _model).setCellValue(e.sheetName, ref, arr.get(dr, dc).toObject());
|
|
4403
4894
|
changed.push({ sheet: e.sheet, row: r, col: c });
|
|
4404
4895
|
if (dr !== 0 || dc !== 0) {
|
|
4405
|
-
const
|
|
4406
|
-
newSpill.add(
|
|
4407
|
-
__privateGet(this, _spillOwner).set(
|
|
4896
|
+
const cellKey2 = keyOf(e.sheet, ref);
|
|
4897
|
+
newSpill.add(cellKey2);
|
|
4898
|
+
__privateGet(this, _spillOwner).set(cellKey2, anchorKey);
|
|
4408
4899
|
}
|
|
4409
4900
|
}
|
|
4410
4901
|
}
|
|
@@ -4424,11 +4915,11 @@ writeResult_fn = function(e) {
|
|
|
4424
4915
|
};
|
|
4425
4916
|
};
|
|
4426
4917
|
/** Whether a target cell already holds content that blocks a spill. */
|
|
4427
|
-
isOccupied_fn = function(
|
|
4428
|
-
if (__privateGet(this, _formulas).has(
|
|
4429
|
-
const owner = __privateGet(this, _spillOwner).get(
|
|
4918
|
+
isOccupied_fn = function(cellKey2, sheetName, ref, anchorKey, prevSpill) {
|
|
4919
|
+
if (__privateGet(this, _formulas).has(cellKey2) && cellKey2 !== anchorKey) return true;
|
|
4920
|
+
const owner = __privateGet(this, _spillOwner).get(cellKey2);
|
|
4430
4921
|
if (owner && owner !== anchorKey) return true;
|
|
4431
|
-
if (prevSpill.has(
|
|
4922
|
+
if (prevSpill.has(cellKey2)) return false;
|
|
4432
4923
|
const v = __privateGet(this, _model).getCellValue(sheetName, ref);
|
|
4433
4924
|
return v !== null && v !== void 0 && v !== "";
|
|
4434
4925
|
};
|
|
@@ -4436,10 +4927,10 @@ isOccupied_fn = function(cellKey, sheetName, ref, anchorKey, prevSpill) {
|
|
|
4436
4927
|
clearSpill_fn = function(anchorKey, changed) {
|
|
4437
4928
|
const spill = __privateGet(this, _spills).get(anchorKey);
|
|
4438
4929
|
if (!spill) return;
|
|
4439
|
-
for (const
|
|
4440
|
-
const cell = parseKey(
|
|
4930
|
+
for (const cellKey2 of spill) {
|
|
4931
|
+
const cell = parseKey(cellKey2);
|
|
4441
4932
|
__privateGet(this, _model).setCellValue(__privateGet(this, _sheetNames).get(cell.sheet) ?? cell.sheet, cell.ref, null);
|
|
4442
|
-
__privateGet(this, _spillOwner).delete(
|
|
4933
|
+
__privateGet(this, _spillOwner).delete(cellKey2);
|
|
4443
4934
|
changed.push({ sheet: cell.sheet, row: cell.row, col: cell.col });
|
|
4444
4935
|
}
|
|
4445
4936
|
__privateGet(this, _spills).delete(anchorKey);
|