GASでWebアプリ｢映画鑑賞記録｣を作る⑫ ／ Googleカレンダーからデータを登録する（前編）

#今回やること

　今まで、映画鑑賞記録を画面から入力していましたが、Googleカレンダーに映画館に行くスケジュールを事前登録している事に気が付きまして、このデータを使って画面からの入力を省きたいと思いました。

- Googleカレンダーのスケジュール情報を使って、映画鑑賞記録を自動登録します。

# Googleカレンダーの作成

　映画鑑賞用に新しいカレンダーを作成します。
　詳細は省きますが、カレンダー画面→［設定］→［カレンダーを追加］→［新しいカレンダーを作成］で、新しいカレンダーを作成します。
　カレンダーの名前は任意ですが、カレンダーにスケジュールを登録する際に必要になりますので、覚えておいてください。
![カレンダー設定①.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510221/93af4bb6-e8be-3169-0f57-4d0325d9a008.png)


　カレンダーの設定で重要な項目は「カレンダーID」です。
　GASからこのカレンダーを参照する際に必要になりますので、覚えておいてください。
![カレンダー設定②.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510221/ac2213a1-4531-62d6-2ea9-e1827cea22be.png)

#映画鑑賞のスケジュール登録

　映画鑑賞のスケジュールを登録します。
　この情報が映画鑑賞記録に使用されます。使用するのは次の項目です。

- `タイトル`　　映画の作品名を入力します。
- `場所`　　　　映画館名ならびに住所を入力します。    
　　　　　　　映画館名を入力するとGoogleが、自動的に映画館名と住所を補完して    
　　　　　　　くれます。
- `カレンダー`　**Googleカレンダーの作成**で作成したカレンダー（ex.「映画鑑賞」）を    
　　　　　　　選択します。
![鑑賞予定の登録.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510221/d0c28a2a-7ac9-acd8-e601-ac4c5209c695.png)

# スプレッドシートの変更

　今回の修正に伴い、スプレッドシートに変更を加えます。
　［映画館］シートに「Google映画館名」（F列）を追加します。
　**【理由】**今回の処理では、スケジュール（カレンダー）に登録されている「場所」の
　　　　　情報から、「映画館名」を自動更新しますが、既存の映画館名と表記が
　　　　　異なっている場合があります。（ex.「シネクイント」）
　　　　　この場合に、既存の「映画館名」（C列）に変換（統一）する必要がある為
　　　　　です。（**プログラムの修正** 参照）
![映画館シートの変更.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510221/aaba2457-f0eb-8d0e-2b13-819f3158c394.png)


# プログラムの修正

　今回、スクリプトファイル（**Calendar.gs**）を追加して、カレンダー用の処理を追加します。

#### Calendar.gs

- `addMovies(day, calId, year)`
 - **処理概要**：カレンダーから日付を指定して、該当日の鑑賞予約の情報を取得して    
　　　　　鑑賞記録に追加登録する処理。    
　　　　　スケジュール（カレンダー）の「場所」には、`映画館名`+`, `+`住所`の    
　　　　　形式（ex.「川越スカラ座, 日本、〒350-0062 埼玉県川越市元町…」）で    
　　　　　登録されているので、`split(',')`を使用して映画館名だけを取得します。
 - **引数**　　：`day`: 該当日（鑑賞日）をDateオブジェクトで指定する。    
　　　　　`calId`: 該当のカレンダー（ex.「映画鑑賞」）の「カレンダーID」    
　　　　　（String型）を指定する。   
　　　　　`year`: 処理する年を文字列で指定する。（ex.`'2021年'`）
 - **返値**　　：取得した鑑賞予約の件数。（取得なし：0）

