Google Apps Script(GAS) 超入門① - スプレッドシートの値をとってみる

## かるく背景

非エンジニアでも簡単に、サーバーも無しで無料で使える超便利なGoogle Apps Scripts。通称GAS。
非常に敷居は低いですが、やっぱり初めて「スクリプトエディタ」を見ると"おえっ"という感じになる人は多いハズ。

そこで、超簡単にGASの使い方のイメージをつかんで読者さんが自分でも触れるようにしよう！
という目的で記事書いてます。

## 目標

* GASを使うための、スプレッドシートへのアクセス方法を知る
* GASを使ってスプレッドシートの値を好きなように取れるようにする

## スプレッドシートを使うときのイメージ

GASでスプレッドシートを使うとき、この3つの概念を頭に入れておくと、超イメージ湧きやすいです。

* **SpreadSheetオブジェクト**
    * スプレッドシートを扱う
    * スプレッドシートに対して、シートを作ったり消したりするときに使います
* **sheetオブジェクト**
    * シート(「シート1」とか「シート2」)を扱う
    * シートの中身に対して範囲を指定するとか、行の追加・削除とかに使います
* **Rangeオブジェクト**
    * 範囲 (普段関数で使う`A2`とか`A2:B3`みたいなものです)
    * 特定のセルの値を取得したり、入力したりします


オブジェクトって何？って思うかも知れませんが、あまり気にしなくても使うことは出来ますし、難しく考えすぎるとまた敷居が高くなります。
今はシートから値を取り出すために必要なもの。くらいに考えておきましょう。

![スクリーンショット_2019-06-14_12_54_45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434023/e004de7b-6d43-46de-91c1-98d94ffedddc.png)

### 使い方

基本的に、`SpreadSheetオブジェクト` > `sheetオブジェクト` > `Rangeオブジェクト`とアクセスしてきます。
これは普通にスプレッドシートを使ってるときと同じ考え方です。
例えば、「営業日報を入力する」シーンを考えてみましょう。

* まず「営業日報」というスプレッドシートを開きますね
    * これが、`SpreadSheetオブジェクト`です
* 次に、「山本」という自分の名前が書かれたシートを選択します
    * これが`Sheetオブジェクト`です
* 最後に、今日に日付の行の3列目(`C4`とか)に今日の受注件数を入力します
    * これが`Rangeオブジェクト`です
    * `Rangeオブジェクト`を使って、`C4`というセルに(セルの情報を取得)、受注件数を入力します(セルに値をセット)


簡単な気がしてきますね。
じゃあ、実践していきましょう。

### 1. シートを使えるようにします

まず、スプレッドシートを作ります。
こんな感じで、B列に名前、C列に生年月日が入ってるものでも用意しておきましょう。

そして、「ツール」>「スクリプトエディタ」をクリックして、Google Apps Scriptsを開きましょう。

![スクリーンショット 2019-06-14 13.14.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434023/c5868999-db75-2319-e9d4-4238db8b19d3.png)

この画面が出たらOKです。

![スクリーンショット 2019-06-14 13.16.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434023/adb5f4db-4e3e-6501-02c3-2455e6619841.png)

まずは、シートを使える状態にしてみましょう。
`sheetオブジェクト`を使える状態にするためには、`shpreadSeetオブジェクト`から`sheetオブジェクト`を作ります。

手始めに、`B3`セルの「大谷」を取得するスクリプトを書いてみます(↓をコピペしてください)

```js
function myFunction() {
  // スプレッドシートオブジェクトを作る
  var spreadSheetByActive = SpreadsheetApp.getActive();

  // シートにアクセスする
  var sheet = spreadSheet.getActiveSheet();
  
  var name = sheet.getRange('B3').getValue();
  Logger.log(name);  
}
```


スプレッドシートからGASファイルを作った場合はこの方法が１番シンプルです。

#### 早速実行してみる

一回作ったらまずは使ってみたいですよね。
最初は承認とかいろいろ必要なので画像で説明していきます。

##### 1. Ctrl+Sでファイルを保存

適当に名前をつけて「OK」

![スクリーンショット 2019-06-14 13.20.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434023/e7e686b4-19e3-b3bf-c2a7-d027a754e60a.png)

##### 2. 実行！！

画面の上部にある「再生ボタン」みたいなやつクリック

