UNPKG

@syncfusion/ej2-spreadsheet

Version:

Feature-rich JavaScript Spreadsheet (Excel) control with built-in support for selection, editing, formatting, importing and exporting to Excel

84 lines (74 loc) 7.6 kB
# Basic Formulas Module data flow ## What It Does Provides core spreadsheet formula implementations (SUM, IF, DATE, TEXT, UNIQUE, RAND, LOOKUP family, etc.), solution helpers for spill/range handling, and wiring for formula registration. This module implements function semantics, argument normalization, and integration hooks for dependency tracking and spill updates used by the calculate engine. ## Entry Points (Core / Integration) - `constructor(parent?: Calculate)` — instantiates `BasicFormulas` and calls `init()` to register formulas. - `init()` — registers formula implementations via `addFormulaCollection()` into the engine's function table. - `addFormulaCollection(formulaName, functionName, category, description)` — map formula name → implementation. - Formula implementations: `ComputeSUM`, `ComputeIF`, `ComputeDATE`, `ComputeTODAY`, `ComputeUNIQUE`, `ComputeRAND`, `ComputeVLOOKUP`, `ComputeHLOOKUP`, `ComputeINDEX`, `ComputeMATCH`, `ComputeTEXT`, `ComputeCOUNT`, `ComputeAVERAGE`, `ComputeCONCATENATE`, `ComputeROUND/ROUNDUP/ROUNDDOWN`, `ComputeMEDIAN`, `ComputeEDATE`, `ComputeEOMONTH`, `ComputeRANDBETWEEN`, and many others provided in this module. - Helper methods: `setValueRefresh(splitValue,rowIdx,colIdx)`, `checkSpill(i,j)`, `clearDependency(value)`, `getDataCollection(cells)`, `parseDouble(value)`, formatting helpers (`spreadsheetDisplayText`, `spreadsheetFormat`). ## ASCII Core Logic Flow User edits cell or engine requests compute ↓ Workbook/Calculate resolves function call → engine invokes registered function handler (e.g., `ComputeSUM`) ↓ Function handler normalizes args (ranges → cell lists, strings → numbers/dates) using helpers ↓ For range-based functions: iterate `getDataCollection()` → gather values, coerce types ↓ Compute result (aggregate, lookup, date math, text transform) and handle special cases (errors, empty, booleans) ↓ If function produces spill (array/unique/sort), call `setValueRefresh()` and `checkSpill()` to write multi-cell results ↓ Update dependency maps via `clearDependency()`/dependency registration (engine-level) and write back computed values using calculate engine APIs ↓ Return final value (or error token) to caller; engine persists value, emits refresh notifications, and records undo/redo entry ## Operations & Key Functions (Implementation-focused) - Registration - `init()` enumerates `formulas[]` and binds implementation functions into the calculation function table. - Argument Normalization - Range expansion: `getDataCollection()` converts A1/range tokens into flat arrays of cell values used by aggregators. - Type coercion: `parseDouble()`, `spreadsheetDisplayText()` and `spreadsheetFormat()` ensure numeric/date/text coercions follow spreadsheet semantics. - Aggregates & Statistical - `ComputeSUM`, `ComputeAVERAGE`, `ComputeCOUNT`, `ComputeMIN`, `ComputeMAX`, `ComputePRODUCT`, `ComputeMEDIAN` — iterate normalized cell lists, skip/handle errors per spec. - Conditional / Logical - `ComputeIF`, `ComputeIFS`, `ComputeIFERROR`, `ComputeAND`, `ComputeOR`, `ComputeNOT` — evaluate logical expression semantics and short-circuit where applicable. - Lookup & Reference - `ComputeVLOOKUP`, `ComputeHLOOKUP`, `ComputeLOOKUP`, `ComputeINDEX`, `ComputeMATCH` — implement search semantics, match types, column/row index handling, and bounds checks. - Text & Formatting - `ComputeTEXT`, `ComputeCONCATENATE`, `ComputeCONCAT`, `ComputeLEN`, `ComputePROPER`, `ComputeFIND`, `ComputeEXACT` — perform string transforms with locale/format awareness. - Date/Time - `ComputeDATE`, `ComputeTODAY`, `ComputeNOW`, `ComputeEDATE`, `ComputeEOMONTH`, `ComputeDAY`, `ComputeMONTH`, `ComputeHOUR`, `ComputeMINUTE`, `ComputeSECOND` — date math using engine date helpers and calendar normalization. - Volatile & Random - `ComputeRAND`, `ComputeRANDBETWEEN` — flagged as volatile; integrated with `randomValues` tracking in `Calculate` for controlled refresh. - Spill & Array Behavior - `ComputeUNIQUE`, `ComputeSORT`, `ComputeFILTER` (if present) may produce multi-cell outputs; `setValueRefresh()` writes spill results and `checkSpill()` verifies target cells are free/valid. - `clearDependency()` removes stale dependency links when formulas are overwritten or spilled ranges change. - Numeric Utilities - `ComputeROUND`, `ComputeROUNDUP`, `ComputeROUNDDOWN`, `ComputeINT`, `ComputeABS`, `ComputePOWER`, `ComputeSQRT`, `ComputeLOG`, `ComputeLN` — implement numeric rounding, precision handling and domain checks. ## Validation & Safety - Argument validation: each `Compute*` verifies argument count, types, and returns spreadsheet-style errors (e.g., `#VALUE!`, `#DIV/0!`) when invalid. - Type coercion: functions explicitly coerce inputs per spreadsheet rules (empty→0 for numeric contexts if engine configured, strings→numbers when parseable). - Bounds & Index checks: lookup/index functions verify row/col indices and return errors for out-of-range access. - Spill conflict safety: `checkSpill()` ensures spill target range isn't blocked by locked/readonly cells; callers must handle failure and surface an error (or abort write). - Volatile function control: `ComputeRAND`/`ComputeRANDBETWEEN` register/refresh through `Calculate.randomValues` to avoid uncontrolled recalculation. - Error propagation: errors inside nested computations bubble up; module returns structured error tokens and relies on `Calculate.onFailure` to emit diagnostics. - No direct DOM mutations: all writes go through calculate/workbook APIs; UI layer is responsible for rendering and protection enforcement. ## Desired Outputs User-Facing - Correct computed cell values for single-cell and spilled formulas. - Properly formatted display values (dates, currency, text) via `spreadsheetFormat` helper when UI requests display text. - Error markers for invalid formulas (e.g., `#N/A`, `#REF!`, `#DIV/0!`) and visible spill ranges for array outputs. System-Level - **Function Registry:** formula name → handler mappings registered during `init()` used by `Calculate.getFunction()` and `getLibraryFormulas()`. - **Model Writes:** multi-cell spill writes via `setValueRefresh()` integrate with engine write/update pipeline and create undo/redo records (workbook layer must record actions). - **Dependency Updates:** `clearDependency()` and spreadsheet-wide dependency registration allow `Calculate` to maintain dependency graphs and trigger efficient refreshes. - **Volatile Tracking:** random/volatile functions update `Calculate.randomValues` for controlled refreshes. - **Events:** module returns results to the calculate engine which triggers cell update notifications; errors propagate to engine `onFailure` event. - **Undo/Redo:** callers (workbook/engine) should capture before/after snapshots when formula text or spilled ranges are committed. - **Headless:** module emits no DOM classes; UI actions (popups, dialogs) are handled by higher-level modules (Formula UI / Workbook integrations). ## Implementation Notes - Keep function implementations pure where possible: side-effects limited to spill writes and dependency clearing. - Normalize and validate ranges early to reduce repeated work in hot paths. - Unit-test edge cases: mixed types in ranges, large spills, volatile refresh behavior, lookup mismatches, date edge-cases (leap years, EOMONTH edge), and rounding precision. - Prefer helper reuse (`parseDouble`, `getDataCollection`, `spreadsheetFormat`) to preserve consistent behavior across formulas.