GASでSpreadSheetを読み書きする。

# 前提
[GoogleAppsScript(GAS) で 「Hello World」する方法](https://qiita.com/ub0t0/items/df688e0f2042df1325f4?fbclid=IwAR1PMbOsGRBgiUlSL2OMZ0tFPfUgBBE1i_t67fANoCmrh6r4Tc_F7EoHTFs)

# 本記事について
GASを使っていろいろやってみようという記事。

# SpreadSheetから関数を呼び出す。
まずはSpreadSheetを開いた状態からGASを呼び出す方法を学ぶ。

## メニューを追加してダイアログを表示

[getUi ドキュメント](https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app#getUi())
ドキュメントを参考に上部メニューを拡張する。

以下のように記述

```.js:コード.gs
const onOpen = (e) => {
  SpreadsheetApp.getUi()
      .createMenu('My Menu') // 上部メニューにMy Menuを追加
      .addItem('Hello GAS', 'helloGAS') // Hello GASを押したらhelloGAS関数を呼ぶ。
      .addToUi();
}

const helloGAS = () => {
  Browser.msgBox("hello GAS!"); // ダイアログを表示
}
```

その上で、ブラウザを更新すると以下のようにメニューが表示されるようになる。
(SpreadSheetの読み込みは時間かかる。)

<img width="184" alt="スクリーンショット 2020-08-09 17.31.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/f52d9b14-3744-629e-a1b7-bc56269bd794.png">


そしてボタンを押すと、許可が求められる。
(画像はエディタ側で読んだ時のものなので見た目は異なってると思われる)
<img width="481" alt="スクリーンショット 2020-08-09 16.55.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/0ff5e4fe-945f-423c-cecf-da3722c67438.png">

許可をおしてGoogleでログインすると以下のような画面が表示される。

<img width="1162" alt="スクリーンショット 2020-08-09 16.55.31.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/d2ca46f2-c658-ecc6-c76e-63c0fa8565b7.jpeg">

その上で実行すると、以下のようにダイアログが表示されるようになる。

<img width="240" alt="スクリーンショット 2020-08-09 17.37.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/199ec0a6-b01e-618a-4264-47286a9ee900.png">

> ミスの修正などでスクリプトを更新した場合にはSpreadSheetの画面を更新して再度スクリプトを読み込む必要がある。

これで読み書きの準備完了。

ブラウザに広告ブロックツールを入れてる場合に、読み込みがめっちゃ遅くなることがあるのでこのページでは無効にすると良い。

## 演習
同じMyMenuに新しいメニューアイテムを1つ追加してみよう。
呼ぶ関数は`helloGAS2`とか適当に。


# SpreadSheetに書かれた文字を読む。

以下のようにデータを作成した。

<img width="227" alt="スクリーンショット 2020-08-09 18.21.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/fbc33740-b173-1475-66e9-8bc4d9840dc7.png">

そして、シート名を`monsters`とする。

<img width="182" alt="スクリーンショット 2020-08-09 18.23.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/09e82b6d-b7e1-6517-052b-e8822cdea78a.png">


これをGASから取得する。

```.js:コード.gs
const onOpen = (e) => {
  SpreadsheetApp.getUi()
      .createMenu('My Menu')
      .addItem('Hello GAS', 'helloGAS')
      .addItem('Read Monster', 'readMonster') // <- 追加
      .addToUi();
}
...
  
const readMonster = () => {
  const spreadSheet = SpreadsheetApp.getActive(); // 今開いているスプレッドシートファイルの中の
  const monstersSheet = spreadSheet.getSheetByName("monsters"); // monstersというシートの
  const range = monstersSheet.getRange(2, 1); // 2行目、1列目の範囲を指定
  const value = range.getValue(); // そこの値を取得
  Browser.msgBox(value);
}
```

[getRange](https://developers.google.com/apps-script/reference/spreadsheet/sheet#getrangerow,-column)

結果は以下

<img width="237" alt="スクリーンショット 2020-08-09 18.21.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/5fd63b21-1d9d-42d8-ce6c-b0f57e7bbba9.png">


> 複数行読み込む場合は`getDataRange`や`getValues`等を使うが二次元配列を使うため今回は省略

# SpreadSheetに書き込む
新しいモンスターを追加してみる。

以下のように記述

```.js:コード.gs
const onOpen = (e) => {
  SpreadsheetApp.getUi()
      .createMenu('My Menu')
      .addItem('Hello GAS', 'helloGAS')
      .addItem('Read Monster', 'readMonster')
      .addItem('Append Monster', 'appendMonster') // 追加
      .addToUi();
}

...

const appendMonster = () => {
  const spreadSheet = SpreadsheetApp.getActive();
  const monstersSheet = spreadSheet.getSheetByName("monsters");
  monstersSheet.appendRow(["ウルフ", 12, 14]);
}
```

[appendRow](https://developers.google.com/apps-script/reference/spreadsheet/sheet#getRange(Integer,Integer))

このように行末に追加される。

<img width="256" alt="スクリーンショット 2020-08-09 18.32.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/de2e5ef6-465c-f03b-69a4-070a2e33942b.png">

# まとめ
ドキュメントにいろいろサンプルコードが乗ってるので試しやすい。