本サイトはアフィリエイト広告(A8.net/もしもアフィリエイト/アクセストレード等)を利用しています
スプシ週次バックアップをGASで自動化|大事故回避の保険
📂 スプレッドシート

スプシ週次バックアップをGASで自動化|大事故回避の保険

📅 ⏱ 読了 約8分 ✍️ 凛

💡 本記事には広告(アフィリエイトリンク)が含まれる場合があります。

こんにちは、凛です。コーヒー片手に副業のスプレッドシートを開くのが、朝のちょっとした楽しみです。夫と共有している売上シートをその朝も開いて、そして固まりました。月初のデータが、ごっそり無い。

この記事は、その日から「週次で自動バックアップを取るGAS」を完成させるまでの記録です。同じように共有スプシで冷や汗をかいたことがある方に、私がたどった道をそのまま残しておきます。

スプシ週次バックアップをGASで自動化

データが消えた朝のこと

血の気が引く、という感覚を久しぶりに味わいました。夫が誤って行を削除していたんです。幸いGoogleのバージョン履歴で戻せたのですが、どの時点まで戻せばいいのか確認するだけで30分。夜勤明けで頭がぼんやりしている状態で、半泣きで作業していました。

共有して使うスプシは、誰かがうっかり上書きしたり行を消したりするリスクと、いつも隣り合わせです。「バックアップなんて大げさ」と、正直それまでの私は思っていました。その考えが、この朝で180度変わりました。

バージョン履歴だけでは足りないと気づいた日

まず「そもそもバージョン履歴があるのに、なぜ足りなかったのか」を整理するところから始めました。

Googleの標準機能であるバージョン履歴は、変更のたびに自動保存され、最大100バージョンまで遡れます。とても便利です。ただ、「あの時点の完全なファイル」を独立した形で取り出すには、それなりの操作が必要でした。しかも、ファイル自体を削除されてしまったら、そもそも履歴にたどり着けません。

一方、GASで別ファイルにコピーしておくと、日付付きの独立したファイルが残ります。「2026年3月分の完全なスナップショット」として保存できて、複数ファイルをまとめて退避することもできる。古くなったものを自動で消して容量を節約することもできます。

本当は両方を組み合わせるのがいちばん安心です。でもこの日の私が欲しかったのは、後者の「別ファイルとして丸ごと残す」ほうでした。というわけで、そちらを作ることにしました。

準備した日:フォルダとIDの確認

作り始める前に、2つだけ手元で確認しました。

バックアップ用フォルダを切る

まず Google Driveに バックアップ_2026 という専用フォルダを作りました。フォルダIDは次の手順で分かります。

  1. Google DriveでフォルダをクリックしてURLを確認
  2. https://drive.google.com/drive/folders/(ここがフォルダID) の形式になっている
  3. folders/ 以降の文字列がフォルダID

バックアップしたいファイルのIDを控える

対象のスプレッドシートを開いて、URLを見ます。 https://docs.google.com/spreadsheets/d/(ここがファイルID)/edit

/d//edit の間の文字列がファイルIDです。私は売上・顧客リスト・在庫の3つを控えました。

コードを書いた日:まず基本形から

最初に書いたのが、この基本版です。指定したファイルを日付付きでコピーして、4週間より古いバックアップは自動でゴミ箱に落とす、というものです。

/**
 * 週次バックアップ:指定したスプシを日付付きでコピー
 * ※静的検証済み:GAS環境(V8ランタイム)で動作確認
 */
function weeklyBackup() {
  // バックアップ対象のファイルIDを配列で指定
  // ← ファイルを増やす場合はここに追加するだけ
  const FILES_TO_BACKUP = [
    '会計データのFILE_ID',     // 実際のIDに差し替えてください
    '顧客リストのFILE_ID',
    '在庫管理のFILE_ID',
  ];

  // バックアップ先フォルダのID
  const BACKUP_FOLDER_ID = 'バックアップフォルダのID';

  // フォルダを取得
  const folder = DriveApp.getFolderById(BACKUP_FOLDER_ID);

  // 今日の日付を yyyyMMdd 形式で取得
  const date = Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyyMMdd');

  // 各ファイルをコピー
  FILES_TO_BACKUP.forEach(id => {
    // ファイルを取得
    const file = DriveApp.getFileById(id);

    // バックアップ用のファイル名を作成(例:backup_20260527_売上管理.gsheet)
    const backupName = `backup_${date}_${file.getName()}`;

    // 指定フォルダにコピーを作成
    file.makeCopy(backupName, folder);

    Logger.log(`バックアップ完了: ${backupName}`);
  });

  // 28日(4週間)以上前のバックアップを自動削除
  const cutoffDate = new Date();
  cutoffDate.setDate(cutoffDate.getDate() - 28);

  // フォルダ内の全ファイルをチェック
  const files = folder.getFiles();
  let deletedCount = 0;

  while (files.hasNext()) {
    const f = files.next();
    // 作成日が4週間以上前ならゴミ箱へ
    if (f.getDateCreated() < cutoffDate) {
      f.setTrashed(true);
      deletedCount++;
      Logger.log(`古いバックアップを削除: ${f.getName()}`);
    }
  }

  Logger.log(`今週のバックアップ完了。削除: ${deletedCount}件`);
}

