GASでスプレッドシートの行・列を
グループ化して折りたたむ方法

明細の多い集計表を「折りたたみボタン」で開閉できるようにするグループ化(アウトライン)を、shiftRowGroupDepthなどのコードで自動設定する方法を解説します。カテゴリ別の自動グループ化まで実装します。

|対象: GAS / スプレッドシート / グループ化

Table of Contents

行・列のグループ化(アウトライン)とは

グループ化(アウトライン)とは、複数の行や列をひとまとまりにして、 シート左端・上端のボタンで「折りたたみ・展開」できるようにする機能です。 明細を隠して小計だけを見せたり、必要なときだけ詳細を開いたりできます。

手作業でも設定できますが、毎月シートを作り直す帳票や、明細行が増減するレポートでは、 GAS(Google Apps Script。Googleサービスを自動化できるプログラミング環境)でコードから設定すると手間がなくなります。 グループ化は表示上の整理で、セルの値や数式は変わりません。

明細の折りたたみ

取引明細をたたんで小計・合計だけを一覧できるようにする

カテゴリ別の整理

部署別・商品カテゴリ別など、ブロックごとに開閉できるようにする

作業用の列を隠す

計算過程やメモの列をグループ化し、普段は折りたたんでおく

月次レポートの自動整形

毎月コピーするテンプレートに、グループ設定まで自動で付ける

行をグループ化する基本コード

行のグループ化は、グループにしたい行を含むRangeを取得し、shiftRowGroupDepth(1)(グループの深さを1段上げるメソッド)を呼ぶだけです。"2:10"のように書くと、その行全体を指定できます。

function groupRows() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("売上");

  // 2行目から10行目(9行分)をひとつのグループにする
  // "2:10" は行全体を指すA1表記
  sheet.getRange("2:10").shiftRowGroupDepth(1);
}

実行すると、2〜10行目が1つのグループになり、シート左端に折りたたみボタン(マイナスのアイコン)が表示されます。

グループを入れ子(多階層)にする

大きなグループの中に、さらに小さなグループを作る「入れ子」も可能です。 大きい範囲をグループ化してから、その一部にもう一度shiftRowGroupDepth(1)を呼ぶと、階層が1段深くなります。深さはgetRowGroupDepthで確認できます。

function groupRowsNested() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("売上");

  // 大グループ: 2〜11行目
  sheet.getRange("2:11").shiftRowGroupDepth(1);

  // その中の小グループ: 3〜6行目(もう1段深くする)
  sheet.getRange("3:6").shiftRowGroupDepth(1);

  // 何段目のグループに属するかを確認
  Logger.log(sheet.getRowGroupDepth(4)); // → 2
}

グループを折りたたむ・展開する

作ったグループはコードから開閉できます。シート全体をまとめて操作するならcollapseAllRowGroupsexpandAllRowGroupsを使います。特定のグループだけ動かしたいときはgetRowGroup(行番号, 深さ)でグループを取得し、collapse()/expand()を呼びます。

// シート全体のグループをまとめて折りたたむ/展開する
function collapseAllRows() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("売上");
  sheet.collapseAllRowGroups();
}

function expandAllRows() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("売上");
  sheet.expandAllRowGroups();
}

// 特定の1グループだけ折りたたむ
function collapseOneGroup() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("売上");

  // 「3行目を含む、深さ1のグループ」を取得
  const group = sheet.getRowGroup(3, 1);
  group.collapse();          // 折りたたむ(expand()で展開)
}

列をグループ化する

列のグループ化は、行のshiftRowGroupDepthに対してshiftColumnGroupDepthを使います。対象の列をすべて含む範囲をgetRangeで取得して呼び出すと、シート上端に折りたたみボタンが付きます。

function groupColumns() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("売上");

  // C〜E列(3列目から3列分)をグループ化する
  // 行数はシート全体(getMaxRows)を指定
  sheet.getRange(1, 3, sheet.getMaxRows(), 3).shiftColumnGroupDepth(1);

  // まとめて開閉するメソッドも用意されている
  sheet.collapseAllColumnGroups();  // 全列グループを折りたたむ
  sheet.expandAllColumnGroups();    // 全列グループを展開する
}

折りたたみボタンの位置を変える

折りたたみボタンは既定でグループの「上側」に表示されます。 小計・合計をグループの下にまとめるレイアウトのときは、setRowGroupControlAfter(true)でボタンを「下側」に移すと、ボタンと小計行の位置が揃って見やすくなります。

function setControlPosition() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("売上");

  // 折りたたみボタンをグループの「下側」に表示する
  // 小計・合計をグループの下にまとめるレイアウト向き
  sheet.setRowGroupControlAfter(true);

  // 現在の設定を確認(true = 後ろ側 / false = 前側)
  Logger.log(sheet.getRowGroupControlPosition());
}

カテゴリ別に自動でグループ化する

