【GAS】大量の予定をGoogleスプレッドシートから簡単にGoogleカレンダーに登録しよう

#この記事を読んで習得できること
・カレンダーに追加したい大量の予定をスプレッドシートから**一括登録**出来るようになる

#この記事を読んだあなた！
###まずはこの画面のどこかにあるLGTM押してください！
#####（最後まで読んで、「そうでもねえな」って思ったらLGTM消していいです笑）

#背景
プロフィールにも書いてあるように、自分は競馬が好きだ。
日本の競馬のみならず、海外の競馬も見たい。
が、海外の競馬は基本的に夜行われているので、結構忘れてしまっている。

なので、忘れないように、googleカレンダーに予め記録しておいて、
毎日確認出来るようにしたかった。

また、海外の競馬といっても、世界各地で行われていて、
一つずつ地道に登録していくのもなかなか骨が折れる。
なので、googleスプレッドシートに全て記載して、
Google Apps Script使って一気にカレンダーに登録してやろうと思った。

#そのカレンダーがこちら
https://calendar.google.com/calendar/embed?src=7pv3mcieh1iqcnl9klgc2ght8g%40group.calendar.google.com&ctz=Asia%2FTokyo

現在73レース登録している。これからもまだまだ追加予定。
手入力なんてしてられないよ…

#とにかく実装
何はともあれ、まずは実装方法見たいよね。

まず、今回使うスプレッドシートはこちら。
![スクリーンショット 2020-07-30 21.46.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389553/eaffdf92-bcd5-c5df-65f0-d1841013d0d1.png)

時間のところは空いてるけど、今回は使用しないので気にせず。
（将来的に使用するから書いておいた）

今回は、このデータをこんな感じで使用することにした。

|項目|使用値（シート列）|
|:----------------:|:-----------------:|
|タイトル|レース名（A列）|      
|日付|日付（B列）|     
|場所|国名（E列） + 競馬場（D列）|     
|説明|グレード（F列）|  

また、G列がDoneまみれになっているが、これは後で説明します。

早速コードを書いてみる。

（コードに色つけたかったので
コード.gs→コード.js
としています）

```コード.js
// スプレッドシートのIDは、スプレッドシートのURLから確認できます
// https://docs.google.com/spreadsheets/d/"{スプレッドシートのID}"/edit#gid=0

// カレンダーIDは「カレンダー」→「設定」→「マイカレンダーの設定」から追加したいカレンダーを選択
// →「カレンダー ID」があるのでそれを使用する

const spreadSheet = SpreadsheetApp.openById("{スプレッドシートのID}")
const calendar = CalendarApp.getCalendarById('xxxxxxxxxxxxxx@group.calendar.google.com')
const sheet = spreadSheet.getSheetByName('シート名')
  
function createEvents() {
  // スプレッドシートの記載されている最終行を取得
  const listLastRow = sheet.getLastRow();
  
  for(var i = 1 ; i < listLastRow; i++) {
    // タイトル
    const title = sheet.getRange(i + 1, 1).getValue()
    // カレンダーに追加されているかを判定するために使う
    const isAdd = sheet.getRange(i + 1, 7).getValue()

    // isAddが'Done'（追加済という意味）もしくはtitleが登録されていない場合、この行をパスする
    if(isAdd == 'Done' || title == '') {
      continue
    }

    // timeだけど今回は日付
    const time = new Date(sheet.getRange(i + 1, 2).getValue())
    // 説明
    const description = sheet.getRange(i + 1, 6).getValue()
    // 国名
    const country = sheet.getRange(i + 1, 4).getValue()
    // 競馬場
    const raceCourse = sheet.getRange(i + 1, 5).getValue()

    // オプション（説明と場所はここに定義する）
    const option = {
      description: description,
      location: country + " " + raceCourse,
    }

    // カレンダーに追加する（全日追加する）
    calendar.createAllDayEvent(title, time, option)

    // 追加したことを記録しておくためにG列に'Done'を記載
    sheet.getRange(i + 1, 7).setValue('Done')
  }
}

```

`calendar.createAllDayEvent(title, time, option)`で、
タイトルと時間、オプションをカレンダーに記録する。
ちなみに、optionは使用しなくてもいい。

今回は全日で登録するが、もし、時間指定したかったら、
時間指定でやりたかったが、
`calendar.createEvent(title, startTime, endTime)`
を使おう。
（option使いたかったら、
`calendar.createEvent(title, startTime, endTime,option)`
みたいに追加する。）

詳しいことはドキュメントに書いてあるからそれを見てくれればいいと思います。


#コードが書けたら
ここまで作ったら、`createEvents()`を実行する。
初めてなら、いろいろ連携についての確認Viewが出ると思うが、OKOKしていけばいい。

これで実行完了されるはず。
カレンダーに追加されたことが確認できると思う。

もう一度、`createEvents()`を実行しても、カレンダーには新たに追加されないと思う。
これは、G列のDoneが効いているから。

新規で追加したかったら、今まで記載しているものはそのままにして、その下から追加していこう。

#終わりに
GASってプログラミングをあまりやったことない人が最初に触ったりする印象がある。
（自分もそうだった）
とりあえずコードコピペして、いろいろいじってみて、試行錯誤しながら正解を見つけていけばいいと思います。

分かりにくかったらコメントください。
読んでいただきありがとうございます。

#追記
@nyanko-box さんより、
`getValue`を多用すると動作時間が遅くなるため、
`getValues`でシートのデータを一括取得する方が良きとのご指摘をいただきました！
ありがとうございます…！

コメントに記載されているので見ていただきたいです↓