Apps ScriptのonEditが動かないときは、最初に「値を変えた主体」を確認してください。Google Sheetsのセルを利用者が直接編集したときの通知と、Apps Script・Sheets API・外部連携による書き込み、数式の再計算は同じイベントではありません。スクリプトやAPIの書き込みをonEditで拾おうとする設計では、トリガーを増やしても検知できないことがあります。書き込み元から処理関数を直接呼ぶか、定期的に差分を照合するかを、必要な即時性・重複対策・権限で選びましょう。
目次
onEditが扱う変更と扱わない変更
単純トリガーのonEdit(e)は、スプレッドシートのセルを利用者が編集したときに実行される予約関数です。Google公式資料は、Apps Scriptの実行やAPIリクエストがトリガーを起動しない例として、Range.setValue()による編集を挙げています。インストール型の編集トリガーも、スクリプト実行・APIリクエストを原因とする変更では通常起動しません。インストール型へ変えればAPI更新も検知できる、とは考えないでください。
数式セルの表示値が変わった場合も、利用者がそのセルを編集したイベントが発生したわけではありません。たとえば別セルの編集を受けて数式が再計算されても、「再計算されたセルごとにonEditが呼ばれる」とは限りません。数式結果を監視したい場合は、数式を更新した入力セルをイベント起点にするのか、計算結果を時間差で照合するのかを設計します。API連携が書き込んだ直後の値を確実に処理したいなら、書き込み側で後処理関数を明示的に呼ぶ方法が候補です。
表は横にスクロールできます
| 値の変化元 | onEditの期待 | 最初に確認すること |
|---|---|---|
| 利用者がセルを直接編集 | 編集イベントの対象 | 対象範囲、編集者、イベント情報、実行エラー |
| Apps Scriptがセルを書込 | その書込自体では起動しない | 書込関数から後処理を呼べるか |
| Sheets API / 外部クライアント | そのAPI書込では起動しない | API呼出元に処理完了通知を追加できるか |
| 数式の再計算 | 再計算セルの編集イベントとは別 | 元入力セルを起点にするか、差分を定期確認するか |
| CSVインポートや一括操作 | 実際の操作・範囲で挙動確認 | 利用者操作かAPI経由か、テストログで分類 |
まず「何が値を変えたか」を記録する
トリガーを修正する前に、発生事例を数件記録します。スプレッドシートの画面で人が入力したのか、Apps Scriptの関数が書いたのか、APIクライアントや自動連携なのかを区別してください。「セルの値が変わった」という結果だけでは、どのトリガーが使えるか決められません。
最小の診断ログには、日時、対象スプレッドシートID、シート名、セル範囲、書込み元(human/script/API/formula/unknown)、書込み処理の実行ID、期待する処理名、処理済みID、結果を含めます。セルの実値に個人情報や機密情報が含まれる場合、ログへコピーせず、必要なら列名や安全なレコードIDだけを残してください。
表は横にスクロールできます
| 記録項目 | 例 | なぜ必要か |
|---|---|---|
| 変更元 | script / API / user edit / formula | トリガー方式の選択条件になる |
| 対象範囲 | Orders!A12:F12 | 処理対象を限定し、無関係な変更を除く |
| 実行ID | 呼出元の一意なID | 二重処理の検知・再実行に使う |
| 期待処理 | 通知 / 集計 / 同期 | onEdit以外の経路が必要か明らかにする |
| 結果 | queued / done / failed | 取りこぼしと失敗再開を区別する |
人の編集ならイベント範囲を絞る
人が編集したときだけ動けばよい処理なら、onEdit(e)を使い続けられます。イベントオブジェクトのe.rangeから編集範囲を取得し、対象シート・対象列・行の状態を先に確認します。対象外範囲なら早く終了させます。貼り付けで複数セルが変わるケースもあるため、常に単一セルの値だけが来る前提にしないでください。イベントに値が含まれる場合でも、必要なレコード状態をシートから読み直す方が適切な場合があります。
例えば、注文表の「承認」列を人が更新したときだけ通知したいなら、列番号だけでなく、シート名、行の必須項目、既送信フラグも確認します。空欄の行や別の編集に対して通知を送らないよう、条件を段階的に絞ります。onEditは1編集ごとの確実な大規模キューと同義ではありません。公式資料には単純onEditが短時間に処理待ちできるイベント数の制限も記載されています。大量貼付や連続更新を取りこぼせない要件なら、ユーザー編集トリガーだけに依存せず、未処理行を走査する回収経路を用意します。
Script / API書込みは呼出元で処理する
更新を行うApps Scriptを管理できるなら、書き込みと後処理を同じ入口で実行します。処理の骨格は次のようになります。
function updateRecordAndProcess(recordId, values) {
writeRecord(recordId, values);
processRecordIfNeeded(recordId);
}
この例は設計の説明で、特定のシート構造やAPIをそのまま動かす完成コードではありません。複数の書込経路がある場合は、各経路が共通のprocessRecordIfNeededを通るようにします。後処理を呼ぶ前に書込みが成功したことを確認し、recordIdを使って対象を特定します。処理が失敗したときは書込みまで戻すのか、後処理待ち状態として残すのかを決めておきます。
Sheets APIなど別システムから更新する場合、更新処理の後に同じ処理関数を直接呼べない構成もあります。その場合は、APIを呼び出すサービス側からwebhookや明示的な処理要求を送る、あるいは「未処理」キューを記録し、Apps Script側が定期処理で回収する方式を検討します。ここで追加するWebhookやAPIは、認証、再送、アクセス制御を含めて設計してください。公開URLへ機密情報を無認証で送信するような仕組みを、単にonEditを代替する目的で作ってはいけません。
Installable triggerを選ぶ場面
インストール型トリガーは、認可が必要なサービスを使う場合や、単純トリガーにないイベント・時間主導の実行が必要な場合に候補になります。ただし、インストール型もスクリプト/API更新では起動しない点が重要です。また、トリガーを作成したアカウントの権限で実行されるため、作成者が退職・権限変更した場合の運用や、共有データに対する権限範囲を確認します。インストール型トリガーは作成者アカウントごとに見え方が異なることがあり、割当て可能な実行回数にも上限があります。個人の認証情報を暗黙のシステムアカウントとして扱わないでください。
利用者が直接編集した内容について、メール送信や別ファイル操作のように認可が必要な処理をしたいときは、インストール型編集トリガーが適する場合があります。インストール型を追加する前に、同じ処理が複数アカウントのトリガーで二重実行されないか確認します。複数人がそれぞれ同じトリガーを登録すると、同じ編集に複数の実行が走る設計になり得ます。
Polling / 差分照合を使う場面
値を更新するすべての書込元を変更できないときや、処理の遅れを許容できるときは、時間主導トリガーで未処理行・更新日時・バージョン番号などを定期的に照合する方法があります。Apps Scriptの時間主導トリガーは指定した時間や間隔で処理する機能ですが、実行時刻・実行間隔は監視要件に合わせて選びます。「変更を即時に検知するイベント」ではなく「現在の状態を定期回収する仕組み」です。
Pollingを入れるなら、前回の確認位置、未処理状態、重複実行対策を先に決めます。処理中に失敗した場合に次の実行で再開できるよう、成功記録は処理完了後に保存します。更新日時だけを使う場合は、同じ時刻の更新や時計精度、時刻の書式が誤差にならないかを考えます。可能なら書込元が単調なバージョン番号や一意な処理IDを記録します。対象件数が増えると全行走査は実行時間やサービスの割当てに影響するため、増分範囲と処理単位を制御します。
二重実行と再試行を安全にする
呼出元から処理関数を直接実行する方式と、人のonEditの両方を使う場合、同じレコードが両経路へ入ることがあります。処理関数を冪等にし、同じrecordId・eventIdを再度受け取っても通知や課金、レコード作成を重複させない設計にします。
処理済みかどうかを調べてから処理するだけでは、同時に二つの実行が開始したときの重複を防げない場合があります。書込み中フラグ、ロック、重複を拒否できる永続キーなど、処理方式に合う制御を選びます。Apps Scriptのロック機構を使う場合も、ロック中に長い処理を行わない、ロックを取得できなかった場合の再試行条件を決めるといった設計が必要です。API側が再送する可能性を前提に、成功・失敗・処理中の状態と最後のエラーを記録します。
再試行は失敗した全件を無差別に再送するのではなく、処理副作用の有無で分けます。読取専用の集計と、メール送信・外部レコード追加では重複リスクが異なります。副作用があったか分からない状態なら、再送前に処理先の記録や送信ログを照合します。
要件別の選択表
表は横にスクロールできます
| 要件 | 第一候補 | 注意点 |
|---|---|---|
| 人の単セル・範囲編集に反応 | onEdit(e) | 対象シートと編集範囲を限定し、貼付や連続編集を試験 |
| 人の編集後に認可サービスを利用 | Installable edit trigger | 作成者の認証権限で動く。API書込は拾わない |
| 自分が管理するスクリプト書込の直後に処理 | 書込関数から処理関数を直接呼ぶ | 書込成功、失敗時の状態、冪等性を確認 |
| 外部API更新を即時に処理 | 呼出元から明示的な処理要求 | 認証・署名・再送・重複対策・権限を設計 |
| 書込元を変更できず遅延を許容 | 時間主導Polling / 差分照合 | 遅延、実行時間、重複、最終確認位置を管理 |
| 数式結果を監視 | 入力セル起点、または定期照合 | 数式再計算をセル編集イベントとみなさない |
検証テストと次の行動
実装前に、検証用スプレッドシートかテスト用コピーを使い、変更元別のテスト表を作ります。各テストで「何がトリガーするか」「イベントログに何が残るか」「処理回数」「重複防止結果」「失敗後の再開」を記録します。実データへテスト通知を送る必要がある場合は、通知先をテスト用に分離し、本番利用者へ誤送信しないようにします。
表は横にスクロールできます
| ケース | 実行方法 | 確認する結果 |
|---|---|---|
| 人が1セルを編集 | 対象セルへ値を入力 | onEdit実行、範囲と状態が記録される |
| 人が複数セルを貼付 | テスト行へ範囲貼付 | 対象範囲全体を安全に処理、通知重複なし |
| Apps ScriptでsetValue | テスト関数から書込 | onEditの自動実行を期待せず、明示呼出しが働く |
| Sheets APIで更新 | テストクライアントから更新 | API側通知またはPollingで処理が回収される |
| 数式結果が変化 | 参照元セルを変更 | 数式セル向けイベントを期待せず、選んだ検知方式で処理 |
| 後処理を途中失敗させる | テスト用エラーを発生 | 次回再開位置、処理済みID、二重副作用を確認 |
実際には人の編集なのに動かないなら、対象シートとセル範囲、スクリプトの実行履歴、トリガー設定、認可エラーを調べます。Installable triggerの場合は作成者アカウントと実行権限も確認します。値の変更元がAPIやスクリプトなら、単にトリガーを再登録するのではなく、書込元から処理を呼ぶか、遅延許容のある差分照合へ設計を変えるのが次の一手です。重要なデータ処理では、実行ログの行数と処理済みレコード数を元データと照合し、失敗した分を特定できる状態にしてから本番へ戻します。
引用・データ出典
公式情報を編集部が見た内容です。Hands-on未実施の記述は本文かここに分けています。
確認日:2026年10月15日
- Google Apps Script|Simple Triggers
https://developers.google.com/apps-script/guides/triggers(新しいタブで開く)
- Google Apps Script|Installable Triggers
https://developers.google.com/apps-script/guides/triggers/installable(新しいタブで開く)
- Google Apps Script|Event Objects
https://developers.google.com/apps-script/guides/triggers/events(新しいタブで開く)
この解説は公式仕様と設計判断を分けています。特定のSpreadsheetやTriggerを実際に操作・計測したレポートではありません。実行時間・Quota・認可条件はプロジェクトや利用サービスで確認してください。