実務でよくあるのは「A列のカテゴリが同じ行をブロックごとにグループ化したい」というケースです。 カテゴリ列で並べ替えたデータを一括取得し、値が切り替わるところをブロックの境目として、 各ブロックにshiftRowGroupDepth(1)を適用します。

// A列のカテゴリが同じ行を、カテゴリごとに自動でグループ化する
// (事前にカテゴリ列で並べ替えておくこと)
function autoGroupByCategory() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("売上");
  const lastRow = sheet.getLastRow();
  if (lastRow < 3) return;

  // 2行目以降のA列(カテゴリ)を一括取得
  const categories = sheet
    .getRange(2, 1, lastRow - 1, 1)
    .getValues()
    .map((row) => row[0]);

  clearRowGroups(sheet); // 既存グループをいったんリセット

  let blockStart = 0; // categories配列上のブロック先頭インデックス
  for (let i = 1; i <= categories.length; i++) {
    const isBoundary =
      i === categories.length || categories[i] !== categories[blockStart];

    if (isBoundary) {
      const startRow = blockStart + 2; // 実際の行番号(ヘッダー分+1)
      const count = i - blockStart;    // 同じカテゴリの行数
      if (count >= 1) {
        sheet.getRange(startRow, 1, count, 1).shiftRowGroupDepth(1);
      }
      blockStart = i;
    }
  }
}

作り直すたびにグループが二重にならないよう、実行の最初に既存グループをすべて解除しておくのがポイントです。 その解除用の関数clearRowGroupsは次のセクションで示します。

グループ化の解除と注意点

グループ化を解除するには、shiftRowGroupDepth(-1)のようにマイナスの値を渡します。深さの数だけ戻せば、その行のグループを完全に外せます。 シート全体のグループを一掃するヘルパー関数を用意しておくと、作り直し処理が安定します。

// シート内の行グループをすべて解除する
function clearRowGroups(sheet) {
  const maxRows = sheet.getMaxRows();
  for (let row = 1; row <= maxRows; row++) {
    const depth = sheet.getRowGroupDepth(row);
    if (depth > 0) {
      // 深さの数だけまとめて解除する
      sheet.getRange(row, 1, 1, 1).shiftRowGroupDepth(-depth);
    }
  }
}

// 範囲を指定して1段だけ解除する例
function ungroupRange() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("売上");
  sheet.getRange("3:6").shiftRowGroupDepth(-1);
}

1. 範囲は「行全体」を指定する

行グループは行単位で決まります。列を1つだけ含む範囲でもグループ化はできますが、 対象行がすべて範囲に含まれているかを基準に考えると間違いが減ります。

2. 自動グループ化の前に並べ替えておく

カテゴリ別の自動グループ化は「同じカテゴリが連続して並んでいる」ことが前提です。 並んでいないと、同じカテゴリでも別々のグループに分かれます。事前の並べ替えとセットで使いましょう。

3. 折りたたみ状態は共有相手にも反映される

グループの開閉はシート自体の状態として保存されます。共有しているシートで折りたたむと、 他の閲覧者にも同じ状態で見えます。用途に応じて、既定は展開のままにしておくのが無難です。

まとめ

GASでのグループ化は、shiftRowGroupDepth/shiftColumnGroupDepthでまとめ、collapse/expandで開閉するのが基本です。カテゴリ別の自動グループ化と組み合わせれば、 明細の多い集計表やレポートを、毎回きれいに折りたためる形で自動生成できます。

よくある質問

Rangeのメソッド shiftRowGroupDepth(1) を使います。グループ化したい行を含む範囲を取得し、shiftRowGroupDepth(1) を呼ぶとその行がひとまとまりのグループ(アウトライン)になり、左端に折りたたみ用のボタンが表示されます。引数に -1 を渡すと1段解除できます。

シート全体をまとめて操作するなら sheet.collapseAllRowGroups() で全折りたたみ、sheet.expandAllRowGroups() で全展開ができます。特定のグループだけ動かしたいときは sheet.getRowGroup(行番号, 深さ) でGroupオブジェクトを取得し、collapse() や expand() を呼びます。

できます。行の shiftRowGroupDepth に対して、列は shiftColumnGroupDepth(1) を使います。対象の列をすべて含む範囲を getRange で取得して呼び出すと、上端に列用の折りたたみボタンが表示されます。解除は同じく -1 を渡します。

sheet.setRowGroupControlAfter(true) を呼ぶと、折りたたみボタンがグループの後ろ(下)側に表示されます。合計・小計をグループの下にまとめるレイアウトのときに、ボタンと小計行の位置が揃って見やすくなります。既定は false(グループの上側)です。

グループ化は行・列の見た目(表示・非表示のまとまり)を制御する機能で、セルの値や数式そのものは変更しません。折りたたんでも非表示になるだけでデータは残り、集計関数の対象にも含まれます。表示上の整理と実データは分けて考えられます。

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

グループ化以外にも、集計表の自動生成・帳票出力・Gmail自動化など、日々の業務を自動化するGAS開発をご相談いただけます。

GAS Webシステム開発を見る