Googleスプレッドシートx Slack（Gas）



##はじめに
Slackを利用している人も多いと思います．
そこで「Gasを組めるようになりたい！」と思う人も多いのではないでしょうか？
しかし，Gasよりも重要なのは，実はスプレッドシートを自由自在に操れるようになることなんです！
この記事を参考に，多くの人が業務効率化できてさらなるパフォーマンスを発揮できると嬉しい限りです！

##今回のGoal
スプレッドシート（多くの情報が詰まっている）から，欲しい情報だけ抽出
→さらに条件に合ったものをSlackへ転送

##スプレッドシート編
今回は[こちらのシート](https://docs.google.com/spreadsheets/d/1p3Gf3VIT9xXzNLG_JwcTDB12jHbaSiXehT-O69A7z-k/edit#gid=0)を例に使っていきます．

まずは二つの関数を使えるようになりましょう！
**1：「QUERY」関数
2：「IMPORTRANGE」関数**

###実際にやってみよう
これら関数の使い方は以下のようになります

####「IMPOTRANGE」関数
この関数は別のシートから情報を取ってくる関数となります．
使い方は，

```
=IMPORTRANGE（“スプレッドシートキー”,“シート名!範囲の文字列”）
```

ここでいうスプレッドシートキーとはデータを取ってきたいシートのURLの「d/**〜〜〜**/edit」の**〜〜〜**の部分です！
「https://docs.google.com/spreadsheets/d/1p3Gf3VIT9xXzNLG_JwcTDB12jHbaSiXehT-O69A7z-k/edit#gid=0」
の場合で言うと，「**1p3Gf3VIT9xXzNLG_JwcTDB12jHbaSiXehT-O69A7z-k**」となります！
次にシート名ですが，これは大丈夫でしょう！
今回の場合は「練習用」ですね！
範囲の文字列は，「Aの最初の行」~「J列最終行」まで取りたいので「A:J」となります！
<details><summary>「A:J」って？</summary>
ここでA・Jのあとに数字はいらないの？と思ったかたもいるかもしれません．
スプレッドシートでは，範囲選択の際，例えば「A:A」とするとA列の最初からA列の最終行って意味になります！
しかし，少し注意が必要！
もし，途中で空白行があるとそこまでしか選択されないのでたまにエラーかな？と思った時は，参照下のシートを確認してみてください！
これも使えるテクニックなので覚えておくといいでしょう！</details>

####「QUERY」関数
この関数は「データ」に「クエリ」を指定して、目的のデータを抽出する関数です．
つまり，必要な情報だけ転記ってことができちゃうわけです！
この関数と上記の　「IMPORTRANGE」関数を組み合わせると最強の自動転記シートができちゃうわけなんですよ〜！
使い方は，

```
=QUERY(データ, クエリ, [見出し])
```

| 引数 | 省略の可否 | 解説 |
|:-:|:-:|:-:|
| **データ**  | 必須  |  クエリを実行するセルの範囲 |
|  **クエリ** |  必須 | データ操作を実行する条件  |
| 見出し  |  省略可 | データの上部にある見出し行の数  |

今回，同じシート内からの転記は簡単なので省略します．（多分ググれば一発）

**で，やりたいのは膨大なデータとかが溜まってる別のシートから，欲しい情報だけ転記したいんですよね．．．**

ここで第1引数に登場するのが「IMPORTRANGE」関数なんです！

今回の場合，
#####第1引数は

```
IMPORTRANGE("1p3Gf3VIT9xXzNLG_JwcTDB12jHbaSiXehT-O69A7z-k","練習用!A:J")
```

となります！

次に
#####第2引数についてお話しします．

ここでもう二つ，使えるようになって欲しいものがあります．
**1：「SELECT」
2：「WHERE」**

例えば，「B列」と「E列」と「D列」と「J列」だけ転記したい．．．
(地域・名前・実施日・状況最新)
って場合の第2引数は，

```
"SELECT Col2, Col5, Col4, Col10"
```

となります！
**「Col」+「列番号（Aなら1）」**を並べることで，欲しい列だけ取ってことができます．

**さらに**
「B列」が「福岡」だけ転記したいと言う場合は，

```
"SELECT Col2, Col5, Col4, Col10 WHERE Col2='福岡'"
```

とかきます！
また，複数条件の場合は

```
WHERE 第1条件 AND  (第2条件 OR 第3条件)
```

のように「AND」「OR」そして「（）」を用います！
（）が意外と使えるんですよ！
上記の場合，第1条件に当てはまってかつ，第2条件か第3条件に当てはまるやつって感じです！
WHEREはプログラミングでいう，「if文」だと思うと簡単ですね！

最後は省略可能なんですけど
#####第3引数

データの上部にある見出し行の数を指定します．省略 or -1 と指定した場合は，データの内容に基づいて推測されます．
つまり，意図しない結果が返ることもあるので，省略せずに指定しておくことをお勧めします！今回は，A:1行目が見出しなので「1」を指定しましょう！

###まとめ
今回は[このシート](https://docs.google.com/spreadsheets/d/1p3Gf3VIT9xXzNLG_JwcTDB12jHbaSiXehT-O69A7z-k/edit#gid=0)から，「B列(地域)が福岡」で「J列(状況最新)がAかB」の情報を，「B・E・H・D・J列」だけ転記したいとします！

その場合，

```
=QUERY(IMPORTRANGE("1p3Gf3VIT9xXzNLG_JwcTDB12jHbaSiXehT-O69A7z-k","練習用!A:J"),"SELECT Col2,Col5Col8,,Col4,Col10 WHERE Col2='福岡' AND (Col10='A' OR Col10='B')",1)
```

ですね！（転記後にのってるよ！）

ここまでがスプレッドシート編となります！
意外と疲れたでしょw
次はやっとGASを組むことになります！

##GAS編

今回は2パターンお教えしたいと思います！

###1：メンション編
ここではサンプルコードを貼りますね．
<details><summary>サンプルコード</summary><div>

```js

function announce() {
  //転記したやつ
  var spreadsheet = SpreadsheetApp.openById("スプレッドシート キー");
  var sheet = spreadsheet.getSheetByName('シート名（今回は転記後）');
  var range = sheet.getDataRange().getValues();
  //この2行で最終行を取得（for文で使うよ！）
  var lastRow = sheet.getRange("A:A").getValues();
  lastRow = lastRow.filter(String).length;

  //メンション用
  var ss2 = SpreadsheetApp.openById("メンション用のスプレッドシートキー");
  //ss2は別のスプレッドシートから持ってくる場合は記入・同じシートの場合はss2→ssを利用
  var sheet2 = ss2.getSheetByName('メンション用のシート名（今回はslack用）');
  var range2 = sheet2.getDataRange()getValues();
  var lastRow2 = sheet2.getRange("A:A").getValues();
  lastRow2 = lastRow2.filter(String).length;
  var now = new Date();
  //送信用メッセージの初期化
  var message ="";
  //for文で使う数字の初期化
  var sum = 0;
  
  for(var i=1;i<lastRow2;i++){
    //values[行][列]：配列は開始番号は1ではなく0に注意！
    var mentor_name = range2[i][0];
    var mentor_id = range2[i][1];

    //そのメンターの担当した状況最新がABを保存するための配列初期化
    var abNow = [];
    for(var k=1;k<lastRow;k++){
      if(range[k][2]==mentor_name && range[k][4] == "A" && range[k][4] == "B"){
      //配列に担当かつ状況最新の人の名前を追加
        abNow.push(range[k][1]);
      }
    }
    //もし，AB読みの人がいたらメンション付きのメッセージを更新，いなかったらスルー
    if(abNow.length != 0){
      message += "\n<@"+mentor_id+">\n";
      for(var k=0;k<abNow.length-1;k++){
        message += abNow[k]+"・";
      }
      message += abNow[abNow.length-1];
    }
    //AB読みの合計数を更新
    sum += abNow.length;
  }
  message += "\n\n\nAB読みはというと，，，"+sum+"人なうです！";
  //ここまでのメッセージをスラックに送るための下の関数に送信
  toslack(message);
    
}


function toslack(str){
    var username = '＊AB読みアナウンス＊';     // 通知時に表示されるユーザー名
    var icon     = ':festival:';  // 通知時に表示されるアイコン(※)
    var postUrl="送りたい先のslackのwebhookURL";
  
    var jsonData = {
    "username" :username,
     "icon_emoji": icon,
     "text" : str
    
  };
  var payload = JSON.stringify(jsonData);

  var options = {
    "method" : "post",
    "contentType" : "application/json",
    "payload" : payload
  };

  UrlFetchApp.fetch(postUrl, options);

}
```
</div></details>

###2：期日編
O日前の人に何かしたい．．．
これのやり方色々ありますが，僕がよく使うものを紹介しますね！
まず，スプレッドシートに

```
=Today()　→　これは今日の日付を取得する関数
```

を打ち込みます！

あとはこのセルと，計算したい日付の列を引き算などする関数を使って計算していきます！
ex）実施日ー今日＝3（3日後に実施のもの）を通知

<details><summary>サンプルコード</summary><div>

```js

function mrk_b() {
 
  var spreadsheet = SpreadsheetApp.openById("スプレッドシートキー");
  var sheet = spreadsheet.getSheetByName('シート名');
  var range = sheet.getDataRange().getValues();
  var lastRow = sheet.getRange("A:A").getValues();
  lastRow = lastRow.filter(String).length;
  var mesReady = ""; 

  for(var i=1;i<lastRow;i++){
  //数式をスプレッドシート に出力（今回はF列に「B1」ー「C列」を計算する式）
    sheet.getRange(i+1, 6).setValue("=$B$1-C"+String(i+1));
    if(range[i][6]==-3){
      var date = Utilities.formatDate(range[i][2], 'Asia/Tokyo', 'yyyy-MM-dd');
      mesReady += range[i][1]+"さん";
      sum += 1;
    }
  }
  if(sum2 != 0){
    message += "3日前だよ！\nリマインドをを送ろう！\n終わったらスタンプ！\n"+mesReady;
    toslack(message);
  }
}

function toslack(str){
    var username = '3日前アナウンス！';     // 通知時に表示されるユーザー名
    var icon     = ':drooling_face:';  // 通知時に表示されるアイコン(※)
    var postUrl="webhookURL";
  
    var jsonData = {
    "username" :username,
     "icon_emoji": icon,
     "text" : str
    
  };
  var payload = JSON.stringify(jsonData);

  var options = {
    "method" : "post",
    "contentType" : "application/json",
    "payload" : payload
  };

  UrlFetchApp.fetch(postUrl, options);

}
```
</div></details>
***

あとはトリガーさえ設定すればおっけい！！

ちなみに，GASを組んでSlackへの通知をする時，テストで送信しまくると迷惑！！！

ここで使える豆知識が，

```js

//toslack（message）
Logger.log(message)
```
のようにすると，スラックへの送信をせずにログとして確認できるのでぜひ使用してみてね！
ログは「command」+「enter」で見れるよ！

#最終まとめ
GASってめっちゃ面白いので，みんな挑戦してみてくれ！！！