Recipe
Remove duplicate rows from Google Sheets automatically
Keeps the first row for each key and deletes later copies. Choose which columns define a duplicate, and whether case matters.
Set it up
- Paste the script and set sheetName and keyCols in RD. keyCols [1] means column A.
- Make a copy of your sheet first. The script rewrites the data range.
- Run removeDuplicates. Optionally add a daily trigger.
The script
/**
* Remove duplicate rows from a sheet, keeping the first one.
* KEY_COLS lists the columns (1-based) that define a duplicate.
* Run removeDuplicates from the editor or a trigger.
*/
var RD = { sheetName: 'Sheet1', keyCols: [1], headerRows: 1, ignoreCase: true };
function removeDuplicates() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(RD.sheetName);
var values = sheet.getDataRange().getValues();
var seen = {};
var keep = values.slice(0, RD.headerRows);
for (var i = RD.headerRows; i < values.length; i++) {
var key = RD.keyCols.map(function (c) {
var v = String(values[i][c - 1]).trim();
return RD.ignoreCase ? v.toLowerCase() : v;
}).join('\u0001');
if (seen[key]) continue;
seen[key] = true;
keep.push(values[i]);
}
var removed = values.length - keep.length;
if (removed === 0) return 0;
sheet.getRange(1, 1, values.length, values[0].length).clearContent();
sheet.getRange(1, 1, keep.length, keep[0].length).setValues(keep);
return removed;
}What you should see
| Plan | |
|---|---|
| ana@example.com | Pro |
| ben@example.com | Free |
| cy@example.com | Free |
Before: 5 rows. After: 3 rows, order kept. Sample values, not output from a real account.
Common errors and fixes
- Formulas turned into values
- The script rewrites values. Keep formulas outside the data range, or use the built-in Data > Data cleanup > Remove duplicates for one-off jobs.
- Rows that look equal stay
- Extra spaces and case are trimmed, but different characters (for example a non-breaking space) are not.
- Exceeded maximum execution time
- Very large sheets need batching. See the fix page.
Permissions. Running this script asks you to grant Google permissions for the services listed above, to your own script. TriggerShelf never receives your Google data. See the permissions table. Google will show "Google hasn't verified this app"; that is expected for a script you paste yourself.
TriggerShelf is independent and not affiliated with or endorsed by Google LLC. Google Sheets, Gmail, Google Drive and Apps Script are trademarks of Google LLC. Quota figures come from Google's Apps Script quotas page. Test on a copy first.