株式会社WR

株式会社WR

WEB TOTAL CONSULTING

GASでスプレッドシートをダッシュボード化——チャートの自動更新
ブログ一覧へ
技術ブログ

GASでスプレッドシートをダッシュボード化——チャートの自動更新

Google スプレッドシートとGASを組み合わせて、データを自動収集・集計してチャートを毎日更新するダッシュボードを作ります。

GASでスプレッドシートをダッシュボード化する意義

Googleスプレッドシートは手軽なデータ共有ツールですが、データが増えるにつれてチャートの更新作業が手間になります。Google Apps Scriptを使ってチャートを自動更新することで、常に最新データを反映したダッシュボードを維持できます。

活用シーン:

  • EC売上の日次・月次ダッシュボード
  • スクレイピングで収集した競合価格の推移グラフ
  • 予約件数・キャンセル率のモニタリング
  • 広告費・ROASのリアルタイム確認

スプレッドシートとGASの連携基本

// スプレッドシートのオブジェクトを取得
const ss = SpreadsheetApp.getActiveSpreadsheet();

// シートを名前で取得
const dataSheet = ss.getSheetByName('データ');
const dashSheet = ss.getSheetByName('ダッシュボード');

// データ範囲を取得
const data = dataSheet.getDataRange().getValues();
console.log(`行数: ${data.length}, 列数: ${data[0].length}`);

売上データの自動集計

/**
 * 月別売上を集計してダッシュボードシートに書き込む
 */
function updateMonthlySummary() {
    const ss   = SpreadsheetApp.getActiveSpreadsheet();
    const data = ss.getSheetByName('売上データ').getDataRange().getValues();
    const dash = ss.getSheetByName('月別集計');

    // ヘッダーをスキップしてデータを月別に集計
    const monthlyMap = {};
    for (let i = 1; i < data.length; i++) {
        const date  = new Date(data[i][0]);
        const sales = parseFloat(data[i][2]) || 0;

        const key = Utilities.formatDate(date, 'Asia/Tokyo', 'yyyy-MM');
        if (!monthlyMap[key]) {
            monthlyMap[key] = { month: key, total: 0, count: 0 };
        }
        monthlyMap[key].total += sales;
        monthlyMap[key].count++;
    }

    // 月順にソートして書き出し
    const sorted = Object.values(monthlyMap).sort((a, b) => a.month.localeCompare(b.month));

    dash.clearContents();
    dash.appendRow(['月', '売上合計', '件数', '平均単価']);

    sorted.forEach(row => {
        dash.appendRow([
            row.month,
            row.total,
            row.count,
            Math.round(row.total / row.count),
        ]);
    });

    // 数値列に書式設定
    const lastRow = dash.getLastRow();
    dash.getRange(2, 2, lastRow - 1, 1)
        .setNumberFormat('#,##0');
    dash.getRange(2, 4, lastRow - 1, 1)
        .setNumberFormat('#,##0');
}

チャートの自動生成・更新

/**
 * 月別売上の棒グラフを生成(または更新)
 */
function createOrUpdateSalesChart() {
    const ss    = SpreadsheetApp.getActiveSpreadsheet();
    const dash  = ss.getSheetByName('月別集計');
    const board = ss.getSheetByName('ダッシュボード');

    const lastRow = dash.getLastRow();
    const dataRange = dash.getRange(1, 1, lastRow, 2); // 月・売上合計の2列

    // 既存チャートを削除
    board.getCharts().forEach(chart => board.removeChart(chart));

    // 新しいチャートを作成
    const chartBuilder = board.newChart()
        .setChartType(Charts.ChartType.COLUMN)
        .addRange(dataRange)
        .setPosition(2, 1, 0, 0)   // 行2・列A から配置
        .setNumHeaders(1)
        .setOption('title', '月別売上推移')
        .setOption('titleTextStyle', { fontSize: 16, bold: true })
        .setOption('width', 700)
        .setOption('height', 400)
        .setOption('colors', ['#1a73e8'])
        .setOption('vAxis.format', '#,##0')
        .setOption('legend.position', 'none');

    board.insertChart(chartBuilder.build());
    SpreadsheetApp.flush();
}

KPIカードの自動更新

/**
 * ダッシュボードにKPIサマリーを更新する
 */
function updateKPICards() {
    const ss   = SpreadsheetApp.getActiveSpreadsheet();
    const data = ss.getSheetByName('売上データ').getDataRange().getValues().slice(1);
    const dash = ss.getSheetByName('ダッシュボード');

    const today = new Date();
    const thisMonth = Utilities.formatDate(today, 'Asia/Tokyo', 'yyyy-MM');
    const lastMonth = Utilities.formatDate(
        new Date(today.getFullYear(), today.getMonth() - 1, 1),
        'Asia/Tokyo', 'yyyy-MM'
    );

    let thisMonthTotal = 0, lastMonthTotal = 0;
    let thisMonthCount = 0, lastMonthCount = 0;

    data.forEach(row => {
        const month = Utilities.formatDate(new Date(row[0]), 'Asia/Tokyo', 'yyyy-MM');
        const sales = parseFloat(row[2]) || 0;

        if (month === thisMonth) { thisMonthTotal += sales; thisMonthCount++; }
        if (month === lastMonth) { lastMonthTotal += sales; lastMonthCount++; }
    });

    const growthRate = lastMonthTotal > 0
        ? ((thisMonthTotal - lastMonthTotal) / lastMonthTotal * 100).toFixed(1)
        : 'N/A';

    // KPIをセルに書き込む
    dash.getRange('B2').setValue(`¥${thisMonthTotal.toLocaleString()}`); // 今月売上
    dash.getRange('B3').setValue(thisMonthCount);                         // 今月件数
    dash.getRange('B4').setValue(`${growthRate}%`);                      // 前月比
    dash.getRange('B5').setValue(new Date().toLocaleString('ja-JP'));    // 最終更新
}

全処理をまとめて実行

/**
 * ダッシュボードを一括更新するメイン関数
 */
function refreshDashboard() {
    console.log('ダッシュボード更新開始:', new Date().toLocaleString('ja-JP'));

    updateMonthlySummary();
    createOrUpdateSalesChart();
    updateKPICards();

    console.log('ダッシュボード更新完了');
}

定期実行トリガーの設定

function setupDailyTrigger() {
    // 既存トリガーをクリア
    ScriptApp.getProjectTriggers()
        .filter(t => t.getHandlerFunction() === 'refreshDashboard')
        .forEach(t => ScriptApp.deleteTrigger(t));

    // 毎朝7時に自動更新
    ScriptApp.newTrigger('refreshDashboard')
        .timeBased()
        .atHour(7)
        .everyDays(1)
        .inTimezone('Asia/Tokyo')
        .create();
}

まとめ

GASを使ったスプレッドシートのダッシュボード化は、Googleアカウントがあれば追加コストゼロで実装できます。弊社ではEC売上分析・スクレイピングデータの可視化・KPIモニタリングのダッシュボードをGASで構築してきました。

業務自動化・データ可視化ツールの開発についてはお気軽にご相談ください。

Category 技術ブログ

Related Posts

関連記事

開発・技術のご相談はお気軽に

お見積りは無料です。まずはお気軽にご相談ください。

お問い合わせ →