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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Google Apps Script

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

Q&A

1回答

2084閲覧

form 自動返信 同時回答 lockサービスについて

renren.778899

総合スコア7

Google Apps Script

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

0グッド

3クリップ

投稿2020/02/12 17:23

編集2020/02/13 06:07

いつもお世話になっております。

本件ご教示頂けますでしょうか。
以下ご参照ください。

<現在>
formの回答をスプレットに集計
GASで上記スプレットの回答内容を自動送信

<改善したいこと>
おそらく最終行を取得し、本文に引用するコードになっているため
formに同時刻に回答があった場合にコンマ数秒差で後に回答した内容が2通送信される
例)Aさん→回答時刻00:00:01 
Bさん→回答時刻00:00:03
上記2名のメール内容はBさんの回答内容になってしまう。

<試したこと>
lockサービス(うまくいきませんでしたが・・)
以下コードを入れてみました。
var lock = LockService.getScriptLock();
lock.waitLock(30000);
lock.releaseLock();//ロック解除
}

ご参考に以下が、現在組んでいるスクリプトです。

lockを入れるところや構文?が違うのか
そもそも最終行を取得し、本文に引用するコードになっているからダメなのか。。

乱文大変申し訳ございません。。
どうかよろしくお願いします。

【2/13追記】
waitlockでtry~cachの構文にしてみましたが、症状は改善されませんでした。
→同内容のメールが二通送信される。

function onFormSubmit() { Logger.log('sendMailGoogleForm() debug start'); } var lock = LockService.getDocumentLock();//ロック try { lock.waitLock(30000);//30秒待つ // メール送信先 var admin = "○○○○@○○○○.co.jp"; // 管理者(必須)→管理者アドレス var sendername = "管理者";//送信者名(必須) var cc = "○○○○@○○○○.co.jp"; // var bcc = admin; // Bcc: var reply = admin; // Reply-To: var to = ''; // To: (入力者のアドレスが自動で入ります) var d = new Date(); var day = Utilities.formatDate(d,'JST', 'M/dd'); // -------------------------------------- 定義---------------------- var Spreadsheet = SpreadsheetApp.openById("abcdefgh1234567890"); var sheet = Spreadsheet.getSheetByName("メールフォーム");   //スプレッドとシートの指定 var ss = Spreadsheet.getSheetByName("宛先リスト"); var atesaki = ss.getRange(3,2).getValue();                              //宛先の指定 // var atesaki2 = ss.getRange(4,2).getValue(); var rows = sheet.getRange(1, 1).getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow(); //A列の最終行を取得する var cols = sheet.getLastColumn(); var rg = sheet.getDataRange(); Logger.log("rows="+rows+" cols="+cols); var tenpo = sheet.getRange(rows, 5).getValue();  //件名に店舗名 var name = sheet.getRange(rows, 6).getValue(); //件名に氏名 // ---------------------------------------------------------------- // 設定エリアここから //------------------------------------------------------------ + "------------------------------------------------------------\n"; // 件名、本文、フッター var subject = "【日報】【"+day+"】"+tenpo+"/"+name+"";  var body = "※本メールは自動配信となります。\n\n各位\n\nお疲れ様です。\n本日の実績報告となります。\n\n"// var footer = "------------------------------------------------------------\n\n" + "以上、よろしくお願いいたします。";// // 入力カラム名の指定 var NAME_COL_NAME = '名前'; var MAIL_COL_NAME = 'メールアドレス'; //------------------------------------------------------------ // 設定エリアここまで //------------------------------------------------------------ try{ // スプレッドシートの操作 var sheet = Spreadsheet.getSheetByName("メールフォーム");  var rows = sheet.getRange(1, 1).getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow(); var cols = sheet.getLastColumn(); var rg = sheet.getDataRange(); Logger.log("rows="+rows+" cols="+cols); // メール件名・本文作成と送信先メールアドレス取得 for (var i = 1; i <= cols; i++ ) { var col_name = rg.getCell(1, i).getValue(); // カラム名 var col_value = rg.getCell(rows, i).getValue(); // 入力値 if (col_name === "タイムスタンプ"){ continue;} if (col_name === "日付"){ continue;} if (col_name === "(集計用)当月"){ continue;} if (col_name === "(内訳)購入サポートから"){ continue;} body += col_name + "\n"; body += col_value + "\n\n"; if ( col_name === NAME_COL_NAME ) { body = col_value+" 様\n\n"+body; } if ( col_name === MAIL_COL_NAME ) { to = col_value; } } body += footer; // 送信先オプション var options = {name: sendername}; if ( cc ) options.cc = cc; if ( bcc ) options.bcc = bcc; if ( reply ) options.replyTo = reply; // メール送信 if ( atesaki ) { MailApp.sendEmail(atesaki, subject, body, options); }else{ MailApp.sendEmail(admin, "【失敗】Googleフォームにメールアドレスが指定されていません", body); } }catch(e){ MailApp.sendEmail(admin, "【失敗】Googleフォームからメール送信中にエラーが発生", e.message); }  } catch (e) { //ロック取得できなかった時の処理等を記述する var checkword = "ロックのタイムアウト: 別のプロセスがロックを保持している時間が長すぎました。"; //通常のエラーとロックエラーを区別する if(e.message == checkword){ //ロックエラーの場合 msg = "誰かまだ使ってるみたい"; }else{ //ソレ以外のエラーの場合 msg = e.message; }   } finally { //ロックを開放する lock.releaseLock(); } コード

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

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

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

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

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

