1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[GAS] 具体事例から学ぶScriptAppによるトリガー生成コードサンプル(2)~毎月月末に実行したい場合(毎日の月末判定不要)

Posted at

はじめに

スプレッドシートを始めとしたGoogleのクラウドアプリは、時間主導型トリガー(以降、タイムトリガー)を使用して、定型処理を定期的に自動実行させることができます。

タイムトリガーはUI画面から簡単に設定可能ですが、UIにて設定できる項目が限られているため、要望する内容によってはGASのScriptAppを使ってプログラム側からトリガーを生成する必要があります。

本稿では、UI画面からの設定では対応できない内容について、当方にご相談頂いた内容を元にした事例別の参考コードを不定期連載形式で紹介していきたいと思います。(ネタが溜まってきたら、随時公開予定です)

今回は比較的実装が容易なケースとして、毎月月末に実行したい場合のご紹介です。

前提条件

  1. 仕様上、実行遅延(タイムラグ)がおよそ数分以内のレベルで発生します。そのため、厳密な時間管理が必要な処理には不向きです。(公式にて一部メソッドにおいては±15分と明記されています)
  2. 同様に、仕様上、エラー通知の頻度をスクリプト側で設定できないため、 毎日通知を受け取る がデフォルトとなります。
  3. 拙記事ですが、こちらを参考にタイムゾーンの設定が実行環境と合っているか確認してください。
  4. サンプルコードでは1日あたりの総実行時間、1ユーザーあたり20トリガーまで等、GASの制限事項は考慮していません。

設置時の共通事項

  1. トリガー生成ロジックは独立した関数として定義し、メイン処理内に組み込みます。組み込み位置は末尾を推奨しておきますが、好みや状況に合わせて適宜ご対応ください。
  2. GASの制限事項を考慮し、適宜メイン処理の軽量化、高速化をしましょう。また、実行回数に関係なく、実行済みトリガーの削除処理の実装を推奨します。
  3. 初回のトリガー設定のみ手動で行いますが、設定画面経由でもエディタから当該関数の直接実行でもどちらでも結構です。

比較的実装が容易なケース(2)

毎月月末に実行したい

要望としてはとてもシンプルなのですが、ひとくちに月末と言っても小の月、特に2月や閏年も考慮する必要があります。月ベースのタイマー31日を指定したら自動で調整してくれてもいいようなものですが、そうもいきません。

相談内容としましては、月末を締め日としているクライアント様が、当日の定型処理を自動化したい、というケースがほとんどです。

ロジック

  • Javascriptにて翌月月末の指定日時を設定する
  • ScriptAppにて特定の日時としてトリガーを生成する

前回と同様、当月実行時に翌月の処理を実行予約するイメージとなります。結果、これが毎月繰り返されることで、毎月末日の指定日時(仮に午後23時55分とします)に自動実行されます。

サンプルコード

毎月月末の午後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ステップで月末設定をしています。

  1. 翌月を指定するために現在時からgetMonthしたものに2を足す1
  2. 同様に、末日を指定するために第3引数(date)に 0 を設定する

初回設定

初回はUI画面より特定の日時当月月末の指定時間を設定し、mainを実行させます。以下は現在時が2022年6月23日の場合の設定例です。

  • 実行する関数を選択:main
  • 時間ベースのトリガーのタイプを選択:特定の日時
  • 日時を入力:2022-06-30 23:55

最後に

前回に引き続き、比較的実装が容易なケースとして 毎月月末に実行したい(毎日の月末判定不要)場合 のご紹介をしましたが、もちろん最適解ではございません。

ネット上では毎日トリガーを実行させ、その都度当日が月末かどうかを判定する方法、要するに 月末判定で処理を分岐させる 方法が散見されます。別途、毎日の定型処理があるなら、ついでの処理としては問題ないと思いますが、個人的には、 月末判定のためだけに毎日トリガーを走らせるのは非効率 かと思います。

なお、前回の内容を理解いただけているならすでにお気づきかもしれませんが、つまるところ、targetDate の生成ロジックがポイントとなります。実行間隔が一定 であるか、実行日を特定できる明確な法則(条件) があれば、特定の日時 を使用することで、ほぼほぼご要望内容は実現可能と思います。

誰かのお役に立てたなら幸いです。

[参考・引用]

  1. JavascriptのDateオブジェクトではgetMonthの戻り値は0スタートになります。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?