スプレッドシートの定期レポートをGASで自動化する3つの実例
毎週のレポート作成に何時間使っていますか?
「月曜の朝、スプレッドシートを開いて先週のデータを集計し、表を作って、メールで送る」——この一連の作業、毎週やっていませんか?
私もそうでした。週次レポートの作成に毎回30分。月に4回で2時間。年間だと24時間。丸1日分の労働を、単純なデータ転記に使っていたのです。
この記事では、Google Apps Script(GAS)を使ってスプレッドシートの定期レポートを完全自動化した3つの実例を紹介します。どれも実際に使っているコードで、コピペして始められます。
実例1:週次売上サマリーを自動でメール送信
やりたいこと
毎週月曜の朝9時、先週のスプレッドシートから売上データを集計し、サマリーをメールで送信する。
コード
function sendWeeklyReport() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('売上データ');
const data = sheet.getDataRange().getValues();
// 先週のデータだけを抽出
const today = new Date();
const oneWeekAgo = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);
let totalSales = 0;
let count = 0;
for (let i = 1; i < data.length; i++) {
const date = new Date(data[i][0]);
if (date >= oneWeekAgo && date < today) {
totalSales += Number(data[i][2]); // C列が売上額
count++;
}
}
const avgSales = count > 0 ? Math.round(totalSales / count) : 0;
// メール送信
const subject = `【週次レポート】${oneWeekAgo.getMonth()+1}月${oneWeekAgo.getDate()}日〜${today.getMonth()+1}月${today.getDate()}日`;
const body = `
先週の売上サマリーです。
■ 件数: ${count}件
■ 合計: ${totalSales.toLocaleString()}円
■ 平均: ${avgSales.toLocaleString()}円/件
詳細はスプレッドシートをご確認ください。
${SpreadsheetApp.getActiveSpreadsheet().getUrl()}
`;
MailApp.sendEmail('team@example.com', subject, body);
}
トリガー設定
スクリプトエディタの「トリガー」(時計アイコン)から:
- 実行する関数:
sendWeeklyReport - イベントのソース: 時間主導型
- 頻度: 週ベース
- 実行日: 月曜日
- 実行時間: 午前9時
これで毎週月曜の9時に自動実行されます。
実例2:日次の進捗サマリーをSlack風フォーマットで送信
やりたいこと
毎日夕方18時、その日のタスク完了状況をスプレッドシートから集計し、チャットツールに送信する形式のレポートを作る。
コード
function sendDailyProgress() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('タスク管理');
const data = sheet.getDataRange().getValues();
const today = new Date();
today.setHours(0, 0, 0, 0);
let completed = [];
let inProgress = [];
for (let i = 1; i < data.length; i++) {
const date = new Date(data[i][0]);
const task = data[i][1];
const status = data[i][2];
if (date.getTime() === today.getTime()) {
if (status === '完了') {
completed.push(task);
} else if (status === '進行中') {
inProgress.push(task);
}
}
}
// フォーマット作成
let report = `📊 本日の進捗(${today.getMonth()+1}月${today.getDate()}日)\n\n`;
report += `✅ 完了: ${completed.length}件\n`;
completed.forEach(t => report += ` ・${t}\n`);
report += `\n🔄 進行中: ${inProgress.length}件\n`;
inProgress.forEach(t => report += ` ・${t}\n`);
// メール送信(SlackのIncoming Webhookにも転送可能)
MailApp.sendEmail('team@example.com', `進捗レポート ${today.getMonth()+1}/${today.getDate()}`, report);
}
ポイント
MailApp.sendEmail()の代わりにUrlFetchApp.fetch()を使えば、SlackのIncoming Webhook URLに直接POSTできます。チャットツールへの自動通知が完成します。
実例3:月次の複数シート集計を1つのレポートに統合
やりたいこと
月末に、スプレッドシート内の複数シート(営業、経費、採用)からデータを集計し、1つの月次サマリーシートに統合する。
コード
function generateMonthlySummary() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
// 集計対象のシートと列定義
const targets = [
{ sheet: '営業', col: 2, label: '売上' },
{ sheet: '経費', col: 3, label: '経費' },
{ sheet: '採用', col: 4, label: '採用数' }
];
// 月次サマリーシートを取得(なければ作成)
let summarySheet = ss.getSheetByName('月次サマリー');
if (!summarySheet) {
summarySheet = ss.insertSheet('月次サマリー');
}
const today = new Date();
const month = today.getFullYear() + '年' + (today.getMonth() + 1) + '月';
// ヘッダー
summarySheet.clear();
summarySheet.getRange('A1').setValue('月次サマリー: ' + month);
summarySheet.getRange('A3').setValue('項目');
summarySheet.getRange('B3').setValue('合計');
let row = 4;
for (const t of targets) {
const sheet = ss.getSheetByName(t.sheet);
if (!sheet) continue;
const data = sheet.getDataRange().getValues();
let total = 0;
for (let i = 1; i < data.length; i++) {
const val = Number(data[i][t.col]);
if (!isNaN(val)) total += val;
}
summarySheet.getRange(row, 1).setValue(t.label);
summarySheet.getRange(row, 2).setValue(total);
row++;
}
// 完了通知
MailApp.sendEmail('boss@example.com',
'月次サマリー生成完了',
`${month}の月次サマリーを生成しました。\n${ss.getUrl()}`
);
}
3つの実例に共通するパターン
どの実例も、以下のパターンで構成されています。
- getDataRange().getValues() でシート全体を読み込む
- forループ で条件に合うデータだけ抽出する
- 集計処理(合計、平均、件数など)を行う
- MailApp.sendEmail() で結果を送信する
- トリガー で定時実行を設定する
この5ステップを覚えれば、スプレッドシートのあらゆる定期レポートを自動化できます。
つまずきやすいポイント
トリガーが動かない
トリガーを設定したのにメールが届かない場合、以下を確認してください。
- トリガーの実行ログ: スクリプトエディタの「実行トランスクリプト」を確認
- 権限エラー: 初回実行時は手動で1回実行し、権限承認を行う
- 時間設定: 「時間主導型」トリガーは指定時刻の前後で実行される(厳密な時刻ではない)
getValues()の型に注意
getValues()は日付をDateオブジェクトで返します。数値として扱いたい場合はNumber()で明示的に変換してください。文字列として比較したい場合はString()を使います。
メール送信の制限
MailApp.sendEmail()は1日100通まで(無料アカウント)。大量送信が必要な場合は、Workspaceアカウント(1日1,500通)の使用を検討してください。
まとめ
定期レポートの自動化は、GASの中でも最も実益が大きい領域です。この記事の3つの実例をベースに、自分の業務に合わせてカスタマイズしてみてください。
「毎週手作業でレポートを作っている」——それが、GASを学ぶ一番の理由になります。
この記事は、著書「Google Apps Script 入門 — 業務自動化の第一歩」(¥1,650・Kindle / Zennでも配信中)の一部を再構成したものです。GASの基礎からトリガー設定、実践プロジェクトまで、31セクションで体系的に解説しています。