onEditで特定のシートやセルが変更された時にGASの実行をしたりメールを自動送信したりできると便利です。
ですが、onEditでは実行できない場合もありますので、
onEditで出来る事、出来ない事と出来ない場合の対処法を含め、
onEditの基本的な使い方やサンプルコードなどを解説しています。
onEdit(e)が自動的に実行される条件
GASのonEditは変更・編集時に実行される関数ですが、
GASのスクリプト実行による編集や数式や参照(importrangeなど)の
自動で表示・入力や行列の削除などはonEditが実行されない場合もあります。
onEditが実行されるもの
- 値の入力、コピペ、削除
- マウスドラッグによる連続コピー
- 行列が非表示時の編集
- フィルタ適用時の編集
- 元に戻す(アンドゥ)
元に戻す(アンドゥ)を使用するとonEditの実行はされますが、意図しない動きになることも多く、また全てを戻せるわけではないので注意が必要です。
基本的にユーザーが手動で行った編集はonEditが実行されますが、
数式などの関数を使って表示する場合は実行されないので注意です。
onEditが実行されないもの
- GASスクリプトによる編集
- 数式等での自動参照(importrange,query,filterなど)
- 行もしくは列の削除
GASのonEditで特定のシートの変更時に実行する
onEditで特定のシートの変更・編集時に自動で実行する方法は、
「e.source.getSheetName()」で編集されたシート名を取得して、
if文でシート名が一致していたら実行すれば可能になります。
onEditで特定のシート変更時実行サンプルコード
//evant(e)からアクティブシート名を取得
var sheetName = e.source.getSheetName();
//対象にしたいシート名
var sheetN = 'シート2';
//編集されたシート名と対象にしたいシート名が一致したら実行
if(sheetName === sheetN){
//編集されたセルの行数を取得
var row = e.range.getRow();
//編集されたセルの列数を取得
var col = e.range.getColumn();
//編集された行列がB7だったら実行
if(row === 7 && col === 2){
var sheet = e.source.getActiveSheet();
sheet.getRange('B4').setValue('onEdit実行完了');
sheet2.getRange('B7').setValue('false')
}
}
GASのonEditで特定のセルの変更時に実行する
onEditで特定のセルの変更・編集時に自動で実行する方法は、
「e.range.getRow()」、「e.range.getColumn()」で編集されたセルの行列数を取得して、if文やswitch文で行列が一致していたら実行すれば可能になります。
onEditで特定のセル変更時実行サンプルコード
//編集されたセルの行数を取得
var row = e.range.getRow();
//編集されたセルの列数を取得
var col = e.range.getColumn();
//編集されたセルがC6だったら実行
if(row === 6 && col === 3){
var sheet = e.source.getActiveSheet();
sheet.getRange('C3').setValue('onEdit実行完了');
sheet.getRange('C6').setValue('false')
}
onEditのeventで取得できるオブジェクト
onEditのeventで取得できるものはいくつか種類がありますが、
ここではよく使う代表的なものを解説しています。
全てのオブジェクトを知りたい方はリファレンスをご確認ください
【公式】GASイベントオブジェクトリファレンス
onEditのeventで取得できるオブジェクト | 内容 |
---|---|
e.source.getName() | アクティブスプレッドシートを取得 |
e.source.getActiveSheet() | アクティブシートを取得 |
e.source.getSheetName() | アクティブシート名を取得 |
e.source.getSheetByName('シート名') | シート名を指定して取得 |
e.value | 編集されたセルの値を取得 |
e.range.getValue() | 編集されたセルの値を取得 |
e.oldValue | 編集される前のセルの値を取得 |
e.range.getRow() | 編集されたセルの行数を取得 |
e.range.getColumn() | 編集されたセルの列数を取得 |
//evant(e)からアクティブスプレッドシートを取得
var ss = e.source.getName();
//evant(e)からアクティブシートを取得
var sheet = e.source.getActiveSheet();
//evant(e)からアクティブシート名を取得
var sheetN = e.source.getSheetName();
//evant(e)からシート名を指定して取得
var sheet1 = e.source.getSheetByName('シート1');
//編集されたセルの値を取得
var value1 = e.value;
var value2 = e.range.getValue();
//編集される前のセルの値を取得
var oldvalue = e.oldValue;
//編集されたセルの行数を取得
var row = e.range.getRow();
//編集されたセルの列数を取得
var col = e.range.getColumn();
GASの特定のイベント発生で動くシンプルトリガー
GASで使用できるシンプルトリガーはonEditの他にもあり、
全部で6種類のシンプルトリガーがあります。
シンプルトリガー | 内容 |
---|---|
onOpen(e) | スプレッドシートを開いた時 |
onInstall(e) | アドオンのインストールがされた時 |
onEdit(e) | スプレッドシートが編集された時 |
onSelectionChange(e) | スプレッドシートの選択を変更した時 |
doGet(e) | Webアプリにアクセスした時 |
doPost(e) | Webアプリに送信する時 |
よく使用するのは、編集時に実行されるonEdit()、
メニュー追加などで使われるonOpen()の2つです。
各シンプルトリガーの詳細を知りたい方は公式で確認してみてください。
【公式】GASシンプルトリガーリファレンス
GASのonEditが動かない原因3選
GASのシンプルトリガーであるonEditは、作成したのに思った通りに動かない!という事がよくあります。
動かない原因を突き止める方法は、ログを確認してエラーが出ているか出ていないかでまずは判断することができます。
エラーが出ている場合は
権限の問題やタイムアウトなどが原因になっていることが多く、
エラーが出ていない場合は特定のシートやセルの編集時に実行されるGASコードになっていて、実行対象のセルになっていないなどが考えられます。
その場合はGASのコードを確認してみてください。
ここでは、よくある動かない原因をまとめました。
onEdit(e)のGASが複数ある
onEdit(e)の関数名が複数あると、どちらかのGASスクリプトのみ実行されます。
これはonEditに限った話ではなく、同じ関数名で複数のGASスクリプトを作成していると、思いもよらないバグが起こったり、処理が実行されなかったりするため、注意してください。
GASの初期値関数名はmyFunctionとなっているので、変更せずにそのまま作成すると、myFunctionが複数存在することになってしまうため、
GASを作成する時は毎回、関数名の変更をするのがおすすめです。
onEditで対象のシートやセルになっていない
onEditで特定のシートや特定のセル編集時のGASコードを組んでいる場合、
コードが間違っていたり、該当のシートやセルの編集をしなければ思ったように実行されません。
onEditで特定のシートやセルの編集時の設定をする時の範囲設定は、
A1やB2などの指定方法ではなく、行1列1などの数値で設定することがほとんどなので、列の設定数値が間違っている事がよくありますので、
該当のコードを確認してみてください。
列の番号は関数でも取得表示して確認する事ができます。
列番号を表示させる関数は「COLUMN()」です。
該当のセルに「COLUMN()」の関数を入れて確認してみてください。
別のスプレッドシートを参照している
GASのシンプルトリガーであるonEdit(e)は別のスプレッドシートの参照をする事ができません。
openById()、openByUrl()などの別シートを参照するメソッドは実行されずエラーになってしまうので、別シートを参照したい場合は後述する対処法を行う必要があります。
権限が必要な処理をしている(Gmail、line、ChatWork送信など)
onEdit()メソッドの権限は一番低いものが設定されているため、getActiveSpreadsheet()、getActiveSheet()などのメソッドしか使用できません。
先に書いている別シートの参照や、Gmail送信、LineやChatWork、Slack等の外部サービスとの連携や、その他権限取得が必要になってくるメソッドの場合、権限が取得できずエラーになってしまいます。
後述する対処法で対応してみてください。
処理の時間がかかっている
GASの実行は基本的には6分で強制終了となりますが、シンプルトリガーのonEditの場合、
30秒程度を過ぎるとタイムアウトとなり実行されずエラーになってしまうようです。
シンプルなGASコードにしていても、何かの理由で処理に時間がかかってしまっていたりして、いつもはうまく実行できているのにエラーになってしまうということが稀にあります。
長い処理時間を要するものや、時間ギリギリのGASコードの場合は、
処理をシンプルにしたり、他の方法で実行させるなどの対処が必要ですが、
稀になぜかエラーになるという原因不明の場合はGASのご機嫌次第となってしまい、対処する事ができません。
頻繁に起こることではないですが、そういうこともあるということを知っておいてください。
GASのonEditが動かない時の対処法
権限の問題等でonEditが動かない場合、別で権限を取得したとしてもonEditでは実行できるようになりませんが、
onEditを使用せずトリガーを使用することで対処する事ができます。
権限が必要なものは事前に取得しておく必要があり、権限はスプレッドシート毎に取得が必要です。
トリガーで設定できるものはいくつかありますが、
スプレッドシートの編集時に設定することで、onEditと同じ動きをさせる事が可能です。
また、トリガーで変更時にするとセルの値が変更された時のみ実行させる事ができるため、セルの変更時のみ実行させたい場合は変更時にすると便利です。
GASでonEditを使用する時の注意点
onEditは編集時に自動実行されるシンプルトリガーなので、
複数人で編集をしていたり、処理が追いつかない速度での編集時など、
予期しないバグが起こる事があります。
これを回避するためにはなるべくonEditを使用せず、トリガー起動する方法をとるのがおすすめです。
特に複数人で共有して編集している時は注意が必要です。
また、トリガーを設定して複数人で編集する場合は設定したアカウントでしか実行できない点も知っておいてください。
トリガー設定でGASが動かない原因5選
onEditが使えないならトリガーを使おう!と設定してみても思ったように動かない場合があります。
ここでは、トリガー設定時によくある動かないトラブルをまとめました。
権限の取得が必要な処理をしている
権限の取得が必要なGASメソッドを実行する場合、事前に権限取得が必要になってきます。
権限の問題で動かないよくあるものは、
別シートの参照、Gmailの送信、Lineやchatworkなどの外部連携時、など、権限が設定されているほとんどのメソッドが当てはまります。
トリガーが権限の問題で動かない場合は、事前に取得することでエラー回避できますが、スプレッドシート毎に権限の取得が必要になります。
権限の取得方法の詳細はまた記事にしていく予定です!
V8ランタイムが有効になっている
Google Apps Script(GAS)のV8ランタイムは2020年2月からサポートされるようになり、現在新規のプロジェクトは全てデフォルトでV8ランタイムが有効化されています。
【公式】V8ランタイムについてのリファレンス
V8ランタイムでは使用できる変数(let,constなど)が増えたり、
map()、filter()、reduce()メソッドなどが使用できるようになり、便利ではあるのですが、トリガー設定時になぜかうまく動かないという場合があります。(全てではないのでバグかもしれません)
V8ランタイムが必要なメソッドを使用していない場合はオフにすることで改善できる事があります。
時間がかからないはずなのにタイムアウトエラー
onEditのトラブルのところでも書きましたが、シンプルなコードにしていたとしても、
なぜか処理に時間がかかって起動時間制限を超えてしまい、強制終了のタイムアウトエラーになってしまう事があります。
普段は問題なく実行できている場合でも、稀に起こるエラーとなりますが、
明らかに時間がかからないGASの場合はGASのご機嫌次第となってしまい対処する事ができないので、稀にこういう事が起こる場合もあると知っておいてください。
オーナー以外のユーザーによる実行
GASでトリガー設定したらトリガー設定したアカウントのみで使用可能になります。
複数人で共有したシートを使用したりしていると、それぞれのアカウントでトリガーの設定を行う必要があり、トリガーを設定していないアカウントでは当然ですが動きません。
複数人で共有して使用する場合は注意してください。
ファイルが読み取り専用になっている
スプレッドシートを共有して使用するなどの場合、表示権限が閲覧者(読み取り専用)になっているとそもそも編集もできませんし、GASが実行されることもありません。
共有する場合は、表示権限の設定を確認が必要になってきます。
コピペで使えるonEditサンプルコード
onEditで指定シートが変更・編集されたら実行
function onEdit(e) {
//evant(e)からアクティブシート名を取得
var sheetName = e.source.getSheetName();
//対象にしたいシート名を入力
var sheetN = 'シート名を入力';
//編集されたシート名と対象にしたいシート名が一致したら実行
if(sheetName === sheetN){
//ここに行いたい処理を記入
//行いたい処理ここまで
}
}
onEditで指定シートの指定セルが変更・編集されたら実行
function onEdit(e) {
//対象にしたいシート名を入力
var sheetN = 'シート名を入力';
//指定したいセル(A1など)を入力
var range = 'ここに指定したいセルを入力';
//evant(e)からアクティブシート名を取得
var sheetName = e.source.getSheetName();
//編集されたセルの行数を取得
var row = e.range.getRow();
//編集されたセルの列数を取得
var col = e.range.getColumn();
//指定セル範囲の行列数取得
var rowlength = sheet.getRange(range).getValues().length;
var collength = sheet.getRange(range).getNextDataCell(SpreadsheetApp.Direction.NEXT).getColumn();
//編集されたシート名と対象にしたいシート名が一致したら実行
if(sheetName === sheetN){
//編集されたセルが指定セルだったら実行
if(row === rowlength && col === collength){
var sheet = e.source.getActiveSheet();
//ここに行いたい処理を記入
//行いたい処理ここまで
}
}
}
行列数の取得方法についてはこちらで解説しています。
【GAS】スプレッドシートで行列取得まとめ、最終行列、getLastrow、getLastcol【Google Apps Script】
onEditで指定セルが変更・編集されたら実行(if文)
function onEdit(e) {
//指定したいセル(A1など)を入力
var range = 'ここに指定したいセルを入力';
//編集されたセルの行数を取得
var row = e.range.getRow();
//編集されたセルの列数を取得
var col = e.range.getColumn();
//指定セル範囲の行列数取得
var rowlength = sheet.getRange(range).getValues().length;
var collength = sheet.getRange(range).getNextDataCell(SpreadsheetApp.Direction.NEXT).getColumn();
//編集されたセルが指定セルだったら実行
if(row === rowlength && col === collength){
var sheet = e.source.getActiveSheet();
//ここに行いたい処理を記入
//行いたい処理ここまで
}
}
onEditで指定複数セルが変更・編集されたら実行(switch文)
function onEdit(e) {
//指定したいセル列数(Aなら1、Bなら2)を入力
var colIdx = 'ここに指定したい列数を数字で入力';
//編集されたセルの行数を取得
var row = e.range.getRow();
//編集されたセルの列数を取得
var col = e.range.getColumn();
//編集されたセルが対象の列だったら実行
if(col === colIdx){
switch(collength){
case 1: //ここに指定したい行数を数字で入力(10行目なら「case 10:」)
////ここに行いたい処理を記入
case 2: //ここに指定したい行数を数字で入力
////ここに行いたい処理を記入
case 3: //ここに指定したい行数を数字で入力
////ここに行いたい処理を記入
}
}
}
swichについての詳しい解説はこちら
【GAS】switchのcaseで複数処理、GASで複数分岐まとめ【Google Apps Script】
onEditで特定シートやセルの編集で実行されるサンプルデータ
onEditのサンプルデータはこちらからダウンロードしてください
【Copori】onEditで自動実行サンプル
onEditサンプルデータの使用方法
1、【Copori】onEditで自動実行サンプルを開いてコピーしてください
3、メニューから「拡張機能」⇨「Apps Script」を開きます
※複数アカウントでログインしているとエラーで開けないので注意してください
4、権限取得.gsを手動実行して権限を取得してください
権限の取得方法はこちら
4、シート1、シート2の「onEdit()を実行」のチェックボックスにチェックを入れるとonEditが実行されます。
このサンプルコードでは、実行結果に「onEdit実行完了」と入力するようになっています。
GASにコピーして使えるサンプルコードも入っています。
5、初期化する時は、C9のチェックボックスにチェックを入れてください
(実行完了すると、シート1、シート2の実行結果のセルが空欄になってC9のチェックが外れます)
onEditサンプルデータの詳細
【Copori】onEditで自動実行サンプルに入っているGASは7つです。
- onEdit.gs
- 【参照用】eventSample .gs
- 権限取得用.gs
- コピペ用onEdit指定シート.gs
- コピペ用onEdit指定シート&セル.gs
- コピペ用onEdit指定セル.gs
- コピペ用onEdit指定複数セル.gs
【onEdit.gs】
このサンプルデータのメインGASです。
onEditでシートの変更・編集により実行されます。
【【参照用】eventSample .gs 】
onEditのeventから使えるメソッドをまとめています。
参照ようなので実行してもエラーになります。
適宜コピーしてご使用ください。
【権限取得用.gs 】
基本的に権限取得をしないとonEditの使用はできないため、
権限取得をするためだけに入れているGASです。
このGASを開いて手動実行すると、権限取得する事ができます。
権限の取得方法はこちら
【コピペ用onEdit指定シート.gs 】
【コピペ用onEdit指定シート&セル.gs 】
【コピペ用onEdit指定セル.gs 】
【コピペ用onEdit指定複数セル.gs 】
この4つはこの記事でも紹介しているコピペ用のサンプルコードが入っています。
記事よりもGASのエディタの方が見やすい方もいると思いますので入れてあります。
GASを含め、すべてのプログラム言語がそうですが、
実際に動かして触ってみないと処理が分からなかったり使えないので、
サンプルデータで実際に動かして確認してみてください。
ありがとうございました!
コメント