質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
LINE Messaging API

LINE Messaging APIは、メッセージの送信・返信ができるAPIです。Web APIを経由しアプリケーションサーバとLINEのAPIでやり取りが可能。複数のメッセージタイプや分かりやすいAPIリファレンスを持ち、グループチャットにも対応しています。

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google フォーム

Google フォームは、 Google社が提供しているアンケートフォーム作成および集計ができる無料のツール。Googleアカウントがあれば利用が可能です。集計データは、スプレッドシートに収集され、データ分析もできます。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Q&A

1回答

1388閲覧

Googleフォームの回答スプレッドシートから特定条件の回答のみ、別スプレッドシートにも反映&LINE通知したい

dora_maru

総合スコア0

LINE Messaging API

LINE Messaging APIは、メッセージの送信・返信ができるAPIです。Web APIを経由しアプリケーションサーバとLINEのAPIでやり取りが可能。複数のメッセージタイプや分かりやすいAPIリファレンスを持ち、グループチャットにも対応しています。

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google フォーム

Google フォームは、 Google社が提供しているアンケートフォーム作成および集計ができる無料のツール。Googleアカウントがあれば利用が可能です。集計データは、スプレッドシートに収集され、データ分析もできます。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

0グッド

1クリップ

投稿2021/08/20 07:33

前提・実現したいこと

Googleフォームで全国で開催しているイベントのアンケートを回収。
アンケートの回答はスプレッドシートへ表示し、新しい回答があった場合、その内容をLINE通知。
回答スプレッドシートから、QUERYとIMPORTRANGEで別のスプレッドシートへ特定の都道府県の回答だけ抜き出しています。
ここまでは出来ました。

≪やりたい事≫
特定の都道府県の回答が来た場合、その分だけ別のLINEグループへ通知したいです。
例えば、愛知県、三重県、岐阜県、静岡県の回答が来た場合、東海LINEグループに通知。それ以外の県の回答は通知しない。

発生している問題・エラーメッセージ

特定の都道府県の回答のみのスプレッドシートからスクリプトエディタでコードを入れました。
トリガーはスクリプトエディタから『変更時』で設定してます。
LINEトークンはプロジェクトのプロパティ→スクリプトのプロパティに「LINE_TOKEN」で設定しました。
通知は来るのですが、特定の都道府県以外の回答時も一つ前の特定の都道府県の回答が通知で来てしまいます。

例えば、愛知県①の回答が来る→愛知県①の回答がLINE通知来る。
次に群馬県①の回答が来る→愛知県①の回答がLINE通知来る。
次に愛知県②の回答が来る→愛知県②の回答がLINE通知来る。
※群馬県①の回答時はLINE通知しないようにしたい。

該当のソースコード

function GoogleFormToLine(){ var sheet = SpreadsheetApp.getActiveSheet(); var row = sheet.getLastRow(); var column = sheet.getLastColumn(); var range = sheet.getDataRange(); var message = "";  for(var i=1;i<=column;i++){  var item = range.getCell(1, i).getValue();  var value = range.getCell(row, i).getValue();   if(item == "タイムスタンプ" || item == "開催日"){   value = Utilities.formatDate(value,"JST","yyyy/MM/dd(E) HH:mm:ss");  }  message += "\n■"+item+"\n"+value;  } SendToLine(message); } function SendToLine(message){ var token = PropertiesService.getScriptProperties().getProperty('LINE_TOKEN'); var op = { "method" : "post", "payload": "message=" + message, "headers":{"Authorization" : "Bearer " + token} }; var res = UrlFetchApp.fetch("https://notify-api.line.me/api/notify",op); Logger.log(JSON.parse(res.getContentText())); }

試したこと

今回の作業の為に初めてGASを知ったくらいの初心者です。
あちこちサイトを調べて使えそうなコードを探しては切り貼りしてみたり、メソッドの解説読んだりしましたが、これが限界でした。
3か月くらい一人で戦ってるので、そろそろ解決したいです。
どうぞよろしくお願いします。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

【通知が重複する原因】
大本の全都道府県の回答を集めたスプレッドシートを[元シート]とします。

そして、[元シート]から計算式で東海エリア4県のデータのみを抽出しているスプレッドシートを[東海エリアシート]とします。

フォームから回答が入力され、[元シート]に東海エリアの県以外の回答データ(群馬県)が追加されたと仮定します。

このとき、[東海エリアシート]には、当然その回答データが追加されないように見えます。

しかし、見た目上の変化がなかったとしても、[東海エリアシート]側ではデータの変更イベントが発生し、トリガーに設定したGoogleFormToLine()関数が実行されてしまいます。

なぜならば、変化がないのは見た目だけであって、実際には[元シート]に回答データが追加された時点で、[元シート]を参照している[東海エリアシート]の内部でも毎回再計算が行われており、これが毎回「データの変更」として扱われるからです。

