GASでスプレッドシートのデータを
並べ替え(ソート)する方法

手作業の「データ › 範囲を並べ替え」をコードに置き換えます。Range.sort()での基本から、複数キー・ヘッダー固定・数値の落とし穴・自動化まで、動くコードで解説します。

|対象: GAS / スプレッドシート / 並べ替え

Table of Contents

なぜGASで並べ替えを自動化するのか

スプレッドシートの並べ替えはメニューからも実行できますが、データが増えるたびに手作業でやり直すのは非効率です。 GAS(Google Apps Script/スプレッドシートを操作できるGoogle公式のプログラム)で並べ替えをコード化すると、 次のような場面で効果を発揮します。

フォーム回答を新着順に

回答が追記されるたびに、タイムスタンプの新しい順へ自動で並べ替える

売上・在庫を金額順に

集計後の一覧を金額の降順にして、上位をひと目で確認できるようにする

名簿を部署・氏名順に

第1キーを部署、第2キーを氏名にして、見やすい順番に自動整列する

定期レポートの前処理

PDF化やメール送信の直前に並べ替えて、常に整った状態で出力する

Range.sortで基本の並べ替え

基本は、並べ替えたい範囲をgetRange()で取得し、sort()を呼ぶだけです。columnはシート上の絶対列番号(A列=1、B列=2…)、ascendingは昇順かどうかを表します。

function sortByColumnDesc() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("売上");
  const lastRow = sheet.getLastRow();
  const lastCol = sheet.getLastColumn();

  // ヘッダー行(1行目)を除いた2行目以降だけを対象にする
  const range = sheet.getRange(2, 1, lastRow - 1, lastCol);

  // C列(3列目)の降順で並べ替え
  range.sort({ column: 3, ascending: false });
}

ポイントは、対象範囲の開始行を2にしてヘッダー行(1行目)を除いていることです。シート全体を並べ替えるsheet.sort(3)も使えますが、こちらは見出し行も一緒に並べ替えてしまうため、表には向きません。

複数キー(第1キー・第2キー)で並べ替える

「まず担当者ごとにまとめ、その中で金額の高い順にしたい」といった並べ替えは、sort()に配列を渡して実現します。配列の先頭が第1キー、次が第2キーとして順に評価されます。

function sortByMultipleKeys() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("受注");
  const lastRow = sheet.getLastRow();
  const lastCol = sheet.getLastColumn();
  const range = sheet.getRange(2, 1, lastRow - 1, lastCol);

  // 第1キー: B列(担当者)を昇順
  // 第2キー: D列(金額)を降順
  range.sort([
    { column: 2, ascending: true },
    { column: 4, ascending: false },
  ]);
}

第1キーのB列で並べたうえで、B列の値が同じ行同士だけがD列の降順で並びます。 キーは3つ以上つなげることもできます。

空データでもエラーにしないガード

データ行が1行も無いシートに対してgetRange(2, 1, lastRow - 1, ...)を呼ぶと、行数が0になりエラーになります。ヘッダーだけの空シートやトリガー実行に備えて、行数のチェックを入れておくと安全です。

function safeSort() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("売上");
  const lastRow = sheet.getLastRow();

  // データ行(ヘッダー以外)が無いときは何もしない
  if (lastRow < 2) {
    Logger.log("並べ替える行がありません");
    return;
  }

  const lastCol = sheet.getLastColumn();
  sheet.getRange(2, 1, lastRow - 1, lastCol).sort({ column: 3, ascending: false });
}

数値と文字列が混ざる列の落とし穴

「金額のはずなのに並び順がおかしい」原因の多くは、セルに1,200円のような単位付き文字列や全角数字が混ざっていることです。 このときはgetValues()で値を取り出し、数値化してから並べ替えると狙い通りに揃います。

function sortByNumberSafely() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("在庫");
  const lastRow = sheet.getLastRow();
  const lastCol = sheet.getLastColumn();
  if (lastRow < 2) return;

  const range = sheet.getRange(2, 1, lastRow - 1, lastCol);
  const values = range.getValues();

  // C列(index 2)を数値として比較して並べ替え
  values.sort((a, b) => toNumber(b[2]) - toNumber(a[2])); // 降順

  range.setValues(values);
}

// "1,200円" や全角数字、空白入りの文字列も数値化する
function toNumber(value) {
  if (typeof value === "number") return value;
  const normalized = String(value)
    .replace(/[0-9]/g, (s) => String.fromCharCode(s.charCodeAt(0) - 0xfee0))
    .replace(/[^0-9.\-]/g, ""); // 数字・小数点・マイナス以外を除去
  const n = Number(normalized);
  return isNaN(n) ? -Infinity : n; // 数値化できない行は末尾へ
}

一番の対策は、そもそもセルに数値として入力しておくことです。表示形式で「円」を付けたい場合は、 値は数値のままsetNumberFormatで見た目だけ整えると、並べ替えもそのまま正しく動きます。

getValues+sortで柔軟に並べ替える

