スプレッドシートで「完了」にした行を、別のシートへ自動で移す方法(GAS・ボタン1つ)

記事
IT・テクノロジー
問い合わせ・注文・作業の一覧をスプレッドシートで管理していると、「完了」の行がどんどん増えて、今やるべき行が見つけにくくなります。かといって、完了の行を手で切り取って別のシートに貼り付けるのは手間で、貼り忘れや消し間違いも心配です。

この記事では、状態の列が「完了」になった行だけを、別のシート「完了」へまとめて移す仕組みを、GAS(Google Apps Script)で作る手順をまとめました。

この仕組みの特徴は次の 3 つです。
・メニューのボタンを押したときだけ動くので、入力の途中で勝手に行が消えない
・先に「完了」シートへ書いてから元の行を消すので、行が消えるだけの事故が起きにくい
・「未完了」「完了済み」のような似た言葉の行は移さない。移した日も残る

■ 手順 1:元のシートを用意する
管理しているシートの名前を「対応中」にします。1 行目は見出しにして、どこか 1 つの列を「状態」にします。この記事では D 列を状態の列にしています。
A 列:受付日
B 列:お客様
C 列:内容
D 列:状態(対応中・完了 など)

■ 手順 2:コードを貼る
メニューの「拡張機能」→「Apps Script」を開き、最初から入っている文字を消して、次のコードを貼り付けて保存します。

const CONFIG = {
  FROM: '対応中', // 元のシート
  TO: '完了', // 移す先のシート(無ければ作ります)
  STATUS_COL: 4, // 状態の列(A=1, B=2, C=3, D=4)
  DONE: '完了', // この文字の行だけを移す
};

// メニューに「完了の行を移す」を出す
function onOpen() {
  SpreadsheetApp.getUi().createMenu('自動化').addItem('完了の行を移す', 'moveDoneRows').addToUi();
}

function moveDoneRows() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const from = ss.getSheetByName(CONFIG.FROM);
  const last = from.getLastRow();
  const cols = from.getLastColumn();
  if (last < 2) return;
  const header = from.getRange(1, 1, 1, cols).getValues()[0];
  const rows = from.getRange(2, 1, last - 1, cols).getValues();

  const moving = [];
  const rowNumbers = [];
  rows.forEach((row, i) => {
    if (String(row[CONFIG.STATUS_COL - 1]).trim() === CONFIG.DONE) {
      moving.push(row);
      rowNumbers.push(i + 2);
    }
  });
  if (moving.length === 0) {
    Logger.log('移す行はありませんでした。');
    return;
  }

  let to = ss.getSheetByName(CONFIG.TO);
  if (!to) {
    to = ss.insertSheet(CONFIG.TO);
    to.getRange(1, 1, 1, cols + 1).setValues([header.concat('移した日')]);
  }
  const stamp = Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/MM/dd HH:mm');
  const out = moving.map(row => row.concat(stamp));
  // 1. 先に「完了」シートへまとめて書く
  to.getRange(to.getLastRow() + 1, 1, out.length, cols + 1).setValues(out);
  // 2. 書けたあとで、元の行を下から消す(上から消すと行番号がずれるため)
  for (let i = rowNumbers.length - 1; i >= 0; i--) {
    from.deleteRow(rowNumbers[i]);
  }
  Logger.log(moving.length + ' 行を「' + CONFIG.TO + '」に移しました。');
}

状態の列が D 列でないときは、STATUS_COL の数字を変えます(A=1、B=2、C=3、D=4)。シートの名前が違うときは、FROM と TO を書きかえます。

■ 手順 3:まず 1 回、動かしてみる
Apps Script の画面で、関数の選び方の欄から「moveDoneRows」を選んで「実行」を押します。初めての実行では Google の許可の画面が出ます(「このアプリは Google で確認されていません」と出たときは、私の別の記事「GASで「このアプリはGoogleで確認されていません」と出たときの対処」で手順を書いています)。

実行すると、「完了」というシートができて、状態が「完了」の行がそこへ移ります。いちばん右の列には「移した日」が入ります。いきなり本番の表で試さず、まずはファイルをコピーして試すと安心です(「ファイル」→「コピーを作成」)。

■ 手順 4:ボタンで動かせるようにする
スプレッドシートを開き直すと、上のメニューに「自動化」が出ます。ここから「完了の行を移す」を押せば、次からは Apps Script の画面を開かずに動かせます。

■ つまずきやすいところ
・状態の文字が「完了」とぴったり同じ行だけが移ります。前後に空白が入っていても移りますが、「完了済み」「済」などは移りません。状態の列は「データ」→「データの入力規則」でプルダウンにしておくと、書き方がそろいます
・移した行は元のシートから消えます。戻したいときは、「完了」シートから行をコピーして元のシートに貼り付け、状態を書きかえてください
・「完了」シートの列は、元のシートの見出しと同じ並びで作られます。あとから元のシートに列を足したときは、「完了」シートにも同じ位置に列を足してください
・ほかのシートや関数が「対応中」シートの行番号を見ている場合(たとえば別のシートで =対応中!B5 のように参照している)、行が消えると参照先がずれたり、#REF! のエラーになったりします。参照している式がないか、先に確かめてください
・何千行もまとめて移すと時間がかかります。完了の行がたまる前に、こまめに動かすのがおすすめです

■ 自分で作るのが大変なときは
「完了にしたら担当者にメールで知らせたい」「月ごとに別のシートへ分けたい」「移すときに集計も更新したい」など、条件が増えると作りが変わります。次の出品でお手伝いしています。
・GAS でスプレッドシートの転記・集計を自動化します:https://coconala.com/services/4455227
・GAS・Python・VBA のエラーを直します:https://coconala.com/services/4455210

あわせて読みたい:
・GASを毎朝決まった時間に自動で動かす方法(トリガーの設定) https://coconala.com/blogs/6357864/829488
・GASで「このアプリはGoogleで確認されていません」と出たときの対処 https://coconala.com/blogs/6357864/828113

この記事は、AI(Claude)の助けを借りて書いています。コードは、テスト用のデータで動きを確かめてから載せています。
サービス数100万件のスキルマーケット、あなたにぴったりのサービスを探す