通知メールも欲しくなった日

しばらく使っていて、ひとつ不安が残りました。「本当に毎週ちゃんと動いているのか、私は把握できていない」ということです。トリガーで裏側で動くものだからこそ、結果を教えてほしい。そこで、成功・失敗をメールで知らせる版も足しました。1件失敗しても全体を止めず、失敗はメールに書き出す作りにしています。

/**
 * 週次バックアップ+完了通知メール版
 * ※静的検証済み:GAS環境(V8ランタイム)で動作確認
 */
function weeklyBackupWithNotification() {
  const FILES_TO_BACKUP = [
    { id: '会計データのFILE_ID', name: '会計データ' },
    { id: '顧客リストのFILE_ID', name: '顧客リスト' },
  ];

  const BACKUP_FOLDER_ID = 'バックアップフォルダのID';
  const NOTIFY_EMAIL = 'your@email.com'; // 通知先メールアドレス

  const folder = DriveApp.getFolderById(BACKUP_FOLDER_ID);
  const date = Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyyMMdd');

  // バックアップ実行
  const backedUpFiles = [];
  const failedFiles = [];

  FILES_TO_BACKUP.forEach(target => {
    try {
      const file = DriveApp.getFileById(target.id);
      const backupName = `backup_${date}_${target.name}`;
      file.makeCopy(backupName, folder);
      backedUpFiles.push(backupName);
    } catch (e) {
      // エラーが起きたファイルは失敗リストに追加(全体を止めない)
      failedFiles.push(`${target.name}: ${e.message}`);
      Logger.log(`バックアップ失敗: ${target.name} - ${e.message}`);
    }
  });

  // 完了メールを送信
  const subject = `[週次バックアップ] ${date} 完了`;
  let body = `週次バックアップが完了しました。\n\n`;
  body += `✅ 成功: ${backedUpFiles.length}件\n`;
  backedUpFiles.forEach(name => { body += `  - ${name}\n`; });

  if (failedFiles.length > 0) {
    body += `\n❌ 失敗: ${failedFiles.length}件\n`;
    failedFiles.forEach(err => { body += `  - ${err}\n`; });
  }

  GmailApp.sendEmail(NOTIFY_EMAIL, subject, body);
  Logger.log('バックアップ完了通知を送信しました');
}

トリガーを仕掛けて「手放し」にした日

コードができたら、あとは毎週勝手に動いてもらうだけです。時間ベースのトリガーを設定します。

  1. GASエディタを開く(スプシ上部メニュー「拡張機能」→「Apps Script」)
  2. 左メニューの時計アイコン「トリガー」をクリック
  3. 右下の「+ トリガーを追加」ボタンをクリック
  4. 「実行する関数を選択」で weeklyBackup を選ぶ
  5. 「イベントのソースを選択」で「時間主導型」を選ぶ
  6. 「時間ベースのトリガーのタイプを選択」で「週タイマー」を選ぶ
  7. 実行する曜日を「月曜日」に設定
  8. 実行時刻を「午前6時〜7時」に設定
  9. 「保存」ボタンをクリック
  10. Googleアカウントの認証画面が出たら「許可」をクリック

これで毎週月曜の朝6時台に、自動でバックアップが走ります。週明けに副業作業を始めた時点で、もう先週分の退避が済んでいる。この「気づいたら終わっている」状態が、じつは一番ありがたいんですよね。

運用して見えてきた3つのコツ

バックアップ専用フォルダは必ず分ける

メインのスプシと同じフォルダにバックアップを置くと、誤って開いて編集してしまう事故が起きます。せっかくの保険が汚れてしまう。バックアップ_2026 のように専用フォルダを切って、しかも自分だけが閲覧・編集できる設定にしておくと、共有メンバーがうっかり触ることも防げます。私は共有スプシのフォルダとは完全に分けて、自分専用にしています。

