みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。
GASでGoogleカレンダーにまとめてイベントを登録できるツールを作成しています。
前回の記事はこちら。
イベントの登録に必要なスプレッドシートの入力は簡単にできる一方で、日付関連の処理にコツが必要だったので、それについて解説をしました。
今回はその続きで、若干複雑化したスクリプトを関数化することで、よりシンプルにしていきます。
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オブジェクト関連の若干ややこしめの処理が入りました。
このあたりを関数として部品化することで、シンプルなコードに変更していきたいと思います。
なお、関数の作り方は以下の記事を復習しておいてくださいね。
ところで、前回のコードと少し手を加えているのですが…気が付きますか?
その変更点が、今回進める部品化をしやすくしています。
共通部分を関数化する
さて、スクリプトですが、よくご覧いただくと、11~14行目と、16~19行目って、処理として似ていますよね…?
処理として似ているところは、うまくやると共通化して外に出す、つまり関数化することができます。
- 11~14行目
- record[1]をベースにDateオブジェクトを生成しstartTimeに代入
- timeの時間、分をセットする
- 16~19行目
- startTimeをベースにDateオブジェクトを生成しendTimeに代入
- endTimeにdeltaの時間、分をそれぞれ加算する
ちょっと文面が違うので、工夫して同じ文面に揃えてみちゃいましょうか。
- 11~14行目
- record[1]をベースにDateオブジェクトを生成しstartTimeに代入
- timeの時間、分をセットして
- 0時間0分を加算する
- 16~19行目
- startTimeをベースにDateオブジェクトを生成しendTimeに代入
- endTimeの時、分をセットして
- 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で使っているテクニックである、引数の省略について解説します。
どうぞお楽しみに!