Google Sheets + GASで完全CRUD対応Webアプリを作ってみた

IT全般
スポンサーリンク

こんにちは!スタッフのやまさきです。

前回は、Google Sheets を簡易データベースとして利用し、GASで GET / POST だけに対応したCRUDテンプレートを作成しました。

データの追加・一覧取得は可能でしたが、更新・削除は未対応でした。

データベースとして使用するなら、CRUD機能は必須だよねー

ということで、今回は完全CRUD版を作成してみました。

完全CRUD版の特徴

今回のテンプレートでは以下を追加・改善しました。

  • id列の追加
    • 各行に一意のIDを割り振り、更新・削除の対象指定に使用。
      (今思えば、なぜ最初から設定していなかったのか…)
  • 更新(PUT)機能
    • 既存の行を指定して、name / email / dateを更新可能。
  • 削除(DELETE)機能
    • ID指定で行を削除可能。誤操作防止の確認ダイアログ付き。
  • 明るく見やすいUI
    • 淡い背景・白カード・アクセントカラーのボタン。

使用するGASコードの概要

  • doGet(e):一覧取得(Read)
  • doPost(e):新規追加(Create)
  • doPut(e):更新(Update)
  • doDelete(e):削除(Delete)

id を元に対象行を特定し、更新・削除を実施します。学習用なのでセキュリティは簡易的です。

// CRUD対応版

function doGet(e) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート1');
  const data = sheet.getDataRange().getValues();
  const headers = data.shift(); // 1行目(ヘッダー)を除外

  const json = data.map(row => {
    let record = {};
    headers.forEach((header, i) => {
      record[header] = row[i];
    });
    return record;
  });

  return ContentService.createTextOutput(JSON.stringify(json))
    .setMimeType(ContentService.MimeType.JSON);
}

function doPost(e) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート1');
  const body = JSON.parse(e.postData.contents);

  // 新しいIDを発行(最後の行のID + 1)
  const lastRow = sheet.getLastRow();
  const lastId = lastRow > 1 ? sheet.getRange(lastRow, 1).getValue() : 0;
  const newId = lastId + 1;

  sheet.appendRow([newId, body.name, body.email, body.date]);

  return ContentService.createTextOutput(JSON.stringify({ status: 'success', id: newId }))
    .setMimeType(ContentService.MimeType.JSON);
}

function doPut(e) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート1');
  const body = JSON.parse(e.postData.contents);
  const id = body.id;

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

  for (let i = 1; i < data.length; i++) { // 1行目はヘッダーなので除外
    if (data[i][0] == id) { // id列が一致
      sheet.getRange(i + 1, 2).setValue(body.name);   // name
      sheet.getRange(i + 1, 3).setValue(body.email);  // email
      sheet.getRange(i + 1, 4).setValue(body.date);   // date
      return ContentService.createTextOutput(JSON.stringify({ status: 'updated', id: id }))
        .setMimeType(ContentService.MimeType.JSON);
    }
  }

  return ContentService.createTextOutput(JSON.stringify({ status: 'error', message: 'id not found' }))
    .setMimeType(ContentService.MimeType.JSON);
}

function doDelete(e) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート1');
  const body = JSON.parse(e.postData.contents);
  const id = body.id;

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

  for (let i = 1; i < data.length; i++) {
    if (data[i][0] == id) { // id列が一致
      sheet.deleteRow(i + 1);
      return ContentService.createTextOutput(JSON.stringify({ status: 'deleted', id: id }))
        .setMimeType(ContentService.MimeType.JSON);
    }
  }

  return ContentService.createTextOutput(JSON.stringify({ status: 'error', message: 'id not found' }))
    .setMimeType(ContentService.MimeType.JSON);
}

Webページの構成

  • index.html:画面構成(接続設定・CRUD操作フォーム・一覧表示)
  • styles.css:明るく見やすいUIデザイン
  • main.js:CRUD処理、一覧表示、行クリックでフォーム反映など

上記3つのファイルはこちら(zip形式)からダウンロードできます。

使い方(操作手順)

  1. GASをウェブアプリとしてデプロイし、ウェブアプリURLを「コピー」
  2. Webページの「API URL」欄に /exec URLを貼り付けて「保存」
    例:https://script.google.com/macros/s/〜/exec
    • 不安な方は「接続テスト」をクリックして確認してください
    • URLはブラウザに保存(ローカルストレージ)される
  3. 一覧から変更したい行をクリックすると更新&削除フォームに反映
  4. 新規作成はフォームに入力後「追加」をクリック

注意点

  • GASの公開設定を「全員」にすると誰でも操作可能
  • 本番で使用する場合は必ず 認証・権限管理・入力検証 を実装
  • 学習、テスト用として使用する場合は安全ですが、公開は注意

いったん保存した値(ウェブアプリURL)は、以下の方法で削除しないかぎり永続的に残ります(消えません)

  1. ユーザーが手動で消去
    • ブラウザの「サイトデータの消去」「履歴のクリア」などで削除
    • ブラウザの開発者ツールから localStorage.clear() や localStorage.removeItem(‘gas_api_url’) を実行
  2. ブラウザやOSの設定による削除
    • プライベートモード(シークレットモード)では、ブラウザを閉じると自動的に消去
    • 一部のブラウザ設定では、終了時に全てのローカルストレージを削除する場合も

まとめ・応用アイデア

  • このテンプレートをベースに小規模な社内フォームやデータ管理Webアプリを作成可能
  • さらに、フィルター機能・ソート・グラフ表示などを追加して高度化も可能

タイトルとURLをコピーしました