kikukiku

2020/02/13 03:30

tryの範囲ですが、定義の中にも処理が入っているので、 var lock = LockService.getScriptLock(); 上記以外のすべてを囲うようにしてください。
macaron_xxx

2020/02/13 04:02

lockなんてする必要ありません。 フォーム側のスクリプトに書いて、フォーム送信のトリガでe.responseにて、フォーム送信項目を取得すればよいです。 スプレッドシートから取得するからだめなのです。
kikukiku

2020/02/13 04:15

記述されている質問文を見ると、macaron_xxxさんの考えに至ることは当然と思います。 ただし、推察しかないのですが、この質問は下記の続きと思われます。 https://teratail.com/questions/239977 ここの記事には、複数のユーザが登録すると、1つのスプレッドシートに記述されていく ようなことが記述されています。 たぶん、この構造は変えられないのではないかと推察していますが、 もちろん、macaron_xxxさんの言われているとおり、スプレッドシートを廃止できれば それが望ましいと考えます。
kikukiku

2020/02/13 04:51

lock.releaseLock()が2つあります。1つでOKのはずなのですが。 括弧の数も合っていません。
renren.778899

2020/02/13 05:46

macaron_xxxさん、kikukikuさん、 大変わかりづらく申し訳ございません。。 kikukikuさんの推察の通り、この構造を変えることは現状難しく、できる限りこのまま行きたいと考えております・・ lock.releaseLock()と括弧の数修正しました。 もう一度試しましたが、同じ状態でした・・
macaron_xxx

2020/02/13 05:52

kikukikuさん というより、構造を変えないと解決しません。 なぜならば、このスクリプトでロックしたところで、データの書き込みを制御することはできないからです。 ロックが可能であるとしても300名の同時回答にロックしていては、タイムエラーがでるのは想像に難くないです。 スプレッドシートは、フォーム回答で自動で書き込まれるシートではないのですか? であるならば、何の構造も変えることなくスクリプトを書き換えるだけで問題なく動くはずですが。
renren.778899

2020/02/13 06:27

macaron_xxxさん フォーム回答で自動で書き込まれるシートはあるのですが、 それをメールフォームというシートに転記して、そのシートを参照するようにしています。 理由は2点あって ①フォームの回答内容が追加や削除が発生した場合にメールの仕上がり?を編集するため →例)新しい項目を追加→自動書き込みシートの一番右にくる(そうなるとメール本文ないでは一番下に位置されてしまう) ②フォームでは当日の実績を報告→メール本文に月間合計の記載が必要な ため、この集計をメールフォームシート上で行っている。 このような場合でも、macaron_xxxさんがおっしゃるようなスクリプトの書き換えでも 問題はいでしょうか?
macaron_xxx

2020/02/13 07:52

集計だけは単純な置き換えでは無理ですね。 代案として、最終行を取得するのではなく、メール送信行にチェックをつけていき、チェックのない行に対してメール送信する方法が考えられます。
renren.778899

2020/02/13 08:29

なるほど!例えばそうした場合に 現状以下のようにほぼ同時に2件の回答があった場合、Bさんの回答内容が2通送られてしまいますが・・ Aさん→回答時刻00:00:01  Bさん→回答時刻00:00:03 でも回答内容が自動で書き込まれるスプレットにはきちんと2名分の回答内容が入っています。 代案では2名分にチェックが入って、メール内容を判別できるのでしょうか??
guest

回答1

0

Form側のスクリプトで実行することをおすすめします。

投稿2020/02/13 00:02

macaron_xxx

総合スコア3191

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問