mirror of
https://github.com/storytold/gridcraft.git
synced 2026-11-10 12:29:58 -06:00
fix(calc): apply "Set precision as displayed" in calculation (#1366)
* ft-121.7.9: apply Set precision as displayed in calculation (#1343) With the option on, a formula result (and each element of a spill) is rounded to its cell's number format before it is stored and before other formulas read it. Numbers typed, pasted or reformatted while it is on are rounded at once, and turning it on through formulas.calculationOptions {precisionAsDisplayed} rounds every number constant, as Excel does. The rounding is NumberFormat::round_as_displayed in the numfmt crate, which shares the renderer's digit logic (fixed, scientific, fraction). General, date/time, text, digitless and conditional formats keep the full value, as observed in Excel through COM. Nothing changes when the flag is off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ft-121.7.9: round conditional formats by the sign's section under precision as displayed (#1343) Excel does round formats with a condition when "Set precision as displayed" is on; the PR kept them at full value. Observed through COM with synthetic values (and in gridcraft-corpus excel/precision-displayed/pad-on-conditional-sections.xlsx): conditions are ignored and the sign picks the section, the first for positives and the second for negatives. `[<1]0.00;0` shows 2+1/3 as 2 but stores 2.33, and stores -10/3 as -3. Two more observed details: with a condition and a single number section, negatives keep the full value (`[<1]0.00`), unless an `@` section follows (`[<1]0.00;@` rounds them by the first section); and a completely empty section passes to the next one (`0.0;;0.000` stores -2.333 as -2.333, `;0.0` stores 2.333 as 2.3), for formats with or without a condition. Display is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * engine: recalculate spill anchors when a spill cell is reformatted under precision as displayed round_edited_as_displayed only looked at stored-cell changes, but a spill destination lives in Sheet::spill, so reformatting it (or its row or column) left the anchor out of the changed set and the element unrounded. Add each spill anchor whose range holds a changed cell or a changed row/column style to the changed set. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * numfmt: drop a cast the fraction merge made redundant * precision as displayed: keep locked constants on protected sheets, round new sheets, fix manual-mode comment * precision as displayed: name the input sheet in the new-sheet histogram test * precision as displayed: use six values in the new-sheet histogram test --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
c402953828
commit
292b784f02
@@ -21,7 +21,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
"Options",
|
||||
["File"],
|
||||
None,
|
||||
"{} → {calculation: {mode, iterative, maxIterations, maxChange}} for the active workbook (the interface opens File › Options; change settings with their own commands, e.g. formulas.calculationOptions, view.theme, app.language.set)",
|
||||
"{} → {calculation: {mode, iterative, maxIterations, maxChange, precisionAsDisplayed}} for the active workbook (the interface opens File › Options; change settings with their own commands, e.g. formulas.calculationOptions, view.theme, app.language.set)",
|
||||
always,
|
||||
options
|
||||
),
|
||||
@@ -230,7 +230,7 @@ fn options(s: &mut Session, _: &Json) -> Result<Json> {
|
||||
gridcraft_model::CalcMode::AutomaticExceptTables => "automaticExceptTables",
|
||||
gridcraft_model::CalcMode::Manual => "manual",
|
||||
};
|
||||
json!({"mode": mode, "iterative": c.iterative, "maxIterations": c.max_iterations, "maxChange": c.max_change})
|
||||
json!({"mode": mode, "iterative": c.iterative, "maxIterations": c.max_iterations, "maxChange": c.max_change, "precisionAsDisplayed": c.precision_as_displayed})
|
||||
});
|
||||
Ok(json!({"calculation": calculation}))
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
"Calculation Options",
|
||||
["Formulas", "Calculation"],
|
||||
None,
|
||||
"{mode?: automatic|automaticExceptTables|manual, iterative?: bool (Enable iterative calculation), maxIterations?: 1–32767 (100), maxChange?: number (0.001)} → the settings. File › Options › Formulas › Calculation options; stored in the workbook.",
|
||||
"{mode?: automatic|automaticExceptTables|manual, iterative?: bool (Enable iterative calculation), maxIterations?: 1–32767 (100), maxChange?: number (0.001), precisionAsDisplayed?: bool (Set precision as displayed: numbers are stored as their format shows them; turning it on rounds every number constant permanently)} → the settings. File › Options › Formulas › Calculation options; stored in the workbook.",
|
||||
has_doc,
|
||||
calc_options
|
||||
),
|
||||
@@ -954,14 +954,30 @@ fn calc_options(s: &mut Session, p: &Json) -> Result<Json> {
|
||||
if let Some(v) = f64_param(p, "maxChange") {
|
||||
cx.wb.calc.set_max_change(v);
|
||||
}
|
||||
let precision = bool_param(p, "precisionAsDisplayed");
|
||||
if let Some(v) = precision {
|
||||
cx.wb.calc.precision_as_displayed = v;
|
||||
if v && !before.precision_as_displayed {
|
||||
crate::cmd::round_all_constants_as_displayed(&mut cx.wb);
|
||||
}
|
||||
}
|
||||
let c = &cx.wb.calc;
|
||||
// Switching to automatic, or changing how circular references are calculated outside
|
||||
// manual mode, recalculates the workbook.
|
||||
let iteration_changed = (c.iterative, c.max_iterations, c.max_change) != (before.iterative, before.max_iterations, before.max_change);
|
||||
if mode == Some(CalcMode::Automatic) || (iteration_changed && c.mode != CalcMode::Manual) {
|
||||
// Switching precision as displayed recalculates the workbook, in manual mode too, so the
|
||||
// values change as soon as it is switched on or off.
|
||||
let precision_changed = c.precision_as_displayed != before.precision_as_displayed;
|
||||
if mode == Some(CalcMode::Automatic) || (iteration_changed && c.mode != CalcMode::Manual) || precision_changed {
|
||||
cx.structural = true;
|
||||
}
|
||||
Ok(json!({"mode": format!("{:?}", c.mode), "iterative": c.iterative, "maxIterations": c.max_iterations, "maxChange": c.max_change}))
|
||||
Ok(json!({
|
||||
"mode": format!("{:?}", c.mode),
|
||||
"iterative": c.iterative,
|
||||
"maxIterations": c.max_iterations,
|
||||
"maxChange": c.max_change,
|
||||
"precisionAsDisplayed": c.precision_as_displayed,
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user