diff --git a/crates/calc/src/eval.rs b/crates/calc/src/eval.rs index 92a0a39fd..5cbc1ca53 100644 --- a/crates/calc/src/eval.rs +++ b/crates/calc/src/eval.rs @@ -1290,7 +1290,9 @@ impl<'h> Evaluator<'h> { } fn subtotal(&mut self, name: &str, args: &[Expr]) -> Ev { - if args.len() < 2 { + // SUBTOTAL needs function_num and ref1; AGGREGATE needs function_num, options and ref1. + let min_args = if name == "AGGREGATE" { 3 } else { 2 }; + if args.len() < min_args { return err(CellError::Value); } let code = match self.arg_num(args, 0, 0.0) { diff --git a/crates/calc/src/tests.rs b/crates/calc/src/tests.rs index 513340983..6c42eedf7 100644 --- a/crates/calc/src/tests.rs +++ b/crates/calc/src/tests.rs @@ -608,6 +608,23 @@ fn subtotal_skips_filtered_rows() { } } +#[test] +fn aggregate_without_data_argument_is_an_error() { + let mut t = T::new(); + t.set("A1", "1"); + t.set("A2", "2"); + t.set("D1", "=AGGREGATE(9,0)"); + t.set("D2", "=AGGREGATE(4,0)"); + t.set("D3", "=AGGREGATE(9,0,A1:A2)"); + t.set("D4", "=AGGREGATE(9,0,A3:A4)"); + t.set("D5", "=AGGREGATE(9,0,A1:A2,A1:A2)"); + assert_eq!(t.get("D1"), Value::Error(CellError::Value)); + assert_eq!(t.get("D2"), Value::Error(CellError::Value)); + assert_eq!(t.num("D3"), 3.0); + assert_eq!(t.num("D4"), 0.0); + assert_eq!(t.num("D5"), 6.0); +} + #[test] fn recalc_all_after_load() { let mut t = T::new();