GoogleAppsScriptでスプレッドシートに書いたスケジュールをGoogleカレンダーに登録・編集する方法

## はじめに
スプレッドシートに書いたスケジュール表からgasでGoogleカレンダーに登録したり編集する方法を勉強したので紹介します。カレンダーを初めて使う人の参考になれたら嬉しいです。

## スプレッドシートに書くスケジュール表
今回紹介する手順は、こんなスケジュール表で想定してます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181001/6cbf1fc2-b4aa-f63a-2f55-83da590e1e97.png)

gasのリファレンスで上の1行分のスケジュールのことを **イベント** って呼んでるようなので、以降の文章より **イベント** を登録・編集すると呼びます。

### E列のイベントIDとは
- Googleカレンダーにイベントを登録した時に発行されるイベント毎のIDです。
- イベントを編集したい時に、必要になります。
- カレンダー登録前なので、最初は空白です。

## カレンダーへ新規イベント登録処理
以降の手順のコードをそのままコピペしても動くと思います。
コードをシンプルにする為、セルの空白チェックや日付チェック等はやってませんのでご了承ください。

### 1. 最初にカレンダーに登録するデータを作成します。
`values` という変数にシートのデータを格納します。

```javascript
  // 今選択中のスプレッドシートのシートを取得
  var sheet = SpreadsheetApp.getActiveSheet();
  // 取得したシートから、セルの中身を取得
  var values = sheet.getDataRange().getValues();
```
### 2. 登録したいカレンダー指定します。
今回は自分のデフォルトカレンダーを指定します。
別のカレンダーを指定したい場合は [公式リファレンス](https://developers.google.com/apps-script/reference/calendar/calendar-app#getallcalendars) に色々な取得方法があるので参考にしてください。

```javascript
  // デフォルトのカレンダーを取得
  var calendar = CalendarApp.getDefaultCalendar();
```
### 3. カレンダーへ登録処理。
`values` をループしながら1行ずつカレンダーに登録します。

```javascript
// ※var i の0番目はヘッダーになるので、1からスタートします。
for (var i = 1; i < values.length; i++) {
    // 予定日
    var date = values[i][0];
    
    // 開始時間
    var startTime = values[i][1];
    var startDateTime = new Date(date.getFullYear(),
                                 date.getMonth(),
                                 date.getDate(), 
                                 startTime.getHours(),
                                 startTime.getMinutes(), 0);
    // 終了時間
    var endTime = values[i][2];
    var endDateTime = new Date(date.getFullYear(),
                               date.getMonth(),
                               date.getDate(),
                               endTime.getHours(),
                               endTime.getMinutes(), 0);
    // タイトル
    var title = values[i][3];
    
    // カレンダーへ登録
    var event = calendar.createEvent(title, startDateTime, endDateTime);
    // イベントIDをE列にセット getRange(行番号, 列番号)
    // i は配列のindexの為、セルを指定する時は +1する必要があります。
    sheet.getRange(i + 1, 5).setValue(event.getId());
  }
```

### 4. 実行結果の確認
登録が成功すると、E列にイベントIDがセットされました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181001/22e95e93-aab5-898f-a057-dc911b2895c4.png)

カレンダーにも登録されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181001/2c982b5e-10e1-ecde-b1fd-06fff72322ae.png)

## イベントの編集処理
スプレッドシートの内容を編集して、カレンダーに変更内容を反映したい場合、E列のイベントIDから `calendar#getEventById('イベントID')` でイベントを取得し、時間とタイトルをセットすると更新できます。

```javascript
    
    // イベントIDに紐づくイベントを取得
    var event = calendar.getEventById(values[i][4]);
    // setTime(開始日時、終了日時)
    event.setTime(startDateTime, endDateTime);
    // タイトル
    event.setTitle(title); 
```
`values` や開始、終了日時の求め方ついてはイベント新規登録時と同様になる為、割愛させていただきます。さきほどの [カレンダーへ登録処理](#3-カレンダーへ登録処理) のループ中のカレンダーへ登録部分をこのコードに置き換えれば編集用の処理になりますね。

## イベントの場所や説明を設定する場合
例えば、スプレッドシートに場所と説明の列を追加した場合です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181001/d313992c-4a0d-e9b5-f5a3-a35f47147c88.png)
実行後のカレンダーのイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181001/c340796c-e1c6-fdc7-74af-44bbcb87860c.png)

### 1. イベント新規作成の時
場所、説明は以下のように連想配列で作成し、さきほどの `createEvent()` の4番目の引数に追加すると登録できます。

```javascript
 var options = {
   location: values[i][4],
   description: values[i][5]
 }
 // var event = calendar.createEvent(title, startDateTime, endDateTime);
 // 引数にoptionsを追加するだけ
 var event = calendar.createEvent(title, startDateTime, endDateTime, options);
```
`options` には招待するゲストや招待メール送るか？の設定もできるみたいです。（私はまだ試したことがありません）くわしくは [公式リファレンス](https://developers.google.com/apps-script/reference/calendar/calendar#createeventtitle,-starttime,-endtime,-options) をご覧ください。

### 2. イベント編集の時
イベントを取得後に、 各setメソッドで更新することができます。

```javascript
// 場所
var location = values[i][4];   
// 説明
var description =values[i][5];

// イベントを取得
var event = calendar.getEventById(values[i][6]);

// 場所を更新
event.setLocation(location);
// 説明を更新
event.setDescription(description);
```

## 公式リファレンス
今回使ったカレンダーの公式リファレンスです。

- [CalendarApp#getDefaultCalendar()](https://developers.google.com/apps-script/reference/calendar/calendar-app#getdefaultcalendar)
- [Calendar#createEvent(String,Date,Date)](https://developers.google.com/apps-script/reference/calendar/calendar#createEvent(String,Date,Date))
- [Calendar#createEvent(String,Date,Date,options)](https://developers.google.com/apps-script/reference/calendar/calendar#createEvent(String,Date,Date,Object))
- [Calendar#getEventById(icalid)](https://developers.google.com/apps-script/reference/calendar/calendar#geteventbyidicalid)
- [Class CalendarEvent](https://developers.google.com/apps-script/reference/calendar/calendar-event)

## おわりに
他の人のQiitaを見て、はじめに、おわりにをつけてる方がなんかいいなーと思って今回初めてつけてみました。以上で終わります。