ファイル名に日付を入れてフォーマットを揃える

backup_yyyyMMdd_ファイル名 の形にしておくと、後で「あの日のデータ欲しい」と言われてもすぐ探せます。yyyyMMdd(例:20260516)にすると、フォルダ内で自動的に日付順に並ぶので、最新がどれか一目で分かります。日付は Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyyMMdd') で取れます。タイムゾーンは 'JST' でも動きますが、公式が推奨しているのは 'Asia/Tokyo' のような地域名形式なので、こちらを使うのが安全です。

古いバックアップは自動で消して容量を守る

溜め続けるとDriveの容量を圧迫します。私は4週間(28日)より古いものは自動でゴミ箱へ、という基準にしています。ただし税務資料のように重要なものは、この自動削除の輪から外して、別フォルダに月次で手動保管しています。目安はこんな感じです。

  • 副業の日常データ → 4週間(週次バックアップ4世代)
  • 確定申告関連データ → 5年以上(別フォルダで手動管理)
  • 顧客情報 → 法律に従った期間(業種によって異なります)

途中でつまずいたところ

順調そうに書いていますが、もちろん途中でいくつか引っかかりました。あとから同じところで止まる方がいると思うので、残しておきます。

コピー先のフォルダIDを間違える

間違ったフォルダにコピーすると、どこに貯まっているのか気づかないまま増えていきます。私は本番前に、フォルダにアクセスできるかだけを確かめるテストを1回走らせるようにしました。

// バックアップ先フォルダの名前をログ出力して確認するテスト用コード
function testFolderAccess() {
  const BACKUP_FOLDER_ID = 'ここにFOLDER_IDを入れる';
  try {
    const folder = DriveApp.getFolderById(BACKUP_FOLDER_ID);
    Logger.log(`フォルダ名: ${folder.getName()}`);
    Logger.log('アクセス成功!このフォルダにバックアップされます');
  } catch (e) {
    Logger.log(`エラー: ${e.message}`);
    Logger.log('フォルダIDが間違っているか、アクセス権限がありません');
  }
}

これを先に流して、フォルダ名がちゃんと表示されるのを見てから本番を動かすと安心です。

共有ドライブの権限不足でエラーになる

会社の共有ドライブに退避しようとして、書き込み権限がなく Exception: You don't have permission to access the requested document. のようなエラーで止まることがあります。確認の順番はこうです。

  1. フォルダの「共有」設定で、自分が「編集者」または「コンテンツ管理者」になっているか
  2. 共有ドライブの場合は「コンテンツ管理者」権限が必要
  3. 権限が正しくても、初回実行時はGASの認証画面で「すべてのGoogle Driveファイルの表示、編集」の権限を許可する必要がある

ファイルIDが変わっていてエラーになる

スプレッドシートのファイルIDは通常変わりませんが、コピー→削除→再作成をすると変わります。別のユーザーがファイルを移動した場合も同じです。ここで効いてくるのが、さっきの通知メール版(weeklyBackupWithNotification)でした。失敗もメールに残るので、IDが変わったことにその日のうちに気づけます。

長く運用するうえで意識していることを、最後に一覧にしておきます。

ポイント理由
バックアップフォルダは専用で分ける誤編集・誤削除を防ぐ
ファイル名に日付を入れる(yyyyMMdd形式)自動的に日付順で並ぶ
古いバックアップは自動削除するGoogle Driveの容量節約
バックアップ完了の通知メールを設定する失敗に気づける
重要なデータは月次バックアップも取る週次だけでは心配なデータ向け
初回は手動実行して動作確認するトリガー設定前に必ず確認

あの朝から半年、青ざめなくなった

このGASを月曜6時のトリガーで動かすようになってから、私はもう「データが消えた!」で青ざめることがなくなりました。何もしていないのに、毎週きちんと退避が済んでいる。共有スプシで大事な数字を扱っているなら、これは本当に入れておいてよかった保険です。あの朝の冷や汗を、あなたにはかいてほしくないなと思います。


関連記事

Google Drive自動化をもっと深めたい方は、以下の記事もおすすめです。

これらと組み合わせると、Driveの運用負担が一気に減ります。


この記事を書いた人:凛

2児2児のママで現役ナース。夜勤明けの細切れ時間を副業GASに投じ、月5〜8万円の副収入を継続中。「看護師でもコードは書ける」を合言葉に、家事育児とプログラミングを両立する等身大の情報を発信しています。

本記事のコードは、掲載前に構文チェックを行っています。 ただし実行結果はお使いの環境に左右されるので、初回は必ず手動実行で動作を確かめてください。