Google Apps Scriptで日付関連の処理を関数化する例とその際のポイント


component

photo credit: blairwang Find Your View via photopin (license)

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

GASでGoogleカレンダーにまとめてイベントを登録できるツールを作成しています。

前回の記事はこちら。

Google Apps ScriptでDateオブジェクトの複製や時刻のセットで注意すること
GASでGoogleカレンダーに複数の予定を簡単に登録できるツールを作成しています。今回はGoogle Apps ScriptでDateオブジェクトの複製や時刻のセットで注意することについてお伝えします。

イベントの登録に必要なスプレッドシートの入力は簡単にできる一方で、日付関連の処理にコツが必要だったので、それについて解説をしました。

今回はその続きで、若干複雑化したスクリプトを関数化することで、よりシンプルにしていきます。

Google Apps Scriptで日付関連の処理を関数化する例とそのポイントについて解説をしていきます。

では、行ってみましょう!

前回のおさらい

Googleカレンダーに登録するイベントを入力するスプレッドシートは以下のようなものです。

スプレッドシートの構成を変更

そして、このスプレッドシートの入力をもとに、デフォルトカレンダーにイベントを登録するスクリプトはこちらです。

function createEvents() {
  const calendar = CalendarApp.getDefaultCalendar();
  const values = SpreadsheetApp.getActiveSheet().getDataRange().getValues();
  values.shift();
  
  for(const record of values){
    const title = record[0];
    const time = new Date(record[2]);
    const delta = new Date(record[3]);

    const startTime = new Date(record[1]);

    startTime.setHours(time.getHours());
    startTime.setMinutes(time.getMinutes());

    const endTime = new Date(startTime);

    endTime.setHours(endTime.getHours() + delta.getHours());
    endTime.setMinutes(endTime.getMinutes() + delta.getMinutes());

    const option = {
      description: record[4],
      location: record[5]
    }
    calendar.createEvent(title, startTime, endTime, option);    
  }
}

全体的にDateオブジェクト関連の若干ややこしめの処理が入りました。

このあたりを関数として部品化することで、シンプルなコードに変更していきたいと思います。

なお、関数の作り方は以下の記事を復習しておいてくださいね。

【初心者向けGAS】Google Apps Scriptで別の関数を呼び出すfunctionの書き方
Google Apps ScriptでBotを作りながらその基本を学ぶシリーズです。今回は、関数から別の関数を呼び出す方法です。functionの書き方、引数、仮引数、戻り値などについても解説します。

ところで、前回のコードと少し手を加えているのですが…気が付きますか?

その変更点が、今回進める部品化をしやすくしています。

共通部分を関数化する

さて、スクリプトですが、よくご覧いただくと、11~14行目と、16~19行目って、処理として似ていますよね…?

処理として似ているところは、うまくやると共通化して外に出す、つまり関数化することができます。

  • 11~14行目
    1. record[1]をベースにDateオブジェクトを生成しstartTimeに代入
    2. timeの時間、分をセットする
  • 16~19行目
    1. startTimeをベースにDateオブジェクトを生成しendTimeに代入
    2. endTimeにdeltaの時間、分をそれぞれ加算する

ちょっと文面が違うので、工夫して同じ文面に揃えてみちゃいましょうか。

  • 11~14行目
    1. record[1]をベースにDateオブジェクトを生成しstartTimeに代入
    2. timeの時間、分をセットして
    3. 0時間0分を加算する
  • 16~19行目
    1. startTimeをベースにDateオブジェクトを生成しendTimeに代入
    2. endTimeの時、分をセットして
    3. deltaの時間、分を加算する

なんか揃いましたね。

どちらかに不足している部分があれば、両方で辻褄が合うように揃えればOKです。例えば、「加算する」がどちらかになければ、そちらは「0を加算する」とすれば良いわけです。

このように似ている処理は共通化することができます。

共通部分を関数化したスクリプト

この考えのもと、別関数として部品化したのが以下のスクリプトです。

