GASでスプレッドシートのデータを
並べ替え(ソート)する方法
手作業の「データ › 範囲を並べ替え」をコードに置き換えます。Range.sort()での基本から、複数キー・ヘッダー固定・数値の落とし穴・自動化まで、動くコードで解説します。
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開発をご相談いただけます。