結果、[東海エリアシート]最終行にある直前のデータ(「愛知県」)がLINEに送信されることになります。


【具体案】
そこで案として、[エリアシート]側ではなく、フォーム回答の集計元シートの側で、フォームから追加された回答データの都道府県を判定し、条件に当てはまる場合のみグループに送信する方法が考えられます。

下記のように、フォーム回答の集計元シートのスクリプトに、
都道府県を判定して該当する都道府県の場合はフラグをtrueにして送信するコードを記述します。

js

1// フォーム回答の集計元シートのスクリプト。 2// 下のSendToGroupLine()にフォーム送信時のトリガーを設定しておく。 3function SendToGroupLine(){ 4 var sendFlag = false; // グループに送信するかどうか。true:送信する。false:送信しない。 5 var ss = SpreadsheetApp.openById("集計元シートのスプレッドシートID"); //集計元シートのスプレッドIDを指定。※エリアシートではない。 6 var sheet = ss.getSheetByName("フォームの回答 1"); // フォームの回答のシート名を指定 7 var row = sheet.getLastRow(); 8 var column = sheet.getLastColumn(); 9 var range = sheet.getDataRange(); 10 var message = ""; 11 12 for(var i=1;i<=column;i++){ 13  var item = range.getCell(1, i).getValue(); 14  var value = range.getCell(row, i).getValue(); 15 // 送信対象の都道府県かどうかを判定 16   if(item == "都道府県" && (value=="岐阜県" || value=="静岡県" || value=="愛知県" || value == "三重県")){ 17 // 送信対象の都道府県であれば、グループ送信フラグをtrueにする。 18 sendFlag = true; 19 } 20 21 // 以下は送信メッセージを組み立てる部分。 22 if(item == "タイムスタンプ" || item == "開催日"){ 23   value = Utilities.formatDate(value,"JST","yyyy/MM/dd(E) HH:mm:ss"); 24  } 25  message += "\n■"+item+"\n"+value; 26 } 27 // グループ送信フラグがtrueならばグループLINEに送信する。 28 if (sendFlag){ 29 SendMessageToGroup(message); 30 } 31 //都道府県に関係なく一律送信する内容はSendMessageToGroupとは別の関数で処理する(必要であれば) 32 SendToLINE(message); 33} 34 35 36// 下記の部分はグループLINEに送信するように設定されている前提。(検証していません) 37function SendMessageToGroup(message){ 38 Logger.log(message) 39 var op = 40 { 41 "method" : "post", 42 "payload": "message=" + message, 43 "headers":{"Authorization" : "Bearer " + token} 44 }; 45 var res = UrlFetchApp.fetch("https://notify-api.line.me/api/notify",op); 46 Logger.log(JSON.parse(res.getContentText())); 47} 48 49// 都道府県に関係なく送信する内容(不要ならばなくてもよい) 50function SendToLINE(message){ 5152}

(上記コード保存後、フォーム回答の集計元シートのトリガーに、「フォーム送信時」に下記SendToGroupLine関数を実行するように設定しておく)
トリガー設定例
イメージ説明
※東海エリアシート側のトリガー及びスクリプトは不要なので削除しておくこと。残っていると二重に通知が来る。

--
注意:上記コードは最適化する余地がたくさんありますが、理解しやすいように、あえて質問文記載のコードからあまり変えないようにしています。
たとえば
・if文で都道府県を判定するのではなく、エリア設定を別のスプレッドシートに入力しておき、複数エリアに対応させる
・getValues()を使用して動作速度を速める
・getActiveSheetやopenByID 経由ではなく、トリガー関数の引数から回答データを取得する
など、御自分で工夫してみて下さい。


#別解

こっちの方が簡単かもしれません。
↓↓↓
東海エリアシートのトリガーは現状のまま(変更時発火)にしておきます。
アイデアとしては、東海エリアシートの適当なセルに現時点の最終行をスクリプトで記録しておき、
フォームの回答が行われて、東海エリアシートの変更イベントが発火したら、
変更時点の最終行数と記録していた最終行数とを比較して、異なっていれば東海エリアの回答データが追加されたとみなし、グループ通知処理を行う、という流れです。

[東海エリア]シートのスクリプト

js

1function SendToGroupLine() { 2 ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); 3 // 記録しておいた最終行数を取得 4 oldRowLen = ss.getRange("Z1").getValue(); 5 // 現在の最終行数を取得 6 currentRowLen = ss.getLastRow(); 7 8 if (oldRowLen != currentRowLen) { 9 10 Logger.log("東海エリアのデータが追加されました") 11 // グループ通知処理 12 13 } 14 // 現在の最終行数をZ1セルに記録 15 ss.getRange("Z1").setValue(currentRowLen); 16} 17

投稿2021/08/20 11:52

編集2021/08/20 12:56
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dora_maru

2021/08/23 04:49

丁寧な回答、ありがとうございます! 早速試してみます。 試してみて、またわからないときは、質問させて頂きます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問