Google App Maker ー Drive Tables へのデータ投入方法

[Google App Maker（App Maker）](https://developers.google.com/appmaker/)の[Google Drive Tables](https://developers.google.com/appmaker/models/drivetables)を使っていると、開発時にデータの登録を何度も行ったり、本番環境への初期データ登録が必要になる。
データを投入する方法は主に３つあり、それぞれ解説する。

- Form ウィジェットを使用したデータ投入
- Import Data From Sheet を使用したデータ投入
- 自分でスクリプトを書いてデータ投入


そもそも App Maker ってなに？という人は、以下の記事を参照してください。
[Google App Maker とは？ 短期間で Web アプリケーション構築を可能にした理由](https://www.topgate.co.jp/what-is-google-app-maker)


# Form ウィジェットを使用したデータ投入
普通に登録画面で使うのと同じように使う。
いちばん手軽だが、1つずつ手で入れる必要がある。現実的ではない。


# Import Data From Sheet を使用したデータ投入
これが基本。
[Import and export data  |  App Maker  |  Google Developers](https://developers.google.com/appmaker/models/import-export)

モデル用にシートを作る必要があるので、既存のシートをそのまま読み込むのはまず無理。
別シートを作ってセル参照させるとかする必要がある。

以下にポイントを書いておく。

- １行目とフィールド名が一致する必要がある
- モデルに存在しないフィールド列を含めてはいけない
- 途中に空白列を含めてはいけない
- 列の順番は一致しなくても良い
- 日付フィールドは `YYYY-MM-DD` 形式であること（時分秒が入れられない、UTC 0時固定）
- 単純に文字列化してインポートしている模様  
    - 日付セルの `2017-08-31` でも、文字列セルの `2017-08-31` でも良い
    - 関数式でも良い

 
# 自分でスクリプトを書いてデータ投入
プログラミングに抵抗がない人これがいい。

- 自由度が高い
- コードを書く必要がある
- スクリプトの実行は開発画面からは出来ない
    - 発火用のボタンを画面に配置して自分で押す
- ダミーデータを大量に作りたいときにも使える


スプレッドシートから読み込む事もできるので、Import Data の欠点を全て無視できる。

[^1]: 難しいことはしてないから特に解説はしない
雰囲気がわかるサンプルコードだけ残しておく[^1]


```javaScript:スプレッドシートを読み込んでデータ登録するスクリプト
function importByScript() {
  var records = [];

  var ss = SpreadsheetApp.openById('119OSCHySluk63gEt04IL-ahyH-1kuRfTNPaKdyz8ZAI');
  var sheet = ss.getSheetByName('スクリプト用データ');
  var range = sheet.getRange('A2:E6');
  
  var values = range.getValues();
  for (var i = 0; i < values.length; i++) {
    var rowData = values[i];
    console.log(rowData);
    
    var name = rowData[0];
    var age = rowData[1];
    var retired = rowData[2];
    var retiredAt = rowData[3];
    
    var record = app.models.Employee.newRecord();
    
    record.Name = name;
    record.Age = Number(age);
    
    if (retired) {  
      record.Retired = Boolean(retired);
    }
    
    if (retiredAt) {
      record.RetiredAt = new Date(retiredAt); 
    }
    
    records.push(record);
  }
  
  app.saveRecords(records);
}
```



# Tips
データ投入と一緒に覚えておいたほうが良いことを記載しておく。

## 一括削除
一括削除機能は用意されてないので自前でコードを書く必要がある。
これも `自分でスクリプトを書いてデータ投入` と同じようにイベント発火するボタンを作って押す。

```javaScript
function deleteAllEmployees() {
  var query = app.models.Employee.newQuery();
  var records = query.run();
  
  var keys = [];
  records.forEach(function (record) {
    keys.push(record._key);
  });

  console.log(keys);
  app.models.Employee.deleteRecords(keys);
}
```

## 日付を扱う場合はタイムゾーンに気をつける

### Date ウィジェット
ブラウザ(OS)のタイムゾーンになる。
つまり **JST０時** (UTC 9時) になる。

### Import Data From Sheet
UTC になる。
つまり **JST9時** (UTC ０時) になる。

※このIssueを見ると `-19時間` になる人がいるみたいだ。バグが有るのかもしれない
https://issuetracker.google.com/issues/36764275

### サーバースクリプトのタイムゾーン
サーバースクリプトのタイムゾーンは、App Maker のサーバーがあるであろう PST になる。
※今はサマータイムなので PDT になる。

サーバーのタイムゾーンは変わるかもしれないから、 `getTimezoneOffset()` とか使って自分で日本時間に直すコードを書く必要がありそう。

たとえばこういうコードだと
**JST 16時** (UTC 7時 / PDT 0時) になる

```javaScript
new Date('2017/8/30');
```

## こういう画面を作ると良いかも
管理者しかアクセスできない管理画面を作る。
そこから、 `一括削除` や `スクリプトから投入` するボタンを作って発火させる。
Table ウィジェットと Form ウィジェットも置いとけば手動でちょろっと直すとかも出来る。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/35595/8806eae6-0517-42cf-76b0-064a2aa6e8c9.png)