GASでスプレッドシートに
ピボットテーブルをコードで自動作成する方法

ピボットテーブル(集計元データを行・列・値で集計し直す表)を、手作業ではなくcreatePivotTableでコードから自動生成する方法を、動くコードで解説します。定期トリガーと組み合わせれば、毎朝最新の集計表が用意できます。

|対象: GAS / スプレッドシート / ピボットテーブル

Table of Contents

ピボットテーブルをコードで作るメリット

ピボットテーブルとは、生データを「行の項目」「列の項目」「集計する値」の3つで自動集計し直す表のことです。 メニューから手作業でも作れますが、GASでコード化すると次のメリットがあります。

毎回同じ集計を再現できる

行・列・集計方法をコードで固定するので、担当者が変わっても同じ表が作れる

定期トリガーで自動更新

毎朝や月初にピボットを作り直し、常に最新の集計を用意できる

複数シート・複数ブックに一括適用

同じ集計ロジックを店舗別・部署別のシートへまとめて展開できる

他の自動化とつなげられる

集計結果をグラフ化・PDF化・メール送信・AI分析へそのまま渡せる

最小コード:行と値だけのピボット

ピボット作成の中心はRange.createPivotTable(集計元の範囲)です。ピボットを置きたいセルを起点にして呼び出します。あとは行の項目をaddRowGroupで、集計する値をaddPivotValueで指定するだけです。

function createSalesPivot() {
  const ss = SpreadsheetApp.getActive();
  const source = ss.getSheetByName("売上データ");

  // 集計元の範囲(1行目に見出しがある想定)
  // 例: A=日付 / B=月 / C=商品カテゴリ / D=地域 / E=売上金額
  const sourceRange = source.getDataRange();

  // ピボットを置くシートを用意(無ければ作る)
  const pivotSheet =
    ss.getSheetByName("集計") || ss.insertSheet("集計");

  // A1セルを起点にピボットテーブルを作成
  const pivotTable = pivotSheet.getRange("A1").createPivotTable(sourceRange);

  // 行に「商品カテゴリ」(C列=3列目)を並べる
  pivotTable.addRowGroup(3);

  // 値に「売上金額」(E列=5列目)の合計を集計する
  pivotTable.addPivotValue(5, SpreadsheetApp.PivotTableSummarizeFunction.SUM);
}

ポイントは、addRowGroup(3)3が「集計元データのC列(3列目)」を指すこと。範囲内での相対位置ではなく、シート上の列番号(1始まり)を渡します。

行×列のクロス集計をつくる

「商品カテゴリごと × 月ごと」のように縦横で集計したいときは、addColumnGroupを追加します。行に置いた項目が縦に、列に置いた項目が横に並び、交差するマスに集計値が入ります。

function createCrossPivot() {
  const ss = SpreadsheetApp.getActive();
  const sourceRange = ss.getSheetByName("売上データ").getDataRange();

  const pivotSheet =
    ss.getSheetByName("集計") || ss.insertSheet("集計");
  const pivotTable = pivotSheet.getRange("A1").createPivotTable(sourceRange);

  // 行: 商品カテゴリ(C列=3列目)
  pivotTable.addRowGroup(3);
  // 列: 月(B列=2列目)→ 横方向に月が並ぶ
  pivotTable.addColumnGroup(2);
  // 値: 売上金額(E列=5列目)の合計
  pivotTable.addPivotValue(5, SpreadsheetApp.PivotTableSummarizeFunction.SUM);
}

行・列ともに複数の項目を重ねられます。例えばaddRowGroupを2回呼べば、大分類→小分類の入れ子で集計できます。

集計方法(合計・件数・平均)を切り替える

集計方法はSpreadsheetApp.PivotTableSummarizeFunctionの値で決めます。SUM(合計)・COUNTA(件数)・AVERAGE(平均)などが使えます。

// 件数を数える(空でないセルの数)
pivotTable.addPivotValue(1, SpreadsheetApp.PivotTableSummarizeFunction.COUNTA);

// 平均を出す
pivotTable.addPivotValue(5, SpreadsheetApp.PivotTableSummarizeFunction.AVERAGE);

// 最大・最小
pivotTable.addPivotValue(5, SpreadsheetApp.PivotTableSummarizeFunction.MAX);
pivotTable.addPivotValue(5, SpreadsheetApp.PivotTableSummarizeFunction.MIN);

// addPivotValue は何度でも呼べる。呼んだ数だけ集計列が増える
// 例: 合計と件数を並べて表示する
pivotTable.addPivotValue(5, SpreadsheetApp.PivotTableSummarizeFunction.SUM);
pivotTable.addPivotValue(5, SpreadsheetApp.PivotTableSummarizeFunction.COUNTA);

ほかにもCOUNTUNIQUE(重複を除いた件数)・MEDIAN(中央値)・MAX /MINなどが用意されています。

フィルタで対象データを絞り込む

