スプレッドシート承認フローの誤更新を防ぐ|GASで承認前後をdry-run検査
Gasおじ|GoogleアカウントをAIエージェント化
スプレッドシートで申請と承認を管理すると、行を見間違えたり、未承認のデータを処理済みにしたりしがちです。今回は、承認そのものを自動化する前に、対象行の不足・状態・重複を読み取り専用で検査する最小構成を作ります。
シート構成
ApprovalQueueシートの1行目に、次の見出しを用意します。
- request_id
- summary
- requested_by
- status
- approved_by
- approved_at
statusは pending、approved、rejected のいずれかに限定します。コードはセルを書き換えず、検査結果だけをログへ出します。
dry-run検査コード
function previewSpreadsheetApprovalFree() {
const DRY_RUN = true;
const sheet = SpreadsheetApp.getActive().getSheetByName('ApprovalQueue');
if (!sheet) throw new Error('ApprovalQueue シートがありません');
const values = sheet.getDataRange().getDisplayValues();
if (values.length < 2) throw new Error('検査対象の行がありません');
const headers = values[0].map(String);
const required = ['request_id', 'summary', 'requested_by', 'status', 'approved_by', 'approved_at'];
const index = Object.fromEntries(required.map(name => [name, headers.indexOf(name)]));
const missingHeaders = required.filter(name => index[name] < 0);
if (missingHeaders.length) throw new Error('不足見出し: ' + missingHeaders.join(', '));
const allowedStatus = new Set(['pending', 'approved', 'rejected']);
const seen = new Set();
const findings = [];
values.slice(1).forEach((row, offset) => {
const rowNumber = offset + 2;
const id = row[index.request_id].trim();
const status = row[index.status].trim().toLowerCase();
const approver = row[index.approved_by].trim();
const approvedAt = row[index.approved_at].trim();
if (!id) findings.push({ row: rowNumber, issue: 'request_id が空欄' });
if (id && seen.has(id)) findings.push({ row: rowNumber, issue: 'request_id が重複' });
if (id) seen.add(id);
if (!row[index.summary].trim()) findings.push({ row: rowNumber, issue: 'summary が空欄' });
if (!row[index.requested_by].trim()) findings.push({ row: rowNumber, issue: 'requested_by が空欄' });
if (!allowedStatus.has(status)) findings.push({ row: rowNumber, issue: 'status が許可値外' });
if (status === 'pending' && (approver || approvedAt)) findings.push({ row: rowNumber, issue: '承認前なのに承認記録あり' });
if (status === 'approved' && (!approver || !approvedAt)) findings.push({ row: rowNumber, issue: '承認記録が不足' });
});
console.log(JSON.stringify({ dryRun: DRY_RUN, checkedRows: values.length - 1, findings }, null, 2));
}実行手順
1. 元シートを複製し、検証用ファイルで試します。
2. Apps Scriptへコードを貼り付けます。
3. previewSpreadsheetApprovalFreeを実行します。
4. 実行ログのfindingsを確認し、元データは人が修正します。
5. findingsが0件になってから、承認通知や更新処理を別関数として追加します。
安全に運用するための停止条件
- 見出しが1つでも不足していたら処理を止める
- request_idが空欄または重複なら自動更新しない
- pending行に承認者や承認日時が入っていたら確認する
- approved行の承認者・承認日時が不足していたら後続処理へ渡さない
- メール送信、セル更新、外部公開はこのコードでは行わない
承認ボタンや通知を足す前に、入力状態を検査する工程を独立させると、誤更新の原因を追いやすくなります。実データでは権限範囲と個人情報の扱いも別途確認してください。
承認後の投稿キューまで安全に運用したい方へ
Gasおじ式 X投稿キュー自動実行GAS Pro|危ない時だけ止まる

GasおじのGAS商品一覧
公開中の商品をTipsで見る