![実行.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434023/5c1be7a7-d795-caeb-7784-a2efca0b85cc.png)

##### 3. 承認してく

最初この画面が出るので、「許可を確認」をクリック

![スクリーンショット 2019-06-14 13.21.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434023/1ed4d9a8-00fe-63b4-dc23-6abc7782bef0.png)

自分のGoogleアカウントをクリック

![2.Googleアカウント承認.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434023/53555adb-7c42-e05d-84a5-8c42ac5100f9.png)

警告が出るので、「詳細を表示」をクリック

![3. 詳細クリック.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434023/0ee2ea8c-67bc-d3d7-147d-e23ca2a9bab3.png)

xxxxに移動をクリック

![4. 詳細から移動.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434023/9cabd40a-7238-d712-d22d-ff2ca782e628.png)

これはGASがスプレッドシートにアクセスして読み書きする事を許可しますか？
と聞いてるので、「許可」をクリック(これで名前が取得出来ます)

![5. 許可.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434023/4b8fdbc9-e002-c5cb-2511-823e89d1656a.png)

##### 4. 実行結果を見てみる

「表示」>「ログ」をクリックすると、ログのダイアログが開きます。

![スクリーンショット 2019-06-14 13.21.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434023/bbe660c9-bd7f-68d4-7205-eaf1e3900acd.png)

ちゃんと、`B3`列に表示されてる`大谷`が取得出来てます。

![スクリーンショット 2019-06-14 13.21.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434023/36c96089-b0b0-be7d-0349-f0a074981edf.png)

もうこれでやりたい事は出来ましたね！！

## スプレッドシートへのアクセスの仕方

スプレッドシート(今回は「gas入門①」というスプレッドシート)にアクセスするには、今回使った`getActive`以外にも4つの方法があります。

```js
function myFunction() {
  // スプレッドシートオブジェクトを作る
  var spreadSheet         = SpreadsheetApp.getActiveSpreadsheet(); // ① アクティブなシートを指定
  var spreadSheetByActive = SpreadsheetApp.getActive(); // ② アクティブなシートを指定
  var spreadSheetById     = SpreadsheetApp.openById('xxxxxxxxxxxxxxxxxxxx'); // ③ スプレッドシートのIDで指定
  var spreadSheetByUrl    = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/xxxxxxxxxxxxxxxxxxxx/edit#gid=0'); // ④ スプレッドシートのURLで指定
}
```

|アクセスの仕方|説明|
|---|---|
① アクティブなシートを選択|このGASファイルを作ったスプレッドシート(今回は`GAS入門①`)を選択
② アクティブなシートを選択|このGASファイルを作ったスプレッドシート(今回は`GAS入門①`)を選択 (①同じです)
③ スプレッドシートのIDで指定 | スプレッドシートのURLの`edit`より前の文字列でアクセス
④ スプレッドシートのURLで指定 | スプレッドシートのURLをまるごと指定してアクセス

見て分かる通り、①と②は、スプレッドシートからGASファイルを作った場合に使います。
ただ、①と②は同じ結果なので、②の`getActive`のほうが短くて良きです。

また、③と④はスプレッドシートに紐付けずにGASファイルを作った場合に使います。
「カレンダーの情報を取得して、特定のスプレッドシートにカキカキ」とかしたくなったら使うので今度説明します。

## シートへのアクセスの仕方

じゃあ、スプレッドシートにアクセスする方法が分かったので、次はシートにアクセスする方法を学びましょう。
シートってのは、今回は「シート1」を使いましたが、「シート2」を使うときとかにどうするか？という話ですね。

### 余談. なんで`getActiveSheet`が使えたのか

↑の例では、`getActiveSheet` と書いたら「B3」の値として「大谷」が取得出来ました。
これは「今アクティブなシート」 = 「今選択中のシート」という意味だったわけです。
たまたま、「シート1」を選択してる状態で実行したので「大谷」が取れてたので、「シート2」を選択した状態で実行するとどうなるか見てみましょう。

一旦スプレッドシートに戻って、「シート2」を選択して、もう一度スクリプトエディタから「実行」してみましょう。

![6. シート2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434023/194680f2-ddcd-5127-7904-1f65007a4659.png)

シート２のB3は何も書かれてないので、ログには「大谷」が表示されません。