特定の地域や区分だけを集計したいときはaddFilterを使います。フィルタ条件はnewFilterCriteriaで作り、setHiddenValuesに「隠したい値」を渡します。残したい値ではなく、除外したい値を指定する点に注意してください。

function createFilteredPivot() {
  const ss = SpreadsheetApp.getActive();
  const sourceRange = ss.getSheetByName("売上データ").getDataRange();

  const pivotSheet =
    ss.getSheetByName("集計") || ss.insertSheet("集計");
  const pivotTable = pivotSheet.getRange("A1").createPivotTable(sourceRange);

  pivotTable.addRowGroup(3);
  pivotTable.addPivotValue(5, SpreadsheetApp.PivotTableSummarizeFunction.SUM);

  // D列(地域=4列目)で「東京」だけを残す=それ以外を非表示にする
  const criteria = SpreadsheetApp.newFilterCriteria()
    .setHiddenValues(["大阪", "名古屋", "福岡"])
    .build();
  pivotTable.addFilter(4, criteria);
}

作り直しで重複させない「削除→再作成」

スクリプトを再実行するたびに新しいピボットが積み重なると、集計シートがぐちゃぐちゃになります。 作成前にgetPivotTables()で既存のピボットを取得し、remove()で消してから作り直すのが鉄則です。定期トリガーと組み合わせれば、毎朝きれいな最新集計が用意できます。

function rebuildPivot() {
  const ss = SpreadsheetApp.getActive();
  const pivotSheet = ss.getSheetByName("集計");
  if (!pivotSheet) return;

  // 既存のピボットテーブルをすべて削除してから作り直す
  pivotSheet.getPivotTables().forEach((pt) => pt.remove());

  const sourceRange = ss.getSheetByName("売上データ").getDataRange();
  const pivotTable = pivotSheet.getRange("A1").createPivotTable(sourceRange);
  pivotTable.addRowGroup(3);
  pivotTable.addColumnGroup(2);
  pivotTable.addPivotValue(5, SpreadsheetApp.PivotTableSummarizeFunction.SUM);
}

// 毎日 早朝6時に集計を作り直すトリガーを1回だけ登録する
function createDailyPivotTrigger() {
  ScriptApp.newTrigger("rebuildPivot")
    .timeBased()
    .everyDays(1)
    .atHour(6)
    .create();
}

実務での注意点

1. 列番号は「集計元シートの列」で数える

addRowGroup・addColumnGroup・addPivotValue・addFilterに渡す数値は、集計元データのシート上の列番号(A=1、B=2…)です。 ヘッダーの見出し文字ではなく数値で指定するため、列の並びを変えたら番号も見直す必要があります。

2. 集計元と出力先は別シートにする

ピボットは指定セルから右下に広がります。生データと同じシートに置くと元データを上書きする恐れがあるため、 専用の「集計」シートを分けるのが安全です。

3. 元データの範囲が増えるなら作り直す

getDataRange()で範囲を取れば、実行時点のデータ量に合わせて集計されます。ただし作成後にデータが増えた分は自動では反映されません。 行が増え続けるシートでは、トリガーで定期的に作り直す運用が確実です。

まとめ

GASのピボットテーブルは、createPivotTableで作り、addRowGroup /addColumnGroup /addPivotValueの3つで組み立てるのが基本です。フィルタで対象を絞り、「削除→再作成」で重複を防ぎ、定期トリガーで自動化すれば、 手作業ゼロで最新の集計表を保てます。集計後はグラフ化やAI分析へつなげて、レポート作成全体を自動化していきましょう。

よくある質問

置きたいセルを起点に range.createPivotTable(集計元の範囲) でピボットテーブルを作り、addRowGroup(列番号) で行の項目を、addPivotValue(列番号, 集計関数) で集計する値を指定するだけです。行と値を1つずつ指定すれば、最小構成のピボットが完成します。

集計元データのシートの列番号(1始まり)です。A列が1、B列が2、C列が3と数えます。範囲内での相対位置ではなくシート上の絶対的な列番号を渡す点に注意してください。ヘッダー行の見出しではなく数値で指定します。

addPivotValue の第2引数を変えるだけです。SpreadsheetApp.PivotTableSummarizeFunction.SUM が合計、COUNTA が件数、AVERAGE が平均です。ほかに MAX・MIN・COUNTUNIQUE・MEDIAN なども用意されています。

作成前に sheet.getPivotTables() で既存のピボットを取得し、forEach で remove() してから作り直すと重複しません。データ更新のたびに「消してから作る」パターンにしておくと、常に最新の集計だけが残ります。

ピボットテーブル自体は集計元データの変更に追従して更新されます。ただし元データの範囲(行数)が増えた場合は作り直しが安全です。時間主導トリガーで毎日ピボットを作り直すようにしておけば、範囲の広がりにも自動で対応できます。

集計・レポート業務を
自動化する。

ピボット集計だけでなく、グラフ化・PDF出力・定期メール配信・AIによる分析コメントまで、 日々のレポート作成を丸ごと自動化するGAS開発をご相談いただけます。

AI×GAS自動化を見る