　**◆参考サイト** [「Google Apps Script」／Reference／Google Workspace services／Calendar](https://developers.google.com/apps-script/reference/calendar?hl=ja)

```javascript
function addMovies(day, calId, year) {
  let calendar = CalendarApp.getCalendarById(calId);
  let events = calendar.getEventsForDay(day);

  for(const event of events) {
    array = event.getLocation().split(',');  // スケジュールから映画館名を取得。
    let cond = {};
    cond.id = 0;
    cond.viewingDate = day;
    cond.movieName = event.getTitle();  // スケジュールから作品名を取得。
    cond.firstLook = 1;
    cond.theaterName = array[0];
    cond.year = year;
    addData(cond);
  }

  return events.length;
}
```
#### ViewingRecord.gs

- `getTheaters()`の修正    
　`getRange()`の4番目の引数を`2`→`4`に変更し、**スプレッドシートの変更**で追加した「Google映画館名」も取得できる様にします。

```javascript
function getTheaters(year) {
  var fileId = getFileIdFromYearSettings(year);
  var sheet = SpreadsheetApp.openById(fileId).getSheetByName('映画館');
  var lastRow = sheet.getLastRow();
//var theaters = sheet.getRange(3, 3, (lastRow - 2), 2).getValues();  //［映画館］シートの「映画館名」列 と「鑑賞種別」列 を取得。
  var theaters = sheet.getRange(3, 3, (lastRow - 2), 4).getValues();  //［映画館］シートの全ての列（データ）を取得。

  return theaters;
}
```

- `getViewingType()`の修正    
　従来の処理は、映画館名（`theaterName`）を指定して、［映画館］シートの「鑑賞種別」を取得するものでした。    
　修正後は、映画館名を指定して、［映画館］シートの「映画館名」（C列）（`.theaterName`）と「鑑賞種別」（`.viewingType`）を取得します。

```javascript
function getViewingType(theaterName, year) {
  var theaters = getTheaters(year);

  for(var i = 0; i < theaters.length; i++) {
    if(theaters[i][0] === theaterName || theaters[i][3] === theaterName) {
      let res = {};
      res.theaterName = theaters[i][0];
      res.viewingType = theaters[i][1];
      return res;
    }
  }

  return false;
}
```

```:以前の記述
function getViewingType(theaterName, year) {
  var theaters = getTheaters(year);

  for(var i = 0; i < theaters.length; i++) {
    if(theaters[i][0] === theaterName) {
      return theaters[i][1];
    }
  }

  return false;
}
```

- `addData()`の修正    
　`setValues()`でセットする「鑑賞種別」と「映画館名」を、`getViewingType()`の返値（`.viewingType`と`.theaterName`）に変更します。

```javascript
function addData(cond) {
    ：
//var viewingType = getViewingType(cond.theaterName, cond.year);
//sheet.getRange(targetRow, 2, 1, 6).setValues([[cond.id, cond.viewingDate, cond.movieName, cond.firstLook, viewingType, cond.theaterName]]);
  const res = getViewingType(cond.theaterName, cond.year);
  sheet.getRange(targetRow, 2, 1, 6).setValues([[cond.id, cond.viewingDate, cond.movieName, cond.firstLook, res.viewingType, res.theaterName]]);
}
```

# 結果
　作成ならびに修正したプログラムを、次のテスト関数を使用して確認します。

```javascript
function test01() {
  const calId = 'xxxxx.xxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxx@group.calendar.google.com'
  const day = new Date(2021, 6, 22);  // 鑑賞日：2021-07-22
  const year = '2021年';
  const res = addMovies(day, calId, year);

  if(res > 0) {
    Logger.log(Utilities.formatDate(day, 'JST', 'MM/dd(E) ') + 'の、' + res + '件の鑑賞記録を追加しました。');
  }
  else {
    Logger.log(Utilities.formatDate(day, 'JST', 'MM/dd(E) ') + 'に、鑑賞予定はありませんでした。');
  }
}
```

　`test01()`を実行した実行ログ。
![実行ログ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510221/3ce6b2dd-fe97-2aa2-b254-753cb2a88bce.png)

　［鑑賞記録］シートの更新結果。
　映画館名が、正しく変換されている事（“イオンスペースシネマ野田1・2”→“イオンスペースシネマ野田”）が分かります。
![実行結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510221/eee8984d-4673-2967-8b12-5e5e68628915.png)

**◆前の記事** [GASでWebアプリ｢映画鑑賞記録｣を作る⑪](https://qiita.com/pump33/items/016c73134eba6609d2f8)
**◆次の記事** [GASでWebアプリ｢映画鑑賞記録｣を作る⑬](https://qiita.com/pump33/items/c43166e3f5f2f57c34b0)

**◆索引** [GASでWebアプリ｢映画鑑賞記録｣を作る《索引》](https://qiita.com/pump33/items/8ded0e6fd3c336e705f4)