SpreadsheetEvaluator.h header

#include <ew/core/spreadsheet/SpreadsheetEvaluator.h>

Namespace ew::core::spreadsheet

Functions

QString ew::core::spreadsheet::evaluatedValue(const Spreadsheet &sheet, int row, int column, const expression::Bindings *names=nullptr)

Evaluates the cell at (row, column) of sheet to the text it should display.

A cell whose text is not a formula (does not begin with '=') displays that text verbatim. A formula ("=<expression>") is parsed and computed over the sheet's cells by ew::core::expression::evaluate, whose documentation lists the operators and functions the language offers – they are the same ones a branching condition and a validation rule are written with. What a spreadsheet adds is what its NAMES mean:

  • A1-style cell references (resolved recursively) – a single reference reads the cell's number or text – and A1:B2 ranges (empty and text cells in a range are skipped); the column and the row may each be pinned with a '$' ($A$1, $A1, A$1), which reads as the same cell as the unpinned form (a pin governs only which cell a formula points at once it is copied elsewhere). names resolves anything that is NOT a cell reference, or nullptr when a formula may name only cells. This is the seam through which a sheet reaches the rest of the project – a formula naming @Rhys.stats.strength is resolved by the caller's bindings, because a spreadsheet lives in the engine and the codex it would be reading lives a layer above it. See ew::app::spreadsheet::evaluatedValues, which supplies the world.

A numeric result is formatted for display and text is returned as-is, or one of the error tokens "#REF!" (bad reference), "#CIRC!" (a reference cycle), "#DIV/0!" (division by zero), or "#ERR!" (a malformed formula, arithmetic on non-numeric text, or a function given the wrong number of arguments) is returned.

std::map< std::pair< int, int >, QString > ew::core::spreadsheet::evaluatedValues(const Spreadsheet &sheet, const expression::Bindings *names=nullptr)

Evaluates EVERY populated cell of sheet in one pass, returning (row, column) -> the text that cell should display. A cell not in the result is empty and displays nothing.

Each entry is exactly what evaluatedValue would return for that cell, including the error tokens; this is a performance entry point, not a different semantics. The difference is that one call shares its results across the whole sheet, so a cell that twenty formulas depend on is evaluated once rather than twenty times. evaluatedValue must rebuild the dependency order and re-evaluate the whole closure on every call, which makes displaying a sheet cost time quadratic in the length of its formula chains – an ordinary running-total column of 2,000 rows measured 1.6 SECONDS per full repaint before this existed.

Prefer this wherever more than a handful of cells are wanted at once: painting a grid, exporting, or pushing a sheet back to the codex. A cycle still yields "#CIRC!" for the cells whose dependencies reach it, leaving the rest of the sheet correct.