// Sheets · Apps Script

Automatically sort a sheet on edit in Google Sheets.

Use an Apps Script onEdit trigger to sort a named range automatically whenever data changes, with a column guard that keeps the header row in place.

I want my Google Sheet to re-sort itself the moment I change a cell, without me having to click Data > Sort every time.

The script

copy · paste · trigger
autoSort.gs
Apps Script
// Sorts A2:D when column B is edited.
// Adjust SORT_SHEET, SORT_COL, and DATA_RANGE to match your sheet.
const SORT_SHEET = 'Inventory';
const WATCH_COL  = 2;  // column B triggers a re-sort
const SORT_COL   = 2;  // sort by column B (1-indexed within range)
const DATA_RANGE = 'A2:D';
const ASCENDING  = true;

function onEdit(e) {
  const sheet = e.range.getSheet();
  if (sheet.getName() !== SORT_SHEET) return;
  if (e.range.getColumn() !== WATCH_COL) return;

  const range = sheet.getRange(DATA_RANGE);
  range.sort({ column: SORT_COL, ascending: ASCENDING });
}

Need a variant? Gnaw writes a custom version from one sentence — fields, triggers, edge cases handled.

Walkthrough

Why A2 and not A1

The range string 'A2:D' is the most load-bearing part of this script. If you pass 'A1:D', the sort treats row 1 as a data row, not a header, and on the first matching edit your column labels get shuffled into the middle of the data. Starting at row 2 keeps the header anchored outside the range the sort can touch.

The first time I hit this it was subtle: the sort ran cleanly for two edits, then on the third a new row happened to sort above row 1 and the header disappeared. Setting DATA_RANGE to start at row 2 is the fix, not a defensive check inside the function.

Guarding the watched column

Without the WATCH_COL guard, onEdit fires on every single keystroke anywhere in the sheet. Sorting on every edit is wasteful and creates visible flicker when a user is mid-entry in an unrelated column. The guard checks e.range.getColumn() against the column whose values determine sort order, so the re-sort only fires when the sorted column actually changes.

Note that e.range.getColumn() returns the leftmost column of the edited range, so if a user pastes a multi-column block this still triggers correctly as long as column B is included. For paste operations that land entirely outside WATCH_COL, it silently returns early — which is exactly what you want.

Installing the trigger and the one permission it needs

Open Extensions > Apps Script, paste the code, save, and run onEdit once manually. Sheets will prompt for the 'See, edit, create, and delete your spreadsheets' OAuth scope. This scope is required because getRange and sort are write operations, even though onEdit itself is a simple trigger.

Simple triggers (the built-in onEdit function name) do not need an installable trigger setup in the Triggers panel. They fire automatically on any edit by any collaborator who has edit access to the sheet. If you rename the function to something other than onEdit, it becomes an orphaned function that never fires — keep the name exact.

Want a custom version?

Describe your sheet and the rule you want. Gnaw writes the Apps Script — fields, triggers, edge cases — in one shot.

FAQ

4 questions
Why does my header row keep getting sorted into the data?
Your DATA_RANGE is starting at row 1. Change it to 'A2:D' (or whichever row your data starts on) so the sort range never includes the header.
Can I sort by a column that is not the one being edited?
Yes. Set WATCH_COL to the column that triggers the sort (the one the user edits) and SORT_COL to a different column index. They can be different values. SORT_COL is 1-indexed relative to the start of DATA_RANGE, so if your range is 'A2:D' and you want to sort by column C, SORT_COL is 3.
The sort runs but it is slow and the sheet flickers. Is that normal?
It is normal for large ranges. range.sort() is a synchronous Sheets API call and on ranges over a few hundred rows you will see a brief re-render. There is no async option in Apps Script for this. The practical fix is to narrow DATA_RANGE to only the columns you actually need sorted rather than an open-ended range.
Does this work when someone else edits the shared sheet?
Yes, simple triggers fire for any collaborator who has edit access. The script runs under the account of the user doing the edit, so that user must also have edit access to the spreadsheet for the sort to succeed.
// one good script a week

Get a working Apps Script snippet in your inbox, weekly.