function createEvents() {
  const calendar = CalendarApp.getDefaultCalendar();
  const values = SpreadsheetApp.getActiveSheet().getDataRange().getValues();
  values.shift();
  
  for(const record of values){
    const title = record[0];
    const date = new Date(record[1]);
    const time = new Date(record[2]);
    const delta = new Date(record[3]);

    const startTime = setTimeDelta(new Date(date), time);        
    const endTime = setTimeDelta(new Date(startTime), time, delta); 

    const option = {
      description: record[4],
      location: record[5]
    }
    calendar.createEvent(title, startTime, endTime, option);    
  }
}

/*
 * 日付のみのDateオブジェクトに与えられた時刻をセットしさらに時間の加算をする
 *
 * @param {Date} 日付を表すDateオブジェクト
 * @param {Date} 時刻を表すDateオブジェクト
 * @param {Date} 加算する時間を表すDateオブジェクト、デフォルトはnew Date(0,0,0,0,0,0);
 * @return {Date} 日付をベースに、時刻をセットし、加算する時刻を加算したDateオブジェクト
 */
function setTimeDelta(date, time, delta){

  if(!delta) delta = new Date(0,0,0,0,0,0);
  
  date.setHours(time.getHours() + delta.getHours());
  date.setMinutes(time.getMinutes() + delta.getMinutes());
  return date;
}

関数createEventsでは、startTime、endTimeを求める部分はそれぞれ1行にまとめることができました。

そして、それらを求めるための関数がsetTimeDeltaですね。

なお、関数setTimeDeltaで第1引数のDateオブジェクトについては、setHoursメソッド、setMinutesメソッドの対象としますので、ここでもちゃんとnewキーワードで生成したものを渡すという点が注意としてありますよ。

関数setTimeDeltaの役割

関数setTimeDeltaは、ドキュメンテーションコメントを入れている通り

  • 日付のベースとなるDateオブジェクト
  • セットをする時刻を表すDateオブジェクト
  • さらに加算する時刻を表すDateオブジェクト

の3つの引数を渡すと、ベースの日付に時刻をセットし、さらに加算する時刻を加算したDateオブジェクトを返す関数になります。

if文でdeltaが与えられなかったときは、deltaはundefined、真偽値判定ではfalseになりますので、そのときはすべての要素が0のDateオブジェクトを加算するという考え方ですね。

まとめ

以上、Google Apps Scriptで日付関連の処理を関数化する例とその際のポイントについてお伝えしました。

このように、処理が似ているところは、積極的に関数化することでスクリプトをシンプルにすることができますし、関数の再利用も可能になります。

とくにDateオブジェクト周りは処理が複雑になりがちなので、積極的に関数化を狙っていきたいですね。

次回、関数addTimeで使っているテクニックである、引数の省略について解説します。

Google Apps Scriptで関数の引数を省略した場合の挙動とデフォルト値の設定方法
GASでGoogleカレンダーの複数の予定をまとめて登録するツールを作成しています。今回は、Google Apps Scriptで関数の引数を省略した場合の挙動とデフォルト値の設定方法についてです。

どうぞお楽しみに!

連載目次:GASでカレンダーイベントをまとめて追加するツールを作る

Googleカレンダー便利ですよね!ただ、複数のイベントをいくつも追加しなければいけないとき…少し面倒です。そんなときのための便利ツールとして、スプレッドシートの入力情報をもとにカレンダーイベントをまとめて追加するツールを作成していきます。
  1. GASでデフォルトのGoogleカレンダーにイベントを追加する簡単なスクリプト
  2. GASでスプレッドシートの入力からGoogleカレンダーに複数のイベントを追加
  3. Google Apps ScriptでDateオブジェクトの複製や時刻のセットで注意すること
  4. Google Apps Scriptで日付関連の処理を関数化する例とその際のポイント
  5. Google Apps Scriptで関数の引数を省略した場合の挙動とデフォルト値の設定方法

  投稿者プロフィール

タカハシノリアキ株式会社プランノーツ 代表取締役
株式会社プランノーツ代表、コミュニティ「ノンプロ研」主宰。1976年こどもの日生まれ。東京板橋区在住。「ITで日本の『働く』の価値を上げる!」をテーマに、VBA&GASの開発、講師、執筆などをしております。→詳しいプロフィールはコチラ
★ご依頼・ご相談はお気軽にどうぞ!→お問い合わせはコチラ
★フォロー頂ければ嬉しいです。

タイトルとURLをコピーしました