![7. log.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434023/969095b0-717d-8343-a6d5-12e3739e221d.png)

じゃあ`getActiveSheet`だと何か危ない気がしますね。他にどんな方法があるのでしょうか。
取得方法は2つで、今回の`getActiveSheet`かシート名で指定する`getSheetByName`の2択です。

```js
function myFunction() {
  // スプレッドシートオブジェクトを作る
  var spreadSheet = SpreadsheetApp.getActive();
   

  // シートにアクセスする
  var sheet       = spreadSheet.getActiveSheet(); // ① アクティブなシートを指定
  var sheetByName = spreadSheet.getSheetByName("シート1"); // ② シート名で指定
  
  // getActiveSheetで指定したときの結果  
  var name = sheet.getRange('B3').getValue();
  Logger.log("getActveSheetの結果 => " + name); 

  // getSheetByNameで指定したときの結果  
  var name = sheetByName.getRange('B3').getValue();
  Logger.log("getSheetByNameの結果 => " + name);   
}
```

これで、「シート2」を選択した状態で実行してみましょう。

`getActiveSheet`で取得すると「シート2」のB3を取りにいくので結果が空です。
ただ、`getSheetByName`で取得した場合は「シート1」のB3を取りに行くので「大谷」が取れてます。

![スクリーンショット 2019-06-14 13.55.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434023/bd9402e3-86f6-dee9-8578-14c0df2fd012.png)

## スプレッドシートの値を取得する

実はもう「大谷」で取得してましたが、もう少し最初の`SpreadSheetオブジェクト`と`Sheetオブジェクト`、`Rangeオブジェクト`に分けて考えてみましょう。

```js
function myFunction() {
  // スプレッドシートオブジェクトを作る
  var spreadSheet = SpreadsheetApp.getActive();
   
  // シートにアクセスする
  var sheet       = spreadSheet.getActiveSheet();
  
  // 範囲(Range)にアクセスする
  var range = sheet.getRange('B3');
  
  var name = range.getValue();
  
  Logger.log(name); 
}
```

この例ではこんな感じでした。

簡単に解説しておくと
* `SpreadSheetApp.getActive()`でスプレッドシートオブジェクトを作って
* そのスプレッドシートオブジェクトから、`getActiveSheet`でシートオブジェクトを作って
* シートオブジェクトから、`getRange`でRangeオブジェクトを作って

で、最後にその値を取得してました。

![8. コード解説.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434023/fb12a89e-eee2-a629-b857-47c5e6af53d3.png)

## もっといろんな値を取得してみる

今回、値は`B3`を直接指定しましたが、この取得方法も2種類あります。
一つは、`getRange("セルの番号")`とする方法。
もう一つは、`getRange("行の番号", "列の番号")とする方法。

後者の方は、行の番号に`何行目、列の番号に`何列目`かを入れるので、B3を取得したい場合は、
`3行目`の`2列目(B列は左から数えて2列目なので)`を指定すれば同じ結果が取得出来ます。

```js
function myFunction() {
  // スプレッドシートオブジェクトを作る
  var spreadSheet = SpreadsheetApp.getActive();
   
  // シートにアクセスする
  var sheet       = spreadSheet.getActiveSheet();
  
  // 範囲(Range)にアクセスする
  var range      = sheet.getRange('B3');
  var rangeByNum = sheet.getRange(3, 2); // 3行目の2列目(B3)にアクセス 
  
  // B3の取得結果
  var name = range.getValue();  
  Logger.log("B3の取得結果　=> " + name); 
  
  
  // 3,2と指定した取得結果
  var name = rangeByNum.getValue();
  Logger.log('3,2の取得結果 => ' + name);
}
```

同じ結果が得られましたね。

![スクリーンショット 2019-06-14 14.06.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434023/bc8ffaf5-8427-396a-39c5-a330ddfb0254.png)

## 次回予告

今回のでスプレッドシートの値を自在に取得できるようになったので、自分でもいろいろできる気がしてきましたね
例えば、スプレッドシートの値を取得(営業の数値とか)して、その結果を毎朝8時にチャットする。とかも出来ますよ。

さて、次回はもっと柔軟に使っていくために、スプレッドシートの値を複数一気に取得する方法と、スプレッドシートに値を入れる方法を紹介していきます。