「五十音順にしたい」「独自の優先順位で並べたい」など、標準のsort()では表しにくい条件は、値を二次元配列として取り出し、JavaScriptのArray.sortで並べ替えてからsetValues()で書き戻します。日本語の並び順にはlocaleCompare(文字列を辞書順で比較するメソッド)が便利です。

function sortInMemory() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("会員");
  const lastRow = sheet.getLastRow();
  const lastCol = sheet.getLastColumn();
  if (lastRow < 2) return;

  const range = sheet.getRange(2, 1, lastRow - 1, lastCol);
  const rows = range.getValues();

  // 第1キー: B列(部署)を五十音・アルファベット順
  // 第2キー: A列(氏名)を昇順
  rows.sort((a, b) => {
    const byDept = String(a[1]).localeCompare(String(b[1]), "ja");
    if (byDept !== 0) return byDept;
    return String(a[0]).localeCompare(String(b[0]), "ja");
  });

  range.setValues(rows); // 並べ替え後の配列を一括で書き戻す
}

この方式は読み書きが各1回で済むため速く、比較ロジックを自由に書ける利点があります。 一方で数式や書式は書き戻しの対象外なので、値だけの表に向いています。

トリガーで並べ替えを自動化する

並べ替えを手作業から解放するには、トリガー(特定のタイミングで関数を自動実行する仕組み)と組み合わせます。 フォーム回答が追記されるシートなら、フォーム送信トリガーで送信直後に並べ替えるのが自然です。

// フォーム送信のたびに自動で並べ替えるトリガーを1回だけ登録する
function createSortTrigger() {
  const ss = SpreadsheetApp.getActive();
  ScriptApp.newTrigger("onFormSubmitSort")
    .forSpreadsheet(ss)
    .onFormSubmit()
    .create();
}

function onFormSubmitSort() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("フォームの回答 1");
  const lastRow = sheet.getLastRow();
  if (lastRow < 2) return;
  const lastCol = sheet.getLastColumn();

  // A列(タイムスタンプ)の新しい順に並べ替え
  sheet.getRange(2, 1, lastRow - 1, lastCol).sort({ column: 1, ascending: false });
}

毎朝決まった時刻に整列させたいだけなら、timeBased().everyDays(1).atHour(8)の時間主導トリガーでも構いません。編集のたびに並べ替えたい場合はonEditを使いますが、実行回数が増えるので対象シートを限定するのがおすすめです。

実務での注意点

1. 並べ替えは元に戻せない

コードでの並べ替えは、手動操作の「元に戻す」が効きません。元の入力順を残したい場合は、通し番号の列を用意しておくと、いつでも元の並びに戻せます。

2. 結合セルがあると失敗する

並べ替え範囲内にセルの結合があると、sort()はエラーになります。データ行の結合は避け、装飾はヘッダー行だけに留めましょう。

3. onEditトリガー内で重い処理をしない

編集のたびに走るonEditで大きな表を毎回並べ替えると、操作が重くなります。対象シートや対象列を絞り込み、必要なときだけ実行する条件を入れておくと快適です。

まとめ

GASでの並べ替えは、ヘッダーを除いた範囲に対するRange.sort()が基本です。複数キーは配列で、複雑な条件はgetValues+Array.sort+setValuesで対応できます。数値の落とし穴と空データのガードに気をつけ、トリガーと組み合わせれば、 人手を介さずに常に整った表を保てます。

よくある質問

並べ替えたい範囲を getRange() で取得し、sort() を呼ぶだけです。例えば sheet.getRange(2, 1, lastRow - 1, lastCol).sort({ column: 3, ascending: false }) と書くと、2行目以降をC列の降順で並べ替えます。columnはシート上の絶対列番号(A列=1)で指定します。

sort() の対象範囲からヘッダー行を外すのがポイントです。getRange(2, 1, ...) のように開始行を2にして、データ行だけを範囲に含めます。シート全体を対象にする sheet.sort() はヘッダーも巻き込むため、見出し付きの表には向きません。

できます。sort() に配列を渡すと、先頭の条件が第1キー、次が第2キーになります。例えば [{ column: 2, ascending: true }, { column: 4, ascending: false }] とすると、まずB列の昇順、B列が同じ行同士はD列の降順で並びます。

セルに数値と文字列(「1,000円」など単位付きの文字列や、先頭の空白)が混ざっていると、意図通りに並ばないことがあります。入力時に数値として保存されているかを確認し、必要なら getValues() で取り出して Number() で数値化してから並べ替えます。

時間主導トリガー(ScriptApp.newTrigger)で並べ替え関数を定期実行するか、onEdit トリガーで編集のたびに並べ替える方法があります。フォーム回答が追記されるシートなら、フォーム送信トリガーで送信直後に並べ替えるのが自然です。

GAS開発・業務Webシステムを
相談する。

並べ替え以外にも、集計・帳票出力・フォーム連携・Gmail自動化など、日々の表計算業務を自動化するGAS開発をご相談いただけます。

GAS Webシステム開発を見る