はじめに
スプレッドシートを始めとしたGoogleのクラウドアプリは、時間主導型トリガー(以降、タイムトリガー)を使用して、定型処理を定期的に自動実行させることができます。
タイムトリガーはUI画面から簡単に設定可能ですが、UIにて設定できる項目が限られているため、要望する内容によってはGASのScriptApp
を使ってプログラム側からトリガーを生成する必要があります。
本稿では、UI画面からの設定では対応できない内容について、当方にご相談頂いた内容を元にした事例別の参考コードを不定期連載形式で紹介していきたいと思います。(ネタが溜まってきたら、随時公開予定です)
今回は比較的実装が容易なケースとして、毎月月末に実行したい場合のご紹介です。
設置時の共通事項
- トリガー生成ロジックは独立した関数として定義し、メイン処理内に組み込みます。組み込み位置は末尾を推奨しておきますが、好みや状況に合わせて適宜ご対応ください。
- GASの制限事項を考慮し、適宜メイン処理の軽量化、高速化をしましょう。また、実行回数に関係なく、実行済みトリガーの削除処理の実装を推奨します。
- 初回のトリガー設定のみ手動で行いますが、設定画面経由でもエディタから当該関数の直接実行でもどちらでも結構です。
比較的実装が容易なケース(2)
毎月月末に実行したい
要望としてはとてもシンプルなのですが、ひとくちに月末と言っても小の月、特に2月や閏年も考慮する必要があります。月ベースのタイマーで31日を指定したら自動で調整してくれてもいいようなものですが、そうもいきません。
相談内容としましては、月末を締め日としているクライアント様が、当日の定型処理を自動化したい、というケースがほとんどです。
ロジック
- Javascriptにて翌月月末の指定日時を設定する
-
ScriptApp
にて特定の日時としてトリガーを生成する
前回と同様、当月実行時に翌月の処理を実行予約するイメージとなります。結果、これが毎月繰り返されることで、毎月末日の指定日時(仮に午後23時55分とします)に自動実行されます。
サンプルコード
// 初期設定用オブジェクト
function init(){
return {
START_TIME: '23:55', // hh:mm形式で指定
TRIGGER_HUNDLER: 'main' // 自動実行対象の関数名
};
}
// メイン処理
function main() {
/* メイン処理省略 */
setTrigger();
}
// トリガー生成処理
function setTrigger() {
const now = new Date();
const INIT = init();
const startTime = INIT.START_TIME.split(':');
const targetDate = new Date(now.getFullYear(), now.getMonth()+2, 0, startTime[0]*1, startTime[1]*1);
ScriptApp.newTrigger(INIT.TRIGGER_HUNDLER)
.timeBased()
.at(targetDate)
.create();
}
ポイントは表題の通り、月末の取得方法になります。以下のような2ステップで月末設定をしています。
- 翌月を指定するために現在時から
getMonth
したものに2を足す1 - 同様に、末日を指定するために第3引数(date)に
0
を設定する
初回設定
初回はUI画面より特定の日時で当月月末の指定時間を設定し、main
を実行させます。以下は現在時が2022年6月23日の場合の設定例です。
- 実行する関数を選択:main
- 時間ベースのトリガーのタイプを選択:特定の日時
- 日時を入力:2022-06-30 23:55
最後に
前回に引き続き、比較的実装が容易なケースとして 毎月月末に実行したい(毎日の月末判定不要)場合 のご紹介をしましたが、もちろん最適解ではございません。
ネット上では毎日トリガーを実行させ、その都度当日が月末かどうかを判定する方法、要するに 月末判定で処理を分岐させる 方法が散見されます。別途、毎日の定型処理があるなら、ついでの処理としては問題ないと思いますが、個人的には、 月末判定のためだけに毎日トリガーを走らせるのは非効率 かと思います。
なお、前回の内容を理解いただけているならすでにお気づきかもしれませんが、つまるところ、targetDate
の生成ロジックがポイントとなります。実行間隔が一定 であるか、実行日を特定できる明確な法則(条件) があれば、特定の日時 を使用することで、ほぼほぼご要望内容は実現可能と思います。
誰かのお役に立てたなら幸いです。
[参考・引用]
- Class ClockTriggerBuilder | Apps Script | Google Developers
- [GAS] 簡単になったGAS実行環境のタイムゾーン設定
- Quotas for Google Services | Apps Script | Google Developers
-
JavascriptのDateオブジェクトでは
getMonth
の戻り値は0スタートになります。 ↩