@cj-tech-master/excelts 9.2.1 → 9.3.0
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/README.md +25 -2
- package/README_zh.md +29 -6
- package/dist/browser/index.browser.d.ts +1 -1
- package/dist/browser/index.browser.js +4 -0
- package/dist/browser/index.d.ts +1 -1
- package/dist/browser/index.js +4 -0
- package/dist/browser/modules/excel/cell.d.ts +17 -3
- package/dist/browser/modules/excel/cell.js +170 -22
- package/dist/browser/modules/excel/defined-names.d.ts +96 -1
- package/dist/browser/modules/excel/defined-names.js +411 -21
- package/dist/browser/modules/excel/image.d.ts +11 -0
- package/dist/browser/modules/excel/image.js +24 -1
- package/dist/browser/modules/excel/stream/workbook-reader.browser.d.ts +9 -3
- package/dist/browser/modules/excel/stream/workbook-reader.browser.js +14 -0
- package/dist/browser/modules/excel/stream/workbook-reader.d.ts +2 -1
- package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +39 -5
- package/dist/browser/modules/excel/stream/workbook-writer.browser.js +48 -1
- package/dist/browser/modules/excel/stream/workbook-writer.d.ts +3 -2
- package/dist/browser/modules/excel/stream/worksheet-reader.js +17 -1
- package/dist/browser/modules/excel/stream/worksheet-writer.d.ts +39 -6
- package/dist/browser/modules/excel/stream/worksheet-writer.js +45 -5
- package/dist/browser/modules/excel/table.js +15 -2
- package/dist/browser/modules/excel/types.d.ts +133 -2
- package/dist/browser/modules/excel/utils/col-cache.d.ts +1 -0
- package/dist/browser/modules/excel/utils/col-cache.js +15 -0
- package/dist/browser/modules/excel/utils/drawing-utils.d.ts +3 -3
- package/dist/browser/modules/excel/utils/drawing-utils.js +4 -0
- package/dist/browser/modules/excel/utils/external-link-formula.d.ts +76 -0
- package/dist/browser/modules/excel/utils/external-link-formula.js +208 -0
- package/dist/browser/modules/excel/utils/iterate-stream.d.ts +9 -3
- package/dist/browser/modules/excel/utils/iterate-stream.js +3 -1
- package/dist/browser/modules/excel/utils/ooxml-paths.d.ts +19 -0
- package/dist/browser/modules/excel/utils/ooxml-paths.js +37 -2
- package/dist/browser/modules/excel/utils/shared-strings.d.ts +8 -3
- package/dist/browser/modules/excel/utils/shared-strings.js +21 -2
- package/dist/browser/modules/excel/utils/workbook-protection.d.ts +30 -0
- package/dist/browser/modules/excel/utils/workbook-protection.js +30 -0
- package/dist/browser/modules/excel/workbook.browser.d.ts +257 -6
- package/dist/browser/modules/excel/workbook.browser.js +318 -34
- package/dist/browser/modules/excel/workbook.d.ts +1 -1
- package/dist/browser/modules/excel/worksheet.d.ts +3 -1
- package/dist/browser/modules/excel/worksheet.js +21 -2
- package/dist/browser/modules/excel/xlsx/rel-type.d.ts +15 -0
- package/dist/browser/modules/excel/xlsx/rel-type.js +16 -1
- package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.d.ts +6 -5
- package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
- package/dist/browser/modules/excel/xlsx/xform/book/external-link-xform.d.ts +84 -0
- package/dist/browser/modules/excel/xlsx/xform/book/external-link-xform.js +330 -0
- package/dist/browser/modules/excel/xlsx/xform/book/external-reference-xform.d.ts +17 -0
- package/dist/browser/modules/excel/xlsx/xform/book/external-reference-xform.js +24 -0
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.d.ts +3 -0
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-protection-xform.d.ts +20 -0
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-protection-xform.js +66 -0
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
- package/dist/browser/modules/excel/xlsx/xform/core/content-types-xform.js +19 -1
- package/dist/browser/modules/excel/xlsx/xform/core/metadata-xform.d.ts +56 -0
- package/dist/browser/modules/excel/xlsx/xform/core/metadata-xform.js +158 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.d.ts +26 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +105 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
- package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.d.ts +1 -1
- package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
- package/dist/browser/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
- package/dist/browser/modules/excel/xlsx/xform/sheet/ignored-errors-xform.d.ts +21 -0
- package/dist/browser/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +80 -0
- package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
- package/dist/browser/modules/excel/xlsx/xform/style/border-xform.js +4 -1
- package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +172 -13
- package/dist/browser/modules/excel/xlsx/xlsx.browser.js +410 -20
- package/dist/browser/modules/excel/xlsx/xlsx.d.ts +7 -4
- package/dist/browser/modules/excel/xlsx/xlsx.js +4 -5
- package/dist/browser/modules/formula/compile/address-utils.d.ts +62 -0
- package/dist/browser/modules/formula/compile/address-utils.js +83 -0
- package/dist/browser/modules/formula/compile/binder.d.ts +42 -0
- package/dist/browser/modules/formula/compile/binder.js +487 -0
- package/dist/browser/modules/formula/compile/bound-ast.d.ts +230 -0
- package/dist/browser/modules/formula/compile/bound-ast.js +80 -0
- package/dist/browser/modules/formula/compile/compiled-formula.d.ts +137 -0
- package/dist/browser/modules/formula/compile/compiled-formula.js +383 -0
- package/dist/browser/modules/formula/compile/dependency-analysis.d.ts +93 -0
- package/dist/browser/modules/formula/compile/dependency-analysis.js +432 -0
- package/dist/browser/modules/formula/compile/structured-ref-utils.d.ts +93 -0
- package/dist/browser/modules/formula/compile/structured-ref-utils.js +136 -0
- package/dist/browser/modules/formula/default-syntax-probe.d.ts +79 -0
- package/dist/browser/modules/formula/default-syntax-probe.js +83 -0
- package/dist/browser/modules/formula/functions/_date-context.d.ts +4 -0
- package/dist/browser/modules/formula/functions/_date-context.js +29 -0
- package/dist/browser/modules/formula/functions/_shared.d.ts +121 -0
- package/dist/browser/modules/formula/functions/_shared.js +381 -0
- package/dist/browser/modules/formula/functions/conditional.d.ts +27 -0
- package/dist/browser/modules/formula/functions/conditional.js +343 -0
- package/dist/browser/modules/formula/functions/database.d.ts +37 -0
- package/dist/browser/modules/formula/functions/database.js +274 -0
- package/dist/browser/modules/formula/functions/date.d.ts +61 -0
- package/dist/browser/modules/formula/functions/date.js +855 -0
- package/dist/browser/modules/formula/functions/dynamic-array.d.ts +23 -0
- package/dist/browser/modules/formula/functions/dynamic-array.js +860 -0
- package/dist/browser/modules/formula/functions/engineering.d.ts +57 -0
- package/dist/browser/modules/formula/functions/engineering.js +1128 -0
- package/dist/browser/modules/formula/functions/financial.d.ts +202 -0
- package/dist/browser/modules/formula/functions/financial.js +2296 -0
- package/dist/browser/modules/formula/functions/lookup.d.ts +18 -0
- package/dist/browser/modules/formula/functions/lookup.js +886 -0
- package/dist/browser/modules/formula/functions/math.d.ts +114 -0
- package/dist/browser/modules/formula/functions/math.js +1406 -0
- package/dist/browser/modules/formula/functions/statistical.d.ts +193 -0
- package/dist/browser/modules/formula/functions/statistical.js +3390 -0
- package/dist/browser/modules/formula/functions/text.d.ts +86 -0
- package/dist/browser/modules/formula/functions/text.js +1845 -0
- package/dist/browser/modules/formula/host-registry.d.ts +53 -0
- package/dist/browser/modules/formula/host-registry.js +69 -0
- package/dist/browser/modules/formula/index.d.ts +39 -0
- package/dist/browser/modules/formula/index.js +49 -0
- package/dist/browser/modules/formula/install.d.ts +62 -0
- package/dist/browser/modules/formula/install.js +88 -0
- package/dist/browser/modules/formula/integration/apply-writeback-plan.d.ts +26 -0
- package/dist/browser/modules/formula/integration/apply-writeback-plan.js +210 -0
- package/dist/browser/modules/formula/integration/calculate-formulas-impl.d.ts +30 -0
- package/dist/browser/modules/formula/integration/calculate-formulas-impl.js +616 -0
- package/dist/browser/modules/formula/integration/calculate-formulas.d.ts +67 -0
- package/dist/browser/modules/formula/integration/calculate-formulas.js +68 -0
- package/dist/browser/modules/formula/integration/formula-instance.d.ts +64 -0
- package/dist/browser/modules/formula/integration/formula-instance.js +79 -0
- package/dist/browser/modules/formula/integration/workbook-adapter.d.ts +26 -0
- package/dist/browser/modules/formula/integration/workbook-adapter.js +324 -0
- package/dist/browser/modules/formula/integration/workbook-snapshot.d.ts +267 -0
- package/dist/browser/modules/formula/integration/workbook-snapshot.js +77 -0
- package/dist/browser/modules/formula/materialize/build-writeback-plan.d.ts +34 -0
- package/dist/browser/modules/formula/materialize/build-writeback-plan.js +473 -0
- package/dist/browser/modules/formula/materialize/spill-engine.d.ts +9 -0
- package/dist/browser/modules/formula/materialize/spill-engine.js +38 -0
- package/dist/browser/modules/formula/materialize/types.d.ts +179 -0
- package/dist/browser/modules/formula/materialize/types.js +29 -0
- package/dist/browser/modules/formula/materialize/writeback-plan.d.ts +167 -0
- package/dist/browser/modules/formula/materialize/writeback-plan.js +27 -0
- package/dist/browser/modules/formula/runtime/evaluator.d.ts +151 -0
- package/dist/browser/modules/formula/runtime/evaluator.js +2291 -0
- package/dist/browser/modules/formula/runtime/function-registry.d.ts +47 -0
- package/dist/browser/modules/formula/runtime/function-registry.js +840 -0
- package/dist/browser/modules/formula/runtime/values.d.ts +211 -0
- package/dist/browser/modules/formula/runtime/values.js +385 -0
- package/dist/browser/modules/formula/syntax/ast.d.ts +129 -0
- package/dist/browser/modules/formula/syntax/ast.js +28 -0
- package/dist/browser/modules/formula/syntax/parser.d.ts +18 -0
- package/dist/browser/modules/formula/syntax/parser.js +439 -0
- package/dist/browser/modules/formula/syntax/token-types.d.ts +153 -0
- package/dist/browser/modules/formula/syntax/token-types.js +59 -0
- package/dist/browser/modules/formula/syntax/tokenizer.d.ts +10 -0
- package/dist/browser/modules/formula/syntax/tokenizer.js +1074 -0
- package/dist/browser/modules/pdf/excel-bridge.js +9 -0
- package/dist/cjs/index.js +4 -0
- package/dist/cjs/modules/excel/cell.js +170 -22
- package/dist/cjs/modules/excel/defined-names.js +411 -21
- package/dist/cjs/modules/excel/image.js +24 -1
- package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +14 -0
- package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +48 -1
- package/dist/cjs/modules/excel/stream/worksheet-reader.js +17 -1
- package/dist/cjs/modules/excel/stream/worksheet-writer.js +45 -5
- package/dist/cjs/modules/excel/table.js +15 -2
- package/dist/cjs/modules/excel/utils/col-cache.js +15 -0
- package/dist/cjs/modules/excel/utils/drawing-utils.js +4 -0
- package/dist/cjs/modules/excel/utils/external-link-formula.js +212 -0
- package/dist/cjs/modules/excel/utils/iterate-stream.js +3 -1
- package/dist/cjs/modules/excel/utils/ooxml-paths.js +42 -2
- package/dist/cjs/modules/excel/utils/shared-strings.js +21 -2
- package/dist/cjs/modules/excel/utils/workbook-protection.js +33 -0
- package/dist/cjs/modules/excel/workbook.browser.js +318 -34
- package/dist/cjs/modules/excel/worksheet.js +20 -1
- package/dist/cjs/modules/excel/xlsx/rel-type.js +16 -1
- package/dist/cjs/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
- package/dist/cjs/modules/excel/xlsx/xform/book/external-link-xform.js +333 -0
- package/dist/cjs/modules/excel/xlsx/xform/book/external-reference-xform.js +27 -0
- package/dist/cjs/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
- package/dist/cjs/modules/excel/xlsx/xform/book/workbook-protection-xform.js +69 -0
- package/dist/cjs/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
- package/dist/cjs/modules/excel/xlsx/xform/core/content-types-xform.js +18 -0
- package/dist/cjs/modules/excel/xlsx/xform/core/metadata-xform.js +161 -0
- package/dist/cjs/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +108 -0
- package/dist/cjs/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
- package/dist/cjs/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
- package/dist/cjs/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
- package/dist/cjs/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
- package/dist/cjs/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +83 -0
- package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
- package/dist/cjs/modules/excel/xlsx/xform/style/border-xform.js +4 -1
- package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +408 -18
- package/dist/cjs/modules/excel/xlsx/xlsx.js +4 -5
- package/dist/cjs/modules/formula/compile/address-utils.js +89 -0
- package/dist/cjs/modules/formula/compile/binder.js +489 -0
- package/dist/cjs/modules/formula/compile/bound-ast.js +68 -0
- package/dist/cjs/modules/formula/compile/compiled-formula.js +387 -0
- package/dist/cjs/modules/formula/compile/dependency-analysis.js +437 -0
- package/dist/cjs/modules/formula/compile/structured-ref-utils.js +141 -0
- package/dist/cjs/modules/formula/default-syntax-probe.js +87 -0
- package/dist/cjs/modules/formula/functions/_date-context.js +33 -0
- package/dist/cjs/modules/formula/functions/_shared.js +396 -0
- package/dist/cjs/modules/formula/functions/conditional.js +354 -0
- package/dist/cjs/modules/formula/functions/database.js +288 -0
- package/dist/cjs/modules/formula/functions/date.js +883 -0
- package/dist/cjs/modules/formula/functions/dynamic-array.js +881 -0
- package/dist/cjs/modules/formula/functions/engineering.js +1183 -0
- package/dist/cjs/modules/formula/functions/financial.js +2348 -0
- package/dist/cjs/modules/formula/functions/lookup.js +902 -0
- package/dist/cjs/modules/formula/functions/math.js +1487 -0
- package/dist/cjs/modules/formula/functions/statistical.js +3488 -0
- package/dist/cjs/modules/formula/functions/text.js +1889 -0
- package/dist/cjs/modules/formula/host-registry.js +75 -0
- package/dist/cjs/modules/formula/index.js +58 -0
- package/dist/cjs/modules/formula/install.js +93 -0
- package/dist/cjs/modules/formula/integration/apply-writeback-plan.js +213 -0
- package/dist/cjs/modules/formula/integration/calculate-formulas-impl.js +619 -0
- package/dist/cjs/modules/formula/integration/calculate-formulas.js +71 -0
- package/dist/cjs/modules/formula/integration/formula-instance.js +82 -0
- package/dist/cjs/modules/formula/integration/workbook-adapter.js +327 -0
- package/dist/cjs/modules/formula/integration/workbook-snapshot.js +84 -0
- package/dist/cjs/modules/formula/materialize/build-writeback-plan.js +475 -0
- package/dist/cjs/modules/formula/materialize/spill-engine.js +42 -0
- package/dist/cjs/modules/formula/materialize/types.js +32 -0
- package/dist/cjs/modules/formula/materialize/writeback-plan.js +28 -0
- package/dist/cjs/modules/formula/runtime/evaluator.js +2298 -0
- package/dist/cjs/modules/formula/runtime/function-registry.js +846 -0
- package/dist/cjs/modules/formula/runtime/values.js +385 -0
- package/dist/cjs/modules/formula/syntax/ast.js +8 -0
- package/dist/cjs/modules/formula/syntax/parser.js +440 -0
- package/dist/cjs/modules/formula/syntax/token-types.js +32 -0
- package/dist/cjs/modules/formula/syntax/tokenizer.js +1076 -0
- package/dist/cjs/modules/pdf/excel-bridge.js +9 -0
- package/dist/esm/index.browser.js +4 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/modules/excel/cell.js +170 -22
- package/dist/esm/modules/excel/defined-names.js +411 -21
- package/dist/esm/modules/excel/image.js +24 -1
- package/dist/esm/modules/excel/stream/workbook-reader.browser.js +14 -0
- package/dist/esm/modules/excel/stream/workbook-writer.browser.js +48 -1
- package/dist/esm/modules/excel/stream/worksheet-reader.js +17 -1
- package/dist/esm/modules/excel/stream/worksheet-writer.js +45 -5
- package/dist/esm/modules/excel/table.js +15 -2
- package/dist/esm/modules/excel/utils/col-cache.js +15 -0
- package/dist/esm/modules/excel/utils/drawing-utils.js +4 -0
- package/dist/esm/modules/excel/utils/external-link-formula.js +208 -0
- package/dist/esm/modules/excel/utils/iterate-stream.js +3 -1
- package/dist/esm/modules/excel/utils/ooxml-paths.js +37 -2
- package/dist/esm/modules/excel/utils/shared-strings.js +21 -2
- package/dist/esm/modules/excel/utils/workbook-protection.js +30 -0
- package/dist/esm/modules/excel/workbook.browser.js +318 -34
- package/dist/esm/modules/excel/worksheet.js +21 -2
- package/dist/esm/modules/excel/xlsx/rel-type.js +16 -1
- package/dist/esm/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
- package/dist/esm/modules/excel/xlsx/xform/book/external-link-xform.js +330 -0
- package/dist/esm/modules/excel/xlsx/xform/book/external-reference-xform.js +24 -0
- package/dist/esm/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
- package/dist/esm/modules/excel/xlsx/xform/book/workbook-protection-xform.js +66 -0
- package/dist/esm/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
- package/dist/esm/modules/excel/xlsx/xform/core/content-types-xform.js +19 -1
- package/dist/esm/modules/excel/xlsx/xform/core/metadata-xform.js +158 -0
- package/dist/esm/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +105 -0
- package/dist/esm/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
- package/dist/esm/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
- package/dist/esm/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
- package/dist/esm/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
- package/dist/esm/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +80 -0
- package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
- package/dist/esm/modules/excel/xlsx/xform/style/border-xform.js +4 -1
- package/dist/esm/modules/excel/xlsx/xlsx.browser.js +410 -20
- package/dist/esm/modules/excel/xlsx/xlsx.js +4 -5
- package/dist/esm/modules/formula/compile/address-utils.js +83 -0
- package/dist/esm/modules/formula/compile/binder.js +487 -0
- package/dist/esm/modules/formula/compile/bound-ast.js +80 -0
- package/dist/esm/modules/formula/compile/compiled-formula.js +383 -0
- package/dist/esm/modules/formula/compile/dependency-analysis.js +432 -0
- package/dist/esm/modules/formula/compile/structured-ref-utils.js +136 -0
- package/dist/esm/modules/formula/default-syntax-probe.js +83 -0
- package/dist/esm/modules/formula/functions/_date-context.js +29 -0
- package/dist/esm/modules/formula/functions/_shared.js +381 -0
- package/dist/esm/modules/formula/functions/conditional.js +343 -0
- package/dist/esm/modules/formula/functions/database.js +274 -0
- package/dist/esm/modules/formula/functions/date.js +855 -0
- package/dist/esm/modules/formula/functions/dynamic-array.js +860 -0
- package/dist/esm/modules/formula/functions/engineering.js +1128 -0
- package/dist/esm/modules/formula/functions/financial.js +2296 -0
- package/dist/esm/modules/formula/functions/lookup.js +886 -0
- package/dist/esm/modules/formula/functions/math.js +1406 -0
- package/dist/esm/modules/formula/functions/statistical.js +3390 -0
- package/dist/esm/modules/formula/functions/text.js +1845 -0
- package/dist/esm/modules/formula/host-registry.js +69 -0
- package/dist/esm/modules/formula/index.js +49 -0
- package/dist/esm/modules/formula/install.js +88 -0
- package/dist/esm/modules/formula/integration/apply-writeback-plan.js +210 -0
- package/dist/esm/modules/formula/integration/calculate-formulas-impl.js +616 -0
- package/dist/esm/modules/formula/integration/calculate-formulas.js +68 -0
- package/dist/esm/modules/formula/integration/formula-instance.js +79 -0
- package/dist/esm/modules/formula/integration/workbook-adapter.js +324 -0
- package/dist/esm/modules/formula/integration/workbook-snapshot.js +77 -0
- package/dist/esm/modules/formula/materialize/build-writeback-plan.js +473 -0
- package/dist/esm/modules/formula/materialize/spill-engine.js +38 -0
- package/dist/esm/modules/formula/materialize/types.js +29 -0
- package/dist/esm/modules/formula/materialize/writeback-plan.js +27 -0
- package/dist/esm/modules/formula/runtime/evaluator.js +2291 -0
- package/dist/esm/modules/formula/runtime/function-registry.js +840 -0
- package/dist/esm/modules/formula/runtime/values.js +385 -0
- package/dist/esm/modules/formula/syntax/ast.js +28 -0
- package/dist/esm/modules/formula/syntax/parser.js +439 -0
- package/dist/esm/modules/formula/syntax/token-types.js +59 -0
- package/dist/esm/modules/formula/syntax/tokenizer.js +1074 -0
- package/dist/esm/modules/pdf/excel-bridge.js +9 -0
- package/dist/iife/excelts.iife.js +2302 -373
- package/dist/iife/excelts.iife.js.map +1 -1
- package/dist/iife/excelts.iife.min.js +34 -34
- package/dist/types/index.browser.d.ts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/modules/excel/cell.d.ts +17 -3
- package/dist/types/modules/excel/defined-names.d.ts +96 -1
- package/dist/types/modules/excel/image.d.ts +11 -0
- package/dist/types/modules/excel/stream/workbook-reader.browser.d.ts +9 -3
- package/dist/types/modules/excel/stream/workbook-reader.d.ts +2 -1
- package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +39 -5
- package/dist/types/modules/excel/stream/workbook-writer.d.ts +3 -2
- package/dist/types/modules/excel/stream/worksheet-writer.d.ts +39 -6
- package/dist/types/modules/excel/types.d.ts +133 -2
- package/dist/types/modules/excel/utils/col-cache.d.ts +1 -0
- package/dist/types/modules/excel/utils/drawing-utils.d.ts +3 -3
- package/dist/types/modules/excel/utils/external-link-formula.d.ts +76 -0
- package/dist/types/modules/excel/utils/iterate-stream.d.ts +9 -3
- package/dist/types/modules/excel/utils/ooxml-paths.d.ts +19 -0
- package/dist/types/modules/excel/utils/shared-strings.d.ts +8 -3
- package/dist/types/modules/excel/utils/workbook-protection.d.ts +30 -0
- package/dist/types/modules/excel/workbook.browser.d.ts +257 -6
- package/dist/types/modules/excel/workbook.d.ts +1 -1
- package/dist/types/modules/excel/worksheet.d.ts +3 -1
- package/dist/types/modules/excel/xlsx/rel-type.d.ts +15 -0
- package/dist/types/modules/excel/xlsx/xform/book/defined-name-xform.d.ts +6 -5
- package/dist/types/modules/excel/xlsx/xform/book/external-link-xform.d.ts +84 -0
- package/dist/types/modules/excel/xlsx/xform/book/external-reference-xform.d.ts +17 -0
- package/dist/types/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.d.ts +3 -0
- package/dist/types/modules/excel/xlsx/xform/book/workbook-protection-xform.d.ts +20 -0
- package/dist/types/modules/excel/xlsx/xform/core/metadata-xform.d.ts +56 -0
- package/dist/types/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.d.ts +26 -0
- package/dist/types/modules/excel/xlsx/xform/sheet/cell-xform.d.ts +1 -1
- package/dist/types/modules/excel/xlsx/xform/sheet/ignored-errors-xform.d.ts +21 -0
- package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +172 -13
- package/dist/types/modules/excel/xlsx/xlsx.d.ts +7 -4
- package/dist/types/modules/formula/compile/address-utils.d.ts +62 -0
- package/dist/types/modules/formula/compile/binder.d.ts +42 -0
- package/dist/types/modules/formula/compile/bound-ast.d.ts +230 -0
- package/dist/types/modules/formula/compile/compiled-formula.d.ts +137 -0
- package/dist/types/modules/formula/compile/dependency-analysis.d.ts +93 -0
- package/dist/types/modules/formula/compile/structured-ref-utils.d.ts +93 -0
- package/dist/types/modules/formula/default-syntax-probe.d.ts +79 -0
- package/dist/types/modules/formula/functions/_date-context.d.ts +4 -0
- package/dist/types/modules/formula/functions/_shared.d.ts +121 -0
- package/dist/types/modules/formula/functions/conditional.d.ts +27 -0
- package/dist/types/modules/formula/functions/database.d.ts +37 -0
- package/dist/types/modules/formula/functions/date.d.ts +61 -0
- package/dist/types/modules/formula/functions/dynamic-array.d.ts +23 -0
- package/dist/types/modules/formula/functions/engineering.d.ts +57 -0
- package/dist/types/modules/formula/functions/financial.d.ts +202 -0
- package/dist/types/modules/formula/functions/lookup.d.ts +18 -0
- package/dist/types/modules/formula/functions/math.d.ts +114 -0
- package/dist/types/modules/formula/functions/statistical.d.ts +193 -0
- package/dist/types/modules/formula/functions/text.d.ts +86 -0
- package/dist/types/modules/formula/host-registry.d.ts +53 -0
- package/dist/types/modules/formula/index.d.ts +39 -0
- package/dist/types/modules/formula/install.d.ts +62 -0
- package/dist/types/modules/formula/integration/apply-writeback-plan.d.ts +26 -0
- package/dist/types/modules/formula/integration/calculate-formulas-impl.d.ts +30 -0
- package/dist/types/modules/formula/integration/calculate-formulas.d.ts +67 -0
- package/dist/types/modules/formula/integration/formula-instance.d.ts +64 -0
- package/dist/types/modules/formula/integration/workbook-adapter.d.ts +26 -0
- package/dist/types/modules/formula/integration/workbook-snapshot.d.ts +267 -0
- package/dist/types/modules/formula/materialize/build-writeback-plan.d.ts +34 -0
- package/dist/types/modules/formula/materialize/spill-engine.d.ts +9 -0
- package/dist/types/modules/formula/materialize/types.d.ts +179 -0
- package/dist/types/modules/formula/materialize/writeback-plan.d.ts +167 -0
- package/dist/types/modules/formula/runtime/evaluator.d.ts +151 -0
- package/dist/types/modules/formula/runtime/function-registry.d.ts +47 -0
- package/dist/types/modules/formula/runtime/values.d.ts +211 -0
- package/dist/types/modules/formula/syntax/ast.d.ts +129 -0
- package/dist/types/modules/formula/syntax/parser.d.ts +18 -0
- package/dist/types/modules/formula/syntax/token-types.d.ts +153 -0
- package/dist/types/modules/formula/syntax/tokenizer.d.ts +10 -0
- package/package.json +28 -28
|
@@ -0,0 +1,902 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Lookup / Reference Functions — Native RuntimeValue Implementation
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.fnROW = fnROW;
|
|
7
|
+
exports.fnCOLUMN = fnCOLUMN;
|
|
8
|
+
exports.fnROWS = fnROWS;
|
|
9
|
+
exports.fnCOLUMNS = fnCOLUMNS;
|
|
10
|
+
exports.fnINDEX = fnINDEX;
|
|
11
|
+
exports.fnMATCH = fnMATCH;
|
|
12
|
+
exports.fnVLOOKUP = fnVLOOKUP;
|
|
13
|
+
exports.fnHLOOKUP = fnHLOOKUP;
|
|
14
|
+
exports.fnXLOOKUP = fnXLOOKUP;
|
|
15
|
+
exports.fnXMATCH = fnXMATCH;
|
|
16
|
+
exports.fnADDRESS = fnADDRESS;
|
|
17
|
+
exports.fnLOOKUP = fnLOOKUP;
|
|
18
|
+
exports.fnTRANSPOSE = fnTRANSPOSE;
|
|
19
|
+
exports.fnAREAS = fnAREAS;
|
|
20
|
+
const values_1 = require("../runtime/values");
|
|
21
|
+
const _shared_1 = require("./_shared");
|
|
22
|
+
// ============================================================================
|
|
23
|
+
// Helpers
|
|
24
|
+
// ============================================================================
|
|
25
|
+
/** Compare two scalar values for same-type ordering. */
|
|
26
|
+
function sameType(a, b) {
|
|
27
|
+
return a.kind === b.kind;
|
|
28
|
+
}
|
|
29
|
+
function scalarIsNumber(v) {
|
|
30
|
+
return v.kind === 1 /* RVKind.Number */;
|
|
31
|
+
}
|
|
32
|
+
function scalarIsString(v) {
|
|
33
|
+
return v.kind === 2 /* RVKind.String */;
|
|
34
|
+
}
|
|
35
|
+
function scalarStringEquals(a, b) {
|
|
36
|
+
return scalarIsString(a) && scalarIsString(b) && a.value.toLowerCase() === b.value.toLowerCase();
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Ordered comparison of two scalars. Numbers compared by value; strings by
|
|
40
|
+
* case-insensitive lexical order. Returns NaN when the two operands have
|
|
41
|
+
* incompatible types (e.g. number vs string) so callers can skip them.
|
|
42
|
+
*/
|
|
43
|
+
/**
|
|
44
|
+
* @deprecated Use `compareScalarsSameKind` from `runtime/values` directly —
|
|
45
|
+
* the two are identical. Retained only as a local alias to keep the diff
|
|
46
|
+
* small; callers inside this file are free to migrate.
|
|
47
|
+
*/
|
|
48
|
+
const compareScalar = values_1.compareScalarsSameKind;
|
|
49
|
+
// ============================================================================
|
|
50
|
+
// Functions
|
|
51
|
+
// ============================================================================
|
|
52
|
+
function fnROW(args) {
|
|
53
|
+
// The reference-aware path is handled in evaluator.ts via tryEvaluateRefFunction.
|
|
54
|
+
// This fallback is only reached when the argument is not a reference (e.g.
|
|
55
|
+
// ROW(INDIRECT("A5")) or ROW({1,2,3})), which Excel rejects as #VALUE!.
|
|
56
|
+
return values_1.ERRORS.VALUE;
|
|
57
|
+
}
|
|
58
|
+
function fnCOLUMN(args) {
|
|
59
|
+
// See fnROW. Non-reference argument → #VALUE!.
|
|
60
|
+
return values_1.ERRORS.VALUE;
|
|
61
|
+
}
|
|
62
|
+
function fnROWS(args) {
|
|
63
|
+
const a = args[0];
|
|
64
|
+
if (a.kind === 5 /* RVKind.Array */) {
|
|
65
|
+
return (0, values_1.rvNumber)(a.height);
|
|
66
|
+
}
|
|
67
|
+
return (0, values_1.rvNumber)(1);
|
|
68
|
+
}
|
|
69
|
+
function fnCOLUMNS(args) {
|
|
70
|
+
const a = args[0];
|
|
71
|
+
if (a.kind === 5 /* RVKind.Array */) {
|
|
72
|
+
return (0, values_1.rvNumber)(a.width);
|
|
73
|
+
}
|
|
74
|
+
return (0, values_1.rvNumber)(1);
|
|
75
|
+
}
|
|
76
|
+
function fnINDEX(args) {
|
|
77
|
+
if (!(0, values_1.isArray)(args[0])) {
|
|
78
|
+
return (0, values_1.topLeft)(args[0]);
|
|
79
|
+
}
|
|
80
|
+
const arr = args[0];
|
|
81
|
+
const rowNumV = args.length > 1 ? (0, values_1.toNumberRV)(args[1]) : (0, values_1.rvNumber)(0);
|
|
82
|
+
if ((0, values_1.isError)(rowNumV)) {
|
|
83
|
+
return rowNumV;
|
|
84
|
+
}
|
|
85
|
+
// Excel truncates fractional indices toward zero before bounds checks.
|
|
86
|
+
// Without this, `INDEX(a, 1.5, 1)` would index into `arr.rows[0.5]`, which
|
|
87
|
+
// in V8 silently returns `undefined` and corrupts downstream values.
|
|
88
|
+
const rowNum = Math.trunc(rowNumV.value);
|
|
89
|
+
const colNumV = args.length > 2 ? (0, values_1.toNumberRV)(args[2]) : (0, values_1.rvNumber)(0);
|
|
90
|
+
if ((0, values_1.isError)(colNumV)) {
|
|
91
|
+
return colNumV;
|
|
92
|
+
}
|
|
93
|
+
const colNum = Math.trunc(colNumV.value);
|
|
94
|
+
if (rowNum < 0 || colNum < 0) {
|
|
95
|
+
return values_1.ERRORS.VALUE;
|
|
96
|
+
}
|
|
97
|
+
if (rowNum === 0 && colNum === 0) {
|
|
98
|
+
return arr;
|
|
99
|
+
}
|
|
100
|
+
// rowNum=0: return entire column as array
|
|
101
|
+
if (rowNum === 0) {
|
|
102
|
+
const c = colNum - 1;
|
|
103
|
+
if (c < 0 || c >= arr.width) {
|
|
104
|
+
return values_1.ERRORS.REF;
|
|
105
|
+
}
|
|
106
|
+
const rows = [];
|
|
107
|
+
for (let r = 0; r < arr.height; r++) {
|
|
108
|
+
rows.push([(0, _shared_1.getCell)(arr, r, c)]);
|
|
109
|
+
}
|
|
110
|
+
return (0, values_1.rvArray)(rows);
|
|
111
|
+
}
|
|
112
|
+
// colNum=0: return entire row as array
|
|
113
|
+
if (colNum === 0) {
|
|
114
|
+
const r = rowNum - 1;
|
|
115
|
+
if (r < 0 || r >= arr.height) {
|
|
116
|
+
return values_1.ERRORS.REF;
|
|
117
|
+
}
|
|
118
|
+
return (0, values_1.rvArray)([[...arr.rows[r]]]);
|
|
119
|
+
}
|
|
120
|
+
// Single cell
|
|
121
|
+
const r = rowNum - 1;
|
|
122
|
+
const c = colNum - 1;
|
|
123
|
+
if (r < 0 || r >= arr.height || c < 0 || c >= arr.width) {
|
|
124
|
+
return values_1.ERRORS.REF;
|
|
125
|
+
}
|
|
126
|
+
return arr.rows[r][c];
|
|
127
|
+
}
|
|
128
|
+
function fnMATCH(args) {
|
|
129
|
+
const lookupValue = (0, values_1.topLeft)(args[0]);
|
|
130
|
+
if (lookupValue.kind === 4 /* RVKind.Error */) {
|
|
131
|
+
return lookupValue;
|
|
132
|
+
}
|
|
133
|
+
if (!(0, values_1.isArray)(args[1])) {
|
|
134
|
+
return values_1.ERRORS.NA;
|
|
135
|
+
}
|
|
136
|
+
const lookupArr = args[1];
|
|
137
|
+
const matchTypeV = args.length > 2 ? (0, values_1.toNumberRV)(args[2]) : (0, values_1.rvNumber)(1);
|
|
138
|
+
if ((0, values_1.isError)(matchTypeV)) {
|
|
139
|
+
return matchTypeV;
|
|
140
|
+
}
|
|
141
|
+
const matchType = matchTypeV.value;
|
|
142
|
+
// Flatten to 1D
|
|
143
|
+
const flat = [];
|
|
144
|
+
for (let r = 0; r < lookupArr.height; r++) {
|
|
145
|
+
for (let c = 0; c < lookupArr.width; c++) {
|
|
146
|
+
flat.push((0, _shared_1.getCell)(lookupArr, r, c));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (matchType === 0) {
|
|
150
|
+
// Exact match (with wildcard support for string lookups). The shared
|
|
151
|
+
// `excelWildcardToRegex` converter applies the same `~*`, `~?`, `~~`
|
|
152
|
+
// escape rules used by SEARCH, XLOOKUP, and SUMIF so behaviour is
|
|
153
|
+
// consistent across the engine.
|
|
154
|
+
const lookupStr = scalarIsString(lookupValue) ? lookupValue.value : null;
|
|
155
|
+
const hasWildcard = lookupStr !== null && (0, _shared_1.hasUnescapedWildcard)(lookupStr);
|
|
156
|
+
let wildcardRe = null;
|
|
157
|
+
if (hasWildcard && lookupStr !== null) {
|
|
158
|
+
try {
|
|
159
|
+
wildcardRe = new RegExp("^" + (0, _shared_1.excelWildcardToRegex)(lookupStr) + "$", "i");
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
wildcardRe = null;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
for (let i = 0; i < flat.length; i++) {
|
|
166
|
+
if ((0, values_1.scalarEquals)(flat[i], lookupValue)) {
|
|
167
|
+
return (0, values_1.rvNumber)(i + 1);
|
|
168
|
+
}
|
|
169
|
+
const fi = flat[i];
|
|
170
|
+
if (scalarIsString(fi) && scalarIsString(lookupValue)) {
|
|
171
|
+
if (wildcardRe) {
|
|
172
|
+
if (wildcardRe.test(fi.value)) {
|
|
173
|
+
return (0, values_1.rvNumber)(i + 1);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
// No unescaped wildcard — but the pattern may still contain
|
|
178
|
+
// `~*` / `~?` / `~~` escape sequences that should reduce to
|
|
179
|
+
// their literal character before comparison. Calling
|
|
180
|
+
// `unescapeExcelWildcard` here matches the treatment that
|
|
181
|
+
// SEARCH and the criteria predicate use; without it,
|
|
182
|
+
// `MATCH("a~*b", ...)` would literally look for `"a~*b"`
|
|
183
|
+
// instead of `"a*b"`.
|
|
184
|
+
const literal = (0, _shared_1.unescapeExcelWildcard)(lookupValue.value).toLowerCase();
|
|
185
|
+
if (fi.value.toLowerCase() === literal) {
|
|
186
|
+
return (0, values_1.rvNumber)(i + 1);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return values_1.ERRORS.NA;
|
|
192
|
+
}
|
|
193
|
+
if (matchType === 1 || matchType > 0) {
|
|
194
|
+
// Sorted ascending. Find largest value <= lookupValue.
|
|
195
|
+
let bestIdx = -1;
|
|
196
|
+
for (let i = 0; i < flat.length; i++) {
|
|
197
|
+
const v = flat[i];
|
|
198
|
+
if (sameType(v, lookupValue)) {
|
|
199
|
+
if (scalarIsNumber(v) && scalarIsNumber(lookupValue)) {
|
|
200
|
+
if (v.value <= lookupValue.value) {
|
|
201
|
+
bestIdx = i;
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
else if (scalarIsString(v) && scalarIsString(lookupValue)) {
|
|
208
|
+
if (v.value.toLowerCase() <= lookupValue.value.toLowerCase()) {
|
|
209
|
+
bestIdx = i;
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return bestIdx >= 0 ? (0, values_1.rvNumber)(bestIdx + 1) : values_1.ERRORS.NA;
|
|
218
|
+
}
|
|
219
|
+
// matchType === -1: Sorted descending. Find smallest value >= lookupValue.
|
|
220
|
+
let bestIdx = -1;
|
|
221
|
+
for (let i = 0; i < flat.length; i++) {
|
|
222
|
+
const v = flat[i];
|
|
223
|
+
if (sameType(v, lookupValue)) {
|
|
224
|
+
if (scalarIsNumber(v) && scalarIsNumber(lookupValue)) {
|
|
225
|
+
if (v.value >= lookupValue.value) {
|
|
226
|
+
bestIdx = i;
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
else if (scalarIsString(v) && scalarIsString(lookupValue)) {
|
|
233
|
+
if (v.value.toLowerCase() >= lookupValue.value.toLowerCase()) {
|
|
234
|
+
bestIdx = i;
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return bestIdx >= 0 ? (0, values_1.rvNumber)(bestIdx + 1) : values_1.ERRORS.NA;
|
|
243
|
+
}
|
|
244
|
+
function fnVLOOKUP(args) {
|
|
245
|
+
const lookupValue = (0, values_1.topLeft)(args[0]);
|
|
246
|
+
if (lookupValue.kind === 4 /* RVKind.Error */) {
|
|
247
|
+
return lookupValue;
|
|
248
|
+
}
|
|
249
|
+
if (!(0, values_1.isArray)(args[1])) {
|
|
250
|
+
return values_1.ERRORS.NA;
|
|
251
|
+
}
|
|
252
|
+
const table = args[1];
|
|
253
|
+
const colIndexV = (0, values_1.toNumberRV)(args[2]);
|
|
254
|
+
if ((0, values_1.isError)(colIndexV)) {
|
|
255
|
+
return colIndexV;
|
|
256
|
+
}
|
|
257
|
+
// VLOOKUP truncates the column index toward zero before bounds checks.
|
|
258
|
+
const colIndex = Math.trunc(colIndexV.value);
|
|
259
|
+
const rangeLookupV = args.length > 3 ? (0, values_1.toBooleanRV)(args[3]) : { kind: 3 /* RVKind.Boolean */, value: true };
|
|
260
|
+
if ((0, values_1.isError)(rangeLookupV)) {
|
|
261
|
+
return rangeLookupV;
|
|
262
|
+
}
|
|
263
|
+
const rangeLookup = rangeLookupV.value;
|
|
264
|
+
if (colIndex < 1 || colIndex > table.width) {
|
|
265
|
+
return values_1.ERRORS.REF;
|
|
266
|
+
}
|
|
267
|
+
if (!rangeLookup) {
|
|
268
|
+
// Exact match
|
|
269
|
+
for (let r = 0; r < table.height; r++) {
|
|
270
|
+
const cell = (0, _shared_1.getCell)(table, r, 0);
|
|
271
|
+
if ((0, values_1.scalarEquals)(cell, lookupValue)) {
|
|
272
|
+
return (0, _shared_1.getCell)(table, r, colIndex - 1);
|
|
273
|
+
}
|
|
274
|
+
if (scalarStringEquals(cell, lookupValue)) {
|
|
275
|
+
return (0, _shared_1.getCell)(table, r, colIndex - 1);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return values_1.ERRORS.NA;
|
|
279
|
+
}
|
|
280
|
+
// Approximate match: sorted ascending by first column.
|
|
281
|
+
let bestRow = -1;
|
|
282
|
+
for (let r = 0; r < table.height; r++) {
|
|
283
|
+
const v = (0, _shared_1.getCell)(table, r, 0);
|
|
284
|
+
if (sameType(v, lookupValue)) {
|
|
285
|
+
if (scalarIsNumber(v) && scalarIsNumber(lookupValue)) {
|
|
286
|
+
if (v.value <= lookupValue.value) {
|
|
287
|
+
bestRow = r;
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
break;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
else if (scalarIsString(v) && scalarIsString(lookupValue)) {
|
|
294
|
+
if (v.value.toLowerCase() <= lookupValue.value.toLowerCase()) {
|
|
295
|
+
bestRow = r;
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return bestRow >= 0 ? (0, _shared_1.getCell)(table, bestRow, colIndex - 1) : values_1.ERRORS.NA;
|
|
304
|
+
}
|
|
305
|
+
function fnHLOOKUP(args) {
|
|
306
|
+
const lookupValue = (0, values_1.topLeft)(args[0]);
|
|
307
|
+
if (lookupValue.kind === 4 /* RVKind.Error */) {
|
|
308
|
+
return lookupValue;
|
|
309
|
+
}
|
|
310
|
+
if (!(0, values_1.isArray)(args[1])) {
|
|
311
|
+
return values_1.ERRORS.NA;
|
|
312
|
+
}
|
|
313
|
+
const table = args[1];
|
|
314
|
+
const rowIndexV = (0, values_1.toNumberRV)(args[2]);
|
|
315
|
+
if ((0, values_1.isError)(rowIndexV)) {
|
|
316
|
+
return rowIndexV;
|
|
317
|
+
}
|
|
318
|
+
// HLOOKUP truncates the row index toward zero before bounds checks.
|
|
319
|
+
const rowIndex = Math.trunc(rowIndexV.value);
|
|
320
|
+
const rangeLookupV = args.length > 3 ? (0, values_1.toBooleanRV)(args[3]) : { kind: 3 /* RVKind.Boolean */, value: true };
|
|
321
|
+
if ((0, values_1.isError)(rangeLookupV)) {
|
|
322
|
+
return rangeLookupV;
|
|
323
|
+
}
|
|
324
|
+
const rangeLookup = rangeLookupV.value;
|
|
325
|
+
if (rowIndex < 1 || rowIndex > table.height) {
|
|
326
|
+
return values_1.ERRORS.REF;
|
|
327
|
+
}
|
|
328
|
+
if (!rangeLookup) {
|
|
329
|
+
for (let c = 0; c < table.width; c++) {
|
|
330
|
+
if ((0, values_1.scalarEquals)((0, _shared_1.getCell)(table, 0, c), lookupValue)) {
|
|
331
|
+
return (0, _shared_1.getCell)(table, rowIndex - 1, c);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return values_1.ERRORS.NA;
|
|
335
|
+
}
|
|
336
|
+
let bestCol = -1;
|
|
337
|
+
for (let c = 0; c < table.width; c++) {
|
|
338
|
+
const hv = (0, _shared_1.getCell)(table, 0, c);
|
|
339
|
+
if (sameType(hv, lookupValue)) {
|
|
340
|
+
// For approximate match, find largest <= lookupValue
|
|
341
|
+
if (scalarIsNumber(hv) && scalarIsNumber(lookupValue)) {
|
|
342
|
+
if (hv.value <= lookupValue.value) {
|
|
343
|
+
bestCol = c;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
else if (scalarIsString(hv) && scalarIsString(lookupValue)) {
|
|
347
|
+
if (hv.value.toLowerCase() <= lookupValue.value.toLowerCase()) {
|
|
348
|
+
bestCol = c;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
return bestCol >= 0 ? (0, _shared_1.getCell)(table, rowIndex - 1, bestCol) : values_1.ERRORS.NA;
|
|
354
|
+
}
|
|
355
|
+
function fnXLOOKUP(args) {
|
|
356
|
+
const lookupValue = (0, values_1.topLeft)(args[0]);
|
|
357
|
+
if (lookupValue.kind === 4 /* RVKind.Error */) {
|
|
358
|
+
return lookupValue;
|
|
359
|
+
}
|
|
360
|
+
if (!(0, values_1.isArray)(args[1])) {
|
|
361
|
+
return values_1.ERRORS.VALUE;
|
|
362
|
+
}
|
|
363
|
+
const lookupArr = args[1];
|
|
364
|
+
if (!(0, values_1.isArray)(args[2])) {
|
|
365
|
+
return values_1.ERRORS.VALUE;
|
|
366
|
+
}
|
|
367
|
+
const returnArr = args[2];
|
|
368
|
+
const ifNotFound = args.length > 3 ? (0, values_1.topLeft)(args[3]) : null;
|
|
369
|
+
const matchModeV = args.length > 4 ? (0, values_1.toNumberRV)(args[4]) : (0, values_1.rvNumber)(0);
|
|
370
|
+
if ((0, values_1.isError)(matchModeV)) {
|
|
371
|
+
return matchModeV;
|
|
372
|
+
}
|
|
373
|
+
const matchMode = matchModeV.value;
|
|
374
|
+
const searchModeV = args.length > 5 ? (0, values_1.toNumberRV)(args[5]) : (0, values_1.rvNumber)(1);
|
|
375
|
+
if ((0, values_1.isError)(searchModeV)) {
|
|
376
|
+
return searchModeV;
|
|
377
|
+
}
|
|
378
|
+
const searchMode = searchModeV.value;
|
|
379
|
+
// Flatten lookup array to 1D
|
|
380
|
+
const flat = [];
|
|
381
|
+
const isRow = lookupArr.height === 1;
|
|
382
|
+
if (isRow) {
|
|
383
|
+
for (let c = 0; c < lookupArr.width; c++) {
|
|
384
|
+
flat.push((0, _shared_1.getCell)(lookupArr, 0, c));
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
for (let r = 0; r < lookupArr.height; r++) {
|
|
389
|
+
flat.push((0, _shared_1.getCell)(lookupArr, r, 0));
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
let foundIdx = -1;
|
|
393
|
+
const doCompare = (a, b) => {
|
|
394
|
+
// Use `compareScalarsSameKind` (shared with sorting / linear match)
|
|
395
|
+
// instead of `localeCompare`. `localeCompare` is locale-sensitive and
|
|
396
|
+
// can disagree with the `toLowerCase+===` equality check used on the
|
|
397
|
+
// linear-search path — binary search would then skip the exact cell
|
|
398
|
+
// that linear search would find (e.g. Turkish dotless I, ß→ss, etc.).
|
|
399
|
+
// See R6-P1-11.
|
|
400
|
+
const cmp = (0, values_1.compareScalarsSameKind)(a, b);
|
|
401
|
+
return Number.isFinite(cmp) ? cmp : 0;
|
|
402
|
+
};
|
|
403
|
+
// ── Binary search for sorted data (searchMode = ±2) ──
|
|
404
|
+
// Excel assumes the data is sorted ascending (2) or descending (-2). The
|
|
405
|
+
// array must contain values of a single type compatible with `lookupValue`;
|
|
406
|
+
// cells of an incompatible type make the sort invalid and binary search
|
|
407
|
+
// cannot produce a meaningful result, so we fall back to #N/A in that
|
|
408
|
+
// scenario (matching Excel's behaviour when the data is "not sorted").
|
|
409
|
+
//
|
|
410
|
+
// Supports matchMode 0 (exact), -1 (exact or next smaller), 1 (exact or
|
|
411
|
+
// next larger). Wildcard matchMode (2) is incompatible with binary search
|
|
412
|
+
// by definition — Excel silently downgrades to linear scan, which we do
|
|
413
|
+
// by leaving `searchMode` as 1 below.
|
|
414
|
+
const isBinary = (searchMode === 2 || searchMode === -2) && matchMode !== 2;
|
|
415
|
+
if (isBinary) {
|
|
416
|
+
const ascending = searchMode === 2;
|
|
417
|
+
let lo = 0;
|
|
418
|
+
let hi = flat.length - 1;
|
|
419
|
+
let exact = -1;
|
|
420
|
+
let nextSmaller = -1; // largest index with value < lookupValue (ascending)
|
|
421
|
+
let nextLarger = -1; // smallest index with value > lookupValue (ascending)
|
|
422
|
+
while (lo <= hi) {
|
|
423
|
+
const mid = (lo + hi) >>> 1;
|
|
424
|
+
const v = flat[mid];
|
|
425
|
+
if (!sameType(v, lookupValue)) {
|
|
426
|
+
// Heterogeneous array — binary search preconditions violated.
|
|
427
|
+
exact = -1;
|
|
428
|
+
nextSmaller = -1;
|
|
429
|
+
nextLarger = -1;
|
|
430
|
+
break;
|
|
431
|
+
}
|
|
432
|
+
const cmp = doCompare(v, lookupValue);
|
|
433
|
+
if (cmp === 0) {
|
|
434
|
+
exact = mid;
|
|
435
|
+
break;
|
|
436
|
+
}
|
|
437
|
+
// In descending order, the ordering is inverted: treat `cmp > 0` on
|
|
438
|
+
// the left half as "still greater than target" → search right.
|
|
439
|
+
const goLeft = ascending ? cmp > 0 : cmp < 0;
|
|
440
|
+
if (goLeft) {
|
|
441
|
+
// mid is larger (ascending) or smaller (descending) than target
|
|
442
|
+
if (ascending) {
|
|
443
|
+
nextLarger = nextLarger === -1 || mid < nextLarger ? mid : nextLarger;
|
|
444
|
+
}
|
|
445
|
+
else {
|
|
446
|
+
nextSmaller = nextSmaller === -1 || mid < nextSmaller ? mid : nextSmaller;
|
|
447
|
+
}
|
|
448
|
+
hi = mid - 1;
|
|
449
|
+
}
|
|
450
|
+
else {
|
|
451
|
+
if (ascending) {
|
|
452
|
+
nextSmaller = nextSmaller === -1 || mid > nextSmaller ? mid : nextSmaller;
|
|
453
|
+
}
|
|
454
|
+
else {
|
|
455
|
+
nextLarger = nextLarger === -1 || mid > nextLarger ? mid : nextLarger;
|
|
456
|
+
}
|
|
457
|
+
lo = mid + 1;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
if (exact !== -1) {
|
|
461
|
+
foundIdx = exact;
|
|
462
|
+
}
|
|
463
|
+
else if (matchMode === -1) {
|
|
464
|
+
foundIdx = nextSmaller;
|
|
465
|
+
}
|
|
466
|
+
else if (matchMode === 1) {
|
|
467
|
+
foundIdx = nextLarger;
|
|
468
|
+
}
|
|
469
|
+
else {
|
|
470
|
+
foundIdx = -1;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
else if (matchMode === 0) {
|
|
474
|
+
// Exact match
|
|
475
|
+
const start = searchMode === -1 ? flat.length - 1 : 0;
|
|
476
|
+
const end = searchMode === -1 ? -1 : flat.length;
|
|
477
|
+
const step = searchMode === -1 ? -1 : 1;
|
|
478
|
+
for (let i = start; i !== end; i += step) {
|
|
479
|
+
if ((0, values_1.scalarEquals)(flat[i], lookupValue)) {
|
|
480
|
+
foundIdx = i;
|
|
481
|
+
break;
|
|
482
|
+
}
|
|
483
|
+
if (scalarStringEquals(flat[i], lookupValue)) {
|
|
484
|
+
foundIdx = i;
|
|
485
|
+
break;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
else if (matchMode === -1) {
|
|
490
|
+
// Exact match or next smaller
|
|
491
|
+
let best = -1;
|
|
492
|
+
for (let i = 0; i < flat.length; i++) {
|
|
493
|
+
if (sameType(flat[i], lookupValue)) {
|
|
494
|
+
const cmp = doCompare(flat[i], lookupValue);
|
|
495
|
+
if (cmp === 0) {
|
|
496
|
+
best = i;
|
|
497
|
+
break;
|
|
498
|
+
}
|
|
499
|
+
if (cmp < 0 && (best === -1 || doCompare(flat[i], flat[best]) > 0)) {
|
|
500
|
+
best = i;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
foundIdx = best;
|
|
505
|
+
}
|
|
506
|
+
else if (matchMode === 1) {
|
|
507
|
+
// Exact match or next larger
|
|
508
|
+
let best = -1;
|
|
509
|
+
for (let i = 0; i < flat.length; i++) {
|
|
510
|
+
if (sameType(flat[i], lookupValue)) {
|
|
511
|
+
const cmp = doCompare(flat[i], lookupValue);
|
|
512
|
+
if (cmp === 0) {
|
|
513
|
+
best = i;
|
|
514
|
+
break;
|
|
515
|
+
}
|
|
516
|
+
if (cmp > 0 && (best === -1 || doCompare(flat[i], flat[best]) < 0)) {
|
|
517
|
+
best = i;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
foundIdx = best;
|
|
522
|
+
}
|
|
523
|
+
else if (matchMode === 2) {
|
|
524
|
+
// Wildcard match — uses the shared Excel wildcard converter so SEARCH,
|
|
525
|
+
// MATCH, XLOOKUP, and SUMIF/COUNTIF agree on `~*`, `~?`, `~~` escaping.
|
|
526
|
+
const lookupStr = (0, values_1.toStringRV)(lookupValue);
|
|
527
|
+
const pattern = (0, _shared_1.excelWildcardToRegex)(lookupStr);
|
|
528
|
+
try {
|
|
529
|
+
const re = new RegExp("^" + pattern + "$", "i");
|
|
530
|
+
for (let i = 0; i < flat.length; i++) {
|
|
531
|
+
if (re.test((0, values_1.toStringRV)(flat[i]))) {
|
|
532
|
+
foundIdx = i;
|
|
533
|
+
break;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
catch {
|
|
538
|
+
for (let i = 0; i < flat.length; i++) {
|
|
539
|
+
if ((0, values_1.toStringRV)(flat[i]).toLowerCase() === lookupStr.toLowerCase()) {
|
|
540
|
+
foundIdx = i;
|
|
541
|
+
break;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
if (foundIdx === -1) {
|
|
547
|
+
return ifNotFound !== null ? ifNotFound : values_1.ERRORS.NA;
|
|
548
|
+
}
|
|
549
|
+
// Return from return array
|
|
550
|
+
if (isRow) {
|
|
551
|
+
// Horizontal lookup: the lookup axis is the column axis of the return
|
|
552
|
+
// array, so `foundIdx` selects a column. A single-row return array
|
|
553
|
+
// yields a scalar; a multi-row return array yields a column vector.
|
|
554
|
+
if (foundIdx >= returnArr.width) {
|
|
555
|
+
return values_1.BLANK;
|
|
556
|
+
}
|
|
557
|
+
if (returnArr.height === 1) {
|
|
558
|
+
return (0, _shared_1.getCell)(returnArr, 0, foundIdx);
|
|
559
|
+
}
|
|
560
|
+
const col = [];
|
|
561
|
+
for (let r = 0; r < returnArr.height; r++) {
|
|
562
|
+
col.push([(0, _shared_1.getCell)(returnArr, r, foundIdx)]);
|
|
563
|
+
}
|
|
564
|
+
return (0, values_1.rvArray)(col);
|
|
565
|
+
}
|
|
566
|
+
// Vertical lookup: `foundIdx` selects a row; a single-column return
|
|
567
|
+
// array yields a scalar; a multi-column array yields a row vector.
|
|
568
|
+
if (foundIdx < returnArr.height) {
|
|
569
|
+
if (returnArr.width === 1) {
|
|
570
|
+
return (0, _shared_1.getCell)(returnArr, foundIdx, 0);
|
|
571
|
+
}
|
|
572
|
+
const row = [];
|
|
573
|
+
for (let c = 0; c < returnArr.width; c++) {
|
|
574
|
+
row.push((0, _shared_1.getCell)(returnArr, foundIdx, c));
|
|
575
|
+
}
|
|
576
|
+
return (0, values_1.rvArray)([row]);
|
|
577
|
+
}
|
|
578
|
+
return values_1.BLANK;
|
|
579
|
+
}
|
|
580
|
+
function fnXMATCH(args) {
|
|
581
|
+
const lookupValue = (0, values_1.topLeft)(args[0]);
|
|
582
|
+
if (lookupValue.kind === 4 /* RVKind.Error */) {
|
|
583
|
+
return lookupValue;
|
|
584
|
+
}
|
|
585
|
+
if (!(0, values_1.isArray)(args[1])) {
|
|
586
|
+
return values_1.ERRORS.VALUE;
|
|
587
|
+
}
|
|
588
|
+
const lookupArr = args[1];
|
|
589
|
+
const matchModeV = args.length > 2 ? (0, values_1.toNumberRV)(args[2]) : (0, values_1.rvNumber)(0);
|
|
590
|
+
if ((0, values_1.isError)(matchModeV)) {
|
|
591
|
+
return matchModeV;
|
|
592
|
+
}
|
|
593
|
+
const matchMode = matchModeV.value;
|
|
594
|
+
const searchModeV = args.length > 3 ? (0, values_1.toNumberRV)(args[3]) : (0, values_1.rvNumber)(1);
|
|
595
|
+
if ((0, values_1.isError)(searchModeV)) {
|
|
596
|
+
return searchModeV;
|
|
597
|
+
}
|
|
598
|
+
const searchMode = searchModeV.value;
|
|
599
|
+
const flat = [];
|
|
600
|
+
if (lookupArr.height === 1) {
|
|
601
|
+
for (let c = 0; c < lookupArr.width; c++) {
|
|
602
|
+
flat.push((0, _shared_1.getCell)(lookupArr, 0, c));
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
else {
|
|
606
|
+
for (let r = 0; r < lookupArr.height; r++) {
|
|
607
|
+
flat.push((0, _shared_1.getCell)(lookupArr, r, 0));
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
if (matchMode === 0) {
|
|
611
|
+
const start = searchMode === -1 ? flat.length - 1 : 0;
|
|
612
|
+
const end = searchMode === -1 ? -1 : flat.length;
|
|
613
|
+
const step = searchMode === -1 ? -1 : 1;
|
|
614
|
+
for (let i = start; i !== end; i += step) {
|
|
615
|
+
if ((0, values_1.scalarEquals)(flat[i], lookupValue)) {
|
|
616
|
+
return (0, values_1.rvNumber)(i + 1);
|
|
617
|
+
}
|
|
618
|
+
if (scalarStringEquals(flat[i], lookupValue)) {
|
|
619
|
+
return (0, values_1.rvNumber)(i + 1);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
return values_1.ERRORS.NA;
|
|
623
|
+
}
|
|
624
|
+
if (matchMode === 2) {
|
|
625
|
+
// Wildcard matching — `*` and `?` (with `~` escape). Only meaningful
|
|
626
|
+
// when the lookup value is a string; for non-string lookup values
|
|
627
|
+
// Excel falls back to plain comparison.
|
|
628
|
+
if (lookupValue.kind !== 2 /* RVKind.String */) {
|
|
629
|
+
// Fall through to exact-match semantics for non-string lookups.
|
|
630
|
+
const start = searchMode === -1 ? flat.length - 1 : 0;
|
|
631
|
+
const end = searchMode === -1 ? -1 : flat.length;
|
|
632
|
+
const step = searchMode === -1 ? -1 : 1;
|
|
633
|
+
for (let i = start; i !== end; i += step) {
|
|
634
|
+
if ((0, values_1.scalarEquals)(flat[i], lookupValue)) {
|
|
635
|
+
return (0, values_1.rvNumber)(i + 1);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
return values_1.ERRORS.NA;
|
|
639
|
+
}
|
|
640
|
+
const pattern = lookupValue.value;
|
|
641
|
+
const matcher = (0, _shared_1.hasUnescapedWildcard)(pattern)
|
|
642
|
+
? new RegExp(`^${(0, _shared_1.excelWildcardToRegex)(pattern)}$`, "iu")
|
|
643
|
+
: null;
|
|
644
|
+
const literal = matcher ? null : (0, _shared_1.unescapeExcelWildcard)(pattern).toLowerCase();
|
|
645
|
+
const start = searchMode === -1 ? flat.length - 1 : 0;
|
|
646
|
+
const end = searchMode === -1 ? -1 : flat.length;
|
|
647
|
+
const step = searchMode === -1 ? -1 : 1;
|
|
648
|
+
for (let i = start; i !== end; i += step) {
|
|
649
|
+
const cell = flat[i];
|
|
650
|
+
if (cell.kind !== 2 /* RVKind.String */) {
|
|
651
|
+
continue;
|
|
652
|
+
}
|
|
653
|
+
if (matcher) {
|
|
654
|
+
if (matcher.test(cell.value)) {
|
|
655
|
+
return (0, values_1.rvNumber)(i + 1);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
else if (cell.value.toLowerCase() === literal) {
|
|
659
|
+
return (0, values_1.rvNumber)(i + 1);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
return values_1.ERRORS.NA;
|
|
663
|
+
}
|
|
664
|
+
if (matchMode === -1) {
|
|
665
|
+
// Next-smaller-or-equal: largest item <= lookupValue.
|
|
666
|
+
let best = -1;
|
|
667
|
+
for (let i = 0; i < flat.length; i++) {
|
|
668
|
+
const cmp = compareScalar(flat[i], lookupValue);
|
|
669
|
+
if (Number.isNaN(cmp)) {
|
|
670
|
+
continue;
|
|
671
|
+
}
|
|
672
|
+
if (cmp <= 0 && (best === -1 || compareScalar(flat[i], flat[best]) > 0)) {
|
|
673
|
+
best = i;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
return best >= 0 ? (0, values_1.rvNumber)(best + 1) : values_1.ERRORS.NA;
|
|
677
|
+
}
|
|
678
|
+
if (matchMode === 1) {
|
|
679
|
+
// Next-larger-or-equal: smallest item >= lookupValue.
|
|
680
|
+
let best = -1;
|
|
681
|
+
for (let i = 0; i < flat.length; i++) {
|
|
682
|
+
const cmp = compareScalar(flat[i], lookupValue);
|
|
683
|
+
if (Number.isNaN(cmp)) {
|
|
684
|
+
continue;
|
|
685
|
+
}
|
|
686
|
+
if (cmp >= 0 && (best === -1 || compareScalar(flat[i], flat[best]) < 0)) {
|
|
687
|
+
best = i;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
return best >= 0 ? (0, values_1.rvNumber)(best + 1) : values_1.ERRORS.NA;
|
|
691
|
+
}
|
|
692
|
+
return values_1.ERRORS.NA;
|
|
693
|
+
}
|
|
694
|
+
function fnADDRESS(args) {
|
|
695
|
+
const rowNumV = (0, values_1.toNumberRV)(args[0]);
|
|
696
|
+
if ((0, values_1.isError)(rowNumV)) {
|
|
697
|
+
return rowNumV;
|
|
698
|
+
}
|
|
699
|
+
const rowNum = Math.trunc(rowNumV.value);
|
|
700
|
+
const colNumV = (0, values_1.toNumberRV)(args[1]);
|
|
701
|
+
if ((0, values_1.isError)(colNumV)) {
|
|
702
|
+
return colNumV;
|
|
703
|
+
}
|
|
704
|
+
const colNum = Math.trunc(colNumV.value);
|
|
705
|
+
// ADDRESS rejects non-positive row/col with #VALUE!. Without this guard
|
|
706
|
+
// ADDRESS(0, 1) would silently return "$A$0" and ADDRESS(1, 0) would
|
|
707
|
+
// produce "$$1" (no column letter) — neither is a legal cell reference.
|
|
708
|
+
if (!Number.isFinite(rowNum) || !Number.isFinite(colNum) || rowNum < 1 || colNum < 1) {
|
|
709
|
+
return values_1.ERRORS.VALUE;
|
|
710
|
+
}
|
|
711
|
+
const absNumV = args.length > 2 ? (0, values_1.toNumberRV)(args[2]) : (0, values_1.rvNumber)(1);
|
|
712
|
+
if ((0, values_1.isError)(absNumV)) {
|
|
713
|
+
return absNumV;
|
|
714
|
+
}
|
|
715
|
+
const absNum = Math.trunc(absNumV.value);
|
|
716
|
+
// Excel only accepts abs_num ∈ {1, 2, 3, 4}; anything else is #VALUE!.
|
|
717
|
+
if (absNum < 1 || absNum > 4) {
|
|
718
|
+
return values_1.ERRORS.VALUE;
|
|
719
|
+
}
|
|
720
|
+
// a1 style (true/default) vs r1c1 (false)
|
|
721
|
+
const a1Arg = args.length > 3 ? (0, values_1.topLeft)(args[3]) : { kind: 3 /* RVKind.Boolean */, value: true };
|
|
722
|
+
const a1 = a1Arg.kind === 3 /* RVKind.Boolean */ ? a1Arg.value : true;
|
|
723
|
+
const sheetText = args.length > 4 ? (0, values_1.toStringRV)(args[4]) : "";
|
|
724
|
+
if (!a1) {
|
|
725
|
+
// R1C1 style
|
|
726
|
+
const rPart = absNum === 1 || absNum === 2 ? `R${rowNum}` : `R[${rowNum}]`;
|
|
727
|
+
const cPart = absNum === 1 || absNum === 3 ? `C${colNum}` : `C[${colNum}]`;
|
|
728
|
+
const prefix = sheetText ? `${renderSheetPrefix(sheetText)}!` : "";
|
|
729
|
+
return (0, values_1.rvString)(prefix + rPart + cPart);
|
|
730
|
+
}
|
|
731
|
+
// Convert column number to letters
|
|
732
|
+
let col = "";
|
|
733
|
+
let cv = colNum;
|
|
734
|
+
while (cv > 0) {
|
|
735
|
+
cv--;
|
|
736
|
+
col = String.fromCharCode(65 + (cv % 26)) + col;
|
|
737
|
+
cv = Math.floor(cv / 26);
|
|
738
|
+
}
|
|
739
|
+
let result;
|
|
740
|
+
switch (absNum) {
|
|
741
|
+
case 1:
|
|
742
|
+
result = "$" + col + "$" + rowNum;
|
|
743
|
+
break;
|
|
744
|
+
case 2:
|
|
745
|
+
result = col + "$" + rowNum;
|
|
746
|
+
break;
|
|
747
|
+
case 3:
|
|
748
|
+
result = "$" + col + rowNum;
|
|
749
|
+
break;
|
|
750
|
+
case 4:
|
|
751
|
+
result = col + rowNum;
|
|
752
|
+
break;
|
|
753
|
+
default:
|
|
754
|
+
// Unreachable — `absNum` is already validated to {1, 2, 3, 4} above.
|
|
755
|
+
result = "$" + col + "$" + rowNum;
|
|
756
|
+
}
|
|
757
|
+
if (sheetText) {
|
|
758
|
+
result = renderSheetPrefix(sheetText) + "!" + result;
|
|
759
|
+
}
|
|
760
|
+
return (0, values_1.rvString)(result);
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* Quote a sheet name for use in a reference prefix the way Excel does:
|
|
764
|
+
* - plain `Name` (letters, digits, underscore, leading non-digit) → as-is
|
|
765
|
+
* - anything else → wrapped in single quotes with embedded `'` doubled
|
|
766
|
+
*/
|
|
767
|
+
function renderSheetPrefix(name) {
|
|
768
|
+
if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) {
|
|
769
|
+
return name;
|
|
770
|
+
}
|
|
771
|
+
return `'${name.replace(/'/g, "''")}'`;
|
|
772
|
+
}
|
|
773
|
+
function fnLOOKUP(args) {
|
|
774
|
+
const lookupValue = (0, values_1.topLeft)(args[0]);
|
|
775
|
+
if (lookupValue.kind === 4 /* RVKind.Error */) {
|
|
776
|
+
return lookupValue;
|
|
777
|
+
}
|
|
778
|
+
if (!(0, values_1.isArray)(args[1])) {
|
|
779
|
+
return values_1.ERRORS.NA;
|
|
780
|
+
}
|
|
781
|
+
const lookupArr = args[1];
|
|
782
|
+
if (args.length > 2 && (0, values_1.isArray)(args[2])) {
|
|
783
|
+
const resultArr = args[2];
|
|
784
|
+
const flat = [];
|
|
785
|
+
const isRow = lookupArr.height === 1;
|
|
786
|
+
if (isRow) {
|
|
787
|
+
for (let c = 0; c < lookupArr.width; c++) {
|
|
788
|
+
flat.push((0, _shared_1.getCell)(lookupArr, 0, c));
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
else {
|
|
792
|
+
for (let r = 0; r < lookupArr.height; r++) {
|
|
793
|
+
flat.push((0, _shared_1.getCell)(lookupArr, r, 0));
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
let bestIdx = -1;
|
|
797
|
+
for (let i = 0; i < flat.length; i++) {
|
|
798
|
+
const v = flat[i];
|
|
799
|
+
if (sameType(v, lookupValue)) {
|
|
800
|
+
if (scalarIsNumber(v) && scalarIsNumber(lookupValue) && v.value <= lookupValue.value) {
|
|
801
|
+
bestIdx = i;
|
|
802
|
+
}
|
|
803
|
+
else if (scalarIsString(v) &&
|
|
804
|
+
scalarIsString(lookupValue) &&
|
|
805
|
+
v.value.toLowerCase() <= lookupValue.value.toLowerCase()) {
|
|
806
|
+
bestIdx = i;
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
if (bestIdx === -1) {
|
|
811
|
+
return values_1.ERRORS.NA;
|
|
812
|
+
}
|
|
813
|
+
if (isRow) {
|
|
814
|
+
return resultArr.height === 1
|
|
815
|
+
? bestIdx < resultArr.width
|
|
816
|
+
? (0, _shared_1.getCell)(resultArr, 0, bestIdx)
|
|
817
|
+
: values_1.BLANK
|
|
818
|
+
: bestIdx < resultArr.height
|
|
819
|
+
? (0, _shared_1.getCell)(resultArr, bestIdx, 0)
|
|
820
|
+
: values_1.BLANK;
|
|
821
|
+
}
|
|
822
|
+
return bestIdx < resultArr.height ? (0, _shared_1.getCell)(resultArr, bestIdx, 0) : values_1.BLANK;
|
|
823
|
+
}
|
|
824
|
+
const rows = lookupArr.height;
|
|
825
|
+
const cols = lookupArr.width;
|
|
826
|
+
if (cols === 0) {
|
|
827
|
+
return values_1.ERRORS.NA;
|
|
828
|
+
}
|
|
829
|
+
if (cols >= rows) {
|
|
830
|
+
let bestIdx = -1;
|
|
831
|
+
for (let c = 0; c < cols; c++) {
|
|
832
|
+
const v = (0, _shared_1.getCell)(lookupArr, 0, c);
|
|
833
|
+
if (sameType(v, lookupValue)) {
|
|
834
|
+
if (scalarIsNumber(v) && scalarIsNumber(lookupValue) && v.value <= lookupValue.value) {
|
|
835
|
+
bestIdx = c;
|
|
836
|
+
}
|
|
837
|
+
else if (scalarIsString(v) &&
|
|
838
|
+
scalarIsString(lookupValue) &&
|
|
839
|
+
v.value.toLowerCase() <= lookupValue.value.toLowerCase()) {
|
|
840
|
+
bestIdx = c;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
return bestIdx >= 0 ? (0, _shared_1.getCell)(lookupArr, rows - 1, bestIdx) : values_1.ERRORS.NA;
|
|
845
|
+
}
|
|
846
|
+
let bestIdx = -1;
|
|
847
|
+
for (let r = 0; r < rows; r++) {
|
|
848
|
+
const v = (0, _shared_1.getCell)(lookupArr, r, 0);
|
|
849
|
+
if (sameType(v, lookupValue)) {
|
|
850
|
+
if (scalarIsNumber(v) && scalarIsNumber(lookupValue) && v.value <= lookupValue.value) {
|
|
851
|
+
bestIdx = r;
|
|
852
|
+
}
|
|
853
|
+
else if (scalarIsString(v) &&
|
|
854
|
+
scalarIsString(lookupValue) &&
|
|
855
|
+
v.value.toLowerCase() <= lookupValue.value.toLowerCase()) {
|
|
856
|
+
bestIdx = r;
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
return bestIdx >= 0 ? (0, _shared_1.getCell)(lookupArr, bestIdx, cols - 1) : values_1.ERRORS.NA;
|
|
861
|
+
}
|
|
862
|
+
function fnTRANSPOSE(args) {
|
|
863
|
+
if (!(0, values_1.isArray)(args[0])) {
|
|
864
|
+
const sv = (0, values_1.topLeft)(args[0]);
|
|
865
|
+
// Excel propagates errors through TRANSPOSE rather than burying them
|
|
866
|
+
// inside a 1×1 array — callers that then aggregate the result (e.g.
|
|
867
|
+
// `SUM(TRANSPOSE(#N/A))`) expect the error to surface. R8-P1 fix.
|
|
868
|
+
if (sv.kind === 4 /* RVKind.Error */) {
|
|
869
|
+
return sv;
|
|
870
|
+
}
|
|
871
|
+
return (0, values_1.rvArray)([[sv]]);
|
|
872
|
+
}
|
|
873
|
+
const arr = args[0];
|
|
874
|
+
const rows = arr.height;
|
|
875
|
+
const cols = arr.width;
|
|
876
|
+
const result = [];
|
|
877
|
+
for (let c = 0; c < cols; c++) {
|
|
878
|
+
const row = [];
|
|
879
|
+
for (let r = 0; r < rows; r++) {
|
|
880
|
+
row.push((0, _shared_1.getCell)(arr, r, c));
|
|
881
|
+
}
|
|
882
|
+
result.push(row);
|
|
883
|
+
}
|
|
884
|
+
return (0, values_1.rvArray)(result);
|
|
885
|
+
}
|
|
886
|
+
function fnAREAS(args) {
|
|
887
|
+
if (args.length === 0) {
|
|
888
|
+
return values_1.ERRORS.VALUE;
|
|
889
|
+
}
|
|
890
|
+
// Error in the argument propagates (Excel parity). A reference value
|
|
891
|
+
// counts as one area; the engine does not yet build multi-area
|
|
892
|
+
// references via `(A1, B1)` union syntax — when that lands, the arity
|
|
893
|
+
// should be `v.areas.length`, not a hardcoded 1.
|
|
894
|
+
const a = args[0];
|
|
895
|
+
if (a.kind === 4 /* RVKind.Error */) {
|
|
896
|
+
return a;
|
|
897
|
+
}
|
|
898
|
+
if (a.kind === 6 /* RVKind.Reference */) {
|
|
899
|
+
return (0, values_1.rvNumber)(a.areas.length);
|
|
900
|
+
}
|
|
901
|
+
return (0, values_1.rvNumber)(1);
|
|
902
|
+
}
|