Rewrite rule formulas for the new top-left cell when cells are removed from a rule

Clearing validation from cells (or setting a new rule, or pasting a
validation over them) and Clear Rules on selected cells shrink a rule's
areas. When that removes the rule's top-left cell, the relative formulas
were left written for the old cell, so the cells left checked other
cells: clearing A1 off a custom `A1>10` on A1:A9 made A2 check A1.

Rewrite the relative references of validation formulas, and of
conditional format expressions and comparison values, for the new
top-left cell. Absolute references and literal lists stay as they are.
This commit is contained in:
ljkx
2026-11-03 00:18:50 +01:00
parent adcb66697c
commit fb6dc688bc
4 changed files with 76 additions and 0 deletions
+7
View File
@@ -38,11 +38,18 @@ fn subtract_range(r: RangeRef, cut: &RangeRef) -> Vec<RangeRef> {
}
/// Removes the cells of `cuts` from every validation, keeping the rest of each rule's ranges.
/// When the rule's top-left cell goes, its relative formulas are rewritten for the new top-left
/// cell, so the cells left keep checking the same cells.
pub(in super::super) fn remove_validation_cells(validations: &mut Vec<Validation>, cuts: &[RangeRef]) {
for dv in validations.iter_mut() {
let before = RangeRef::top_left(&dv.ranges);
for cut in cuts {
dv.ranges = dv.ranges.iter().flat_map(|r| subtract_range(*r, cut)).collect();
}
if let (Some(from), Some(to)) = (before, RangeRef::top_left(&dv.ranges)) {
dv.f1 = move_rule_formula(&dv.f1, from, to);
dv.f2 = dv.f2.take().map(|f| move_rule_formula(&f, from, to));
}
}
validations.retain(|d| !d.ranges.is_empty());
}