diff --git a/crates/engine/src/cmd/data.rs b/crates/engine/src/cmd/data.rs index 7f8467e8a..38bece3bc 100644 --- a/crates/engine/src/cmd/data.rs +++ b/crates/engine/src/cmd/data.rs @@ -580,6 +580,9 @@ fn remove_duplicates(s: &mut Session, p: &Json) -> Result { let r = data_range(s, p)?; let d = s.doc()?; let sh = d.wb.active().ok_or(EngineError::NoDocument)?; + // Rows and columns past the data are blank: only the part with data is compared (whole + // columns compared a million blank rows and reported them as removed duplicates). + let r = sh.used_range().and_then(|u| r.intersection(&u)).unwrap_or(RangeRef::cell(r.start)); let header = bool_param(p, "header").unwrap_or_else(|| guess_header(&d.wb, sh, r)); let cols: Vec = p .get("columns") diff --git a/crates/engine/src/tests.rs b/crates/engine/src/tests.rs index 9d0c7189f..e673485fb 100644 --- a/crates/engine/src/tests.rs +++ b/crates/engine/src/tests.rs @@ -181,6 +181,10 @@ fn whole_sheet_selection_stays_within_the_data() { s.execute("edit.fillUp", json!({})).unwrap(); assert_eq!(v(&s, "A1"), Value::Number(5.0)); assert!(s.execute("edit.fillDown", json!({"range": "A1:Z1000000"})).is_err(), "too large to fill"); + s.execute("range.setValues", json!({"range": "D1", "values": [[1], [1], [2]]})).unwrap(); + let r = s.execute("data.removeDuplicates", json!({"range": "D:D", "header": false})).unwrap(); + assert_eq!((r["removed"].clone(), r["remaining"].clone()), (json!(1), json!(2))); + assert!(s.execute("data.removeDuplicates", json!({"range": "A1:XFD1048576", "header": false})).is_ok()); } #[test]