GAS×スプレッドシート実践

GAS実践ガイド

GAS×スプレッドシート実践【よく使うテクニック集】

GASとスプレッドシートを組み合わせれば、強力な業務ツールが作れます。この記事では、実務でよく使うテクニックを解説します。

データ操作の基本

効率的なデータ取得

JavaScript
// 悪い例:1セルずつ取得(遅い)
for (let i = 1; i <= 1000; i++) {
  const value = sheet.getRange(i, 1).getValue();
}

// 良い例:一括取得(速い)
const data = sheet.getRange(1, 1, 1000, 1).getValues();
for (const row of data) {
  const value = row[0];
}

効率的なデータ書き込み

JavaScript
// 悪い例:1セルずつ書き込み(遅い)
for (let i = 1; i <= 1000; i++) {
  sheet.getRange(i, 1).setValue(i);
}

// 良い例:一括書き込み(速い)
const data = [];
for (let i = 1; i <= 1000; i++) {
  data.push([i]);
}
sheet.getRange(1, 1, 1000, 1).setValues(data);

最終行・列の取得

JavaScript
function getLastRowCol() {
  const sheet = SpreadsheetApp.getActiveSheet();

  // 最終行(データがある最後の行)
  const lastRow = sheet.getLastRow();

  // 最終列
  const lastCol = sheet.getLastColumn();

  // A列の最終行(特定列)
  const lastRowA = sheet.getRange("A:A")
    .getValues()
    .filter(row => row[0] !== "")
    .length;

  return { lastRow, lastCol, lastRowA };
}

データの集計

グループ別集計

JavaScript
function groupSum() {
  const sheet = SpreadsheetApp.getActiveSheet();
  const data = sheet.getDataRange().getValues();

  // A列でグループ化、B列を合計
  const groups = {};
  for (let i = 1; i < data.length; i++) {
    const key = data[i][0];
    const value = data[i][1];

    if (!groups[key]) {
      groups[key] = 0;
    }
    groups[key] += value;
  }

  // 結果を出力
  const resultSheet = SpreadsheetApp.getActiveSpreadsheet()
    .getSheetByName("集計") || SpreadsheetApp.getActiveSpreadsheet()
    .insertSheet("集計");

  resultSheet.clear();
  resultSheet.appendRow(["グループ", "合計"]);

  Object.entries(groups).forEach(([key, sum]) => {
    resultSheet.appendRow([key, sum]);
  });
}

ピボットテーブル的な集計

JavaScript
function pivotSummary() {
  const sheet = SpreadsheetApp.getActiveSheet();
  const data = sheet.getDataRange().getValues();

  // 行: A列、列: B列、値: C列の合計
  const pivot = {};
  const colKeys = new Set();

  for (let i = 1; i < data.length; i++) {
    const rowKey = data[i][0];
    const colKey = data[i][1];
    const value = data[i][2];

    if (!pivot[rowKey]) pivot[rowKey] = {};
    if (!pivot[rowKey][colKey]) pivot[rowKey][colKey] = 0;
    pivot[rowKey][colKey] += value;

    colKeys.add(colKey);
  }

  // 出力
  const colArray = Array.from(colKeys).sort();
  const output = [["", ...colArray]];

  Object.entries(pivot).forEach(([rowKey, cols]) => {
    const row = [rowKey];
    colArray.forEach(colKey => {
      row.push(cols[colKey] || 0);
    });
    output.push(row);
  });

  const resultSheet = SpreadsheetApp.getActiveSpreadsheet()
    .insertSheet("ピボット");
  resultSheet.getRange(1, 1, output.length, output[0].length)
    .setValues(output);
}

複数シートの操作

全シートのデータを統合

JavaScript
function mergeAllSheets() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheets = ss.getSheets();

  let mergedData = [];
  let headerAdded = false;

  sheets.forEach(sheet => {
    if (sheet.getName() === "統合") return;

    const data = sheet.getDataRange().getValues();

    if (!headerAdded) {
      mergedData.push(data[0]);
      headerAdded = true;
    }

    // ヘッダー以外を追加
    for (let i = 1; i < data.length; i++) {
      mergedData.push(data[i]);
    }
  });

  // 統合シートに出力
  let mergedSheet = ss.getSheetByName("統合");
  if (!mergedSheet) {
    mergedSheet = ss.insertSheet("統合");
  }
  mergedSheet.clear();
  mergedSheet.getRange(1, 1, mergedData.length, mergedData[0].length)
    .setValues(mergedData);
}

シートのコピーと操作

JavaScript
function copyAndModifySheet() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sourceSheet = ss.getSheetByName("テンプレート");

  // シートをコピー
  const newSheet = sourceSheet.copyTo(ss);
  newSheet.setName("新しいシート_" + new Date().getTime());

  // コピーしたシートを編集
  newSheet.getRange("A1").setValue("コピーしたシート");

  return newSheet;
}

外部データとの連携

CSVのインポート

JavaScript
function importCsvFromDrive(fileId) {
  const file = DriveApp.getFileById(fileId);
  const content = file.getBlob().getDataAsString("UTF-8");
  const data = Utilities.parseCsv(content);

  const sheet = SpreadsheetApp.getActiveSheet();
  sheet.clear();
  sheet.getRange(1, 1, data.length, data[0].length).setValues(data);
}

JSONデータの取得

JavaScript
function fetchJsonData() {
  const url = "https://api.example.com/data";
  const response = UrlFetchApp.fetch(url);
  const json = JSON.parse(response.getContentText());

  // スプレッドシートに出力
  const sheet = SpreadsheetApp.getActiveSheet();
  const headers = Object.keys(json[0]);
  sheet.appendRow(headers);

  json.forEach(item => {
    const row = headers.map(h => item[h]);
    sheet.appendRow(row);
  });
}

カスタムメニュー

メニューの追加

JavaScript
function onOpen() {
  const ui = SpreadsheetApp.getUi();
  ui.createMenu("カスタムメニュー")
    .addItem("集計を実行", "runSummary")
    .addItem("データをクリア", "clearData")
    .addSeparator()
    .addSubMenu(ui.createMenu("エクスポート")
      .addItem("CSV出力", "exportCsv")
      .addItem("PDF出力", "exportPdf"))
    .addToUi();
}

function runSummary() {
  // 集計処理
  SpreadsheetApp.getUi().alert("集計が完了しました");
}

function clearData() {
  const sheet = SpreadsheetApp.getActiveSheet();
  sheet.getRange(2, 1, sheet.getLastRow() - 1, sheet.getLastColumn()).clear();
}

確認ダイアログ

JavaScript
function confirmAction() {
  const ui = SpreadsheetApp.getUi();
  const response = ui.alert(
    "確認",
    "本当に実行しますか?",
    ui.ButtonSet.YES_NO
  );

  if (response === ui.Button.YES) {
    // 処理を実行
    ui.alert("実行しました");
  } else {
    ui.alert("キャンセルしました");
  }
}

実践的なツール例

在庫管理ツール

JavaScript
function updateStock(productId, quantity, type) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet()
    .getSheetByName("在庫");
  const data = sheet.getDataRange().getValues();

  for (let i = 1; i < data.length; i++) {
    if (data[i][0] === productId) {
      const currentStock = data[i][2];
      const newStock = type === "in"
        ? currentStock + quantity
        : currentStock - quantity;

      sheet.getRange(i + 1, 3).setValue(newStock);

      // 履歴を記録
      const historySheet = SpreadsheetApp.getActiveSpreadsheet()
        .getSheetByName("履歴");
      historySheet.appendRow([
        new Date(),
        productId,
        type,
        quantity,
        newStock
      ]);

      return newStock;
    }
  }
  return null;
}

勤怠管理ツール

JavaScript
function recordAttendance(type) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet()
    .getSheetByName("勤怠");
  const today = new Date();
  const dateStr = Utilities.formatDate(today, "JST", "yyyy/MM/dd");
  const timeStr = Utilities.formatDate(today, "JST", "HH:mm");
  const user = Session.getActiveUser().getEmail();

  sheet.appendRow([dateStr, user, type, timeStr]);
}

function clockIn() {
  recordAttendance("出勤");
  SpreadsheetApp.getUi().alert("出勤を記録しました");
}

function clockOut() {
  recordAttendance("退勤");
  SpreadsheetApp.getUi().alert("退勤を記録しました");
}

まとめ

パフォーマンスのポイント

  1. データは一括で取得・書き込み
  2. ループ内でgetValue/setValueを避ける
  3. 配列で処理してからシートに反映

よく使うメソッド

JavaScript
// シート操作
sheet.getRange(row, col).getValue()
sheet.getRange(row, col, numRows, numCols).getValues()
sheet.appendRow([values])
sheet.getLastRow()

// 書式
range.setBackground(color)
range.setFontWeight("bold")

関連記事

お問い合わせ

GAS開発についてのご相談は、お気軽にお問い合わせください。

  • ツール開発
  • 業務自動化
  • 技術サポート

お問い合わせはこちら

最終更新: 2025年1月