みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。
GASでGoogleカレンダーに複数の予定を簡単に登録できるツールを作成しています。
前回の記事はこちら。
スプレッドシートの情報をもとに、カレンダーにイベントを複数追加するスクリプトを作成しました。
…え、まだ何かやることあるの?
というふうに思われるかもしれませんが、イベントのデータの準備をもっと楽にできるんです。
ただ、それに伴って、ちょっとDateオブジェクトの使い方を気にする必要があります。
ということで、今回はGoogle Apps ScriptでDateオブジェクトの複製や時刻のセットで注意することについてお伝えします。
では、行ってみましょう!
前回のおさらい
前回作成したスクリプトはこちらです。
function createEvents() { const calendar = CalendarApp.getDefaultCalendar(); const title = '研修1回目'; const startTime = new Date('2020/4/1 10:00:00'); const endTime = new Date('2020/4/1 12:00:00'); const option = { description: 'イントロダクション', location: '〒105-0011 東京都港区芝公園4丁目2−8' } calendar.createEvent(title, startTime, endTime, option); }
バインドしているスプレッドシートのアクティブシートのイベントをカレンダーにまとめて追加することができます。
それで、そのスプレッドシートがこちらでした。
日時と開始時間、期間を入力データとしたい
で、作ってみてちょっと思うことがあるんですね。
B列の開始時間と、C列の終了時間。
年、月、日、時、分を同じセルに入力しなければいけません。
…ちょっと面倒ですよね?
それで、例えば以下のようなスプレッドシートのほうが入力しやすいと思うのです。
日付と開始時間、そして期間が決まれば、終了時間も決まりますもんね。
日付と開始時間、期間からカレンダーイベントを追加するスクリプト
それで、変更後のスプレッドシートに合わせてスクリプトも変更しました。
こちらです。
function createEvents() { const calendar = CalendarApp.getDefaultCalendar(); const values = SpreadsheetApp.getActiveSheet().getDataRange().getValues(); values.shift(); for(const record of values){ const title = record[0]; const startTime = new Date(record[1]); const time = new Date(record[2]); const delta = new Date(record[3]); 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オブジェクトですね。
オブジェクトを複製したいならnewしよう
まず、8~10行目が日付、開始時間、期間をそれぞれDateオブジェクト化して、定数startDate、time、deltaに格納しています。
startDateには年、月、日までのデータしかないので、12,13行目でtimeの時、分をセットします。
15行目で、新たなDateオブジェクトを生成して定数endTimeにセットしています。
この部分、newキーワードを使わずに、うっかり以下のようにしたくなりますが…
const endTime = startTime; endTime.setHours(endTime.getHours() + delta.getHours()); endTime.setMinutes(endTime.getMinutes() + delta.getMinutes());
これで実行すると、実はstartTimeがendTimeと同じ日時にセットされちゃいます。
Dateオブジェクトをはじめ、オブジェクトを変数や定数にセットした場合、そのオブジェクトへの参照をセットすることになります。
物理的にメモリの別の場所にオブジェクトを複製するのではなくて、同じオブジェクトを表すことになっちゃうんですね。
ですから、startTime、endTimeはいずれも同じDateオブジェクトを参照することになっているのです。
なので、別のDateオブジェクトを生成したいのであれば、ちゃんとnewキーワードを使って新たに生成しないと駄目なんです。
別のDateオブジェクトの時、分をセットする
Dateオブジェクトの時間や分を変更したいのであれば、setHoursメソッド、setMinutesメソッドを使って、時や分を数値で指定してあげます。
Dateオブジェクト.setMinutes(分)
それで、別のDateオブジェクトの時間や分を参照してセットしたいのであれば、スクリプト内にあるように、以下のようにすることになります。
Dateオブジェクト.setMinutes(Dateオブジェクト2.getMinutes())
getHoursメソッドやgetMinutesメソッドはDateオブジェクトの時間や分を数値で取得するメソッドです。
ちょっと回りくどいですが、GASの時刻の取り扱いではこのような使い方は比較的使いますので、マスターしちゃいましょう。
今回は、秒単位でスプレッドシートのデータを準備することを想定していませんが、万が一秒単位が必要であれば、setSecondsメソッド、getSecondsメソッドも使用する必要があります。
まとめ
以上、Google Apps ScriptでDateオブジェクトの複製や時刻のセットで注意することについてお伝えしました。
カレンダー以外にも、スプレッドシートやフォームなどで日時の取り扱いは比較的起こりえます。
GASのDateオブジェクトの取り扱いでは、複製をしたいとき、時刻をセットしたいときに、若干のコツがいりますのでつかんでおくと良いですね。
次回は、今回作成した処理を関数化してみたいと思います。
どうぞお楽しみに!