google formに回答があった時に、
スクリプトが実行されるように設定(「スプレッドシートから フォーム送信時」)しています。
自動返信メールを送るスクリプトです。
単にメールを送るだけでなく、
スプレッドシートの値をコピーしたり、
その値をもとにグラフを生成し、それをメールに添付したりするもので、
一回あたりの実行時間が5秒程度かかります。
このスクリプト実行の約5秒間の間に、
次のフォームを受信してしまうと、そのままエラーになってしまいます。
フォームが同時に送信された場合、
現在実行中のスクリプトが完了次第、準備ができるまで待ってもらうようなスクリプトを書く方法があればお教え下さい。
どうぞよろしくお願い致します。
function tillDraft(){ var ss = SpreadsheetApp.openById(SpreadsheetApp.getActiveSpreadsheet().getId()); var sheet = ss.getSheetByName("graph"); var ReferenceCell = sheet.getRange("s1"); //毎回VlookUPのために、値を更新する必要がある。 var EndCell = sheet.getRange("t1"); var ssID = "略"; var sheetID = sheet.getSheetId(); var driveID = "略"; //////////////////// //追加変数と、追加回答処理部分 //////////////////// var DataSheet = ss.getSheetByName("data"); const CValues = DataSheet.getRange('C:C').getValues(); var LastRow_Answered = CValues.filter(String).length; //返信済み打刻されている最終行。CValues(返信まち最終行)よりも、短い。 const CZValues = DataSheet.getRange('CZ:CZ').getValues(); var LastRow = CZValues.filter(String).length; //未処理の回答数をカウント var mishori_count = LastRow_Answered - LastRow; Logger.log(mishori_count) //未処理カウントが1以上の場合、これが0になるまで(1になるまで?)繰り返し処理 if(mishori_count >0){ Logger.log("ifクリア"); for(var i = mishori_count; i >=1; i--){ Logger.log("ループ実行"); var toshibango = DataSheet.getRange(LastRow,1).getValues(); var yokonaga = DataSheet.getRange(LastRow-1,42,LastRow-1, 89).getValues(); DataSheet.getRange(LastRow,1).copyTo(DataSheet.getRange(LastRow+1,1)); //通し番号コピってます DataSheet.getRange(LastRow-1,42,2,48 ).copyTo(DataSheet.getRange(LastRow,42,2, 48));//42列目〜89列目APからCK コピってます。 DataSheet.getRange(LastRow+1,104).setValue(new Date());//打刻 //最終行の回答番号を取得して、開始セルも終了セルもそれにする(つまり1枚のみPDF生成) var LatestAnswer = DataSheet.getRange(LastRow+1,1).getValue(); Logger.log(LatestAnswer); ReferenceCell.setValue(LatestAnswer); EndCell.setValue(LatestAnswer); //////////////////// //以下、PDF生成から下書き作成まで //////////////////// var yourName = sheet.getRange("K1").getValue(); var gmailAddress = sheet.getRange("s3").getValue(); var filename = "結果_" + yourName +"様.pdf" createPDF2(driveID, ssID,sheetID, filename); //下の関数を実行 createDraft2(gmailAddress, yourName, filename); //下の関数を実行 LastRow += 1 LastRow_Answered += 1 } } } function createPDF2(folderid, ssid, sheetid, filename){ // PDFファイルの保存先となるフォルダをフォルダIDで指定 var folder = DriveApp.getFolderById(folderid); // スプレッドシートをPDFにエクスポートするためのURL。このURLに色々なオプションを付けてPDFを作成 var url = "https://docs.google.com/spreadsheets/d/SSID/export?".replace("SSID", ssid); // PDF作成のオプションを指定 var opts = { exportFormat: "pdf", // ファイル形式の指定 pdf / csv / xls / xlsx format: "pdf", // ファイル形式の指定 pdf / csv / xls / xlsx size: "A4", // 用紙サイズの指定 legal / letter / A4 portrait: "true", // true → 縦向き、false → 横向き fitw: "true", // 幅を用紙に合わせるか sheetnames: "false", // シート名をPDF上部に表示するか printtitle: "false", // スプレッドシート名をPDF上部に表示するか pagenumbers: "false", // ページ番号の有無 gridlines: "false", // グリッドラインの表示有無 fzr: "false", // 固定行の表示有無 gid: sheetid // シートIDを指定 sheetidは引数で取得 }; var url_ext = []; // 上記のoptsのオプション名と値を「=」で繋げて配列url_extに格納 for( optName in opts ){ url_ext.push( optName + "=" + opts[optName] ); } // url_extの各要素を「&」で繋げる var options = url_ext.join("&"); // optionsは以下のように作成しても同じです。 // var ptions = 'exportFormat=pdf&format=pdf' // + '&size=A4' // + '&portrait=true' // + '&sheetnames=false&printtitle=false' // + '&pagenumbers=false&gridlines=false' // + '&fzr=false' // + '&gid=' + sheetid; // API使用のためのOAuth認証 var token = ScriptApp.getOAuthToken(); // PDF作成 var response = UrlFetchApp.fetch(url + options, { headers: { 'Authorization': 'Bearer ' + token } }); // var blob = response.getBlob().setName(filename); //} // PDFを指定したフォルダに保存 folder.createFile(blob); } ////////////////////////////////////////// //CREATE DRAFT ////////////////////////////////////////// function createDraft2(gmailAddress, yourName, filename){ //var accessToken = e.messageMetadata.accessToken; //GmailApp.setCurrentMessageAccessToken(accessToken); var attachedPDF = DriveApp.getFilesByName(filename).next(); var body = yourName + "様\n" + "\n"+ "結果をお送りいたします。\n"+ "添付ファイルをご確認くださいませ。\n"+ "\n"+ GmailApp.createDraft(gmailAddress, "結果", body,{attachments:[attachedPDF]}); }
回数というよりは実行時間なんで、1日 288回でも 1回あたり10秒平均くらいなら問題ないですよ。
https://qiita.com/mitonattou919/items/de415bb9302a52d52e2e
ただ、検索もしくは質問すべきは、
> 現在実行中のスクリプトが完了次第、準備ができるまで待ってもらう
という方法ではなくて、
>フォームを同時に送信されると、エラーになってしまいます。
を解決する方法だと思うので、どういうコードでどういうエラーが発生してるかを書いて質問した方がよいです。
どうもありがとうございました。
スクリプト実行中には、
その同じスクリプトを実行することはできない」ということで、
これを解決するために「順番待ち」のようなことができるのかどうかという質問に変更致しました。
もしも、そういった方法がないようであれば、
5〜10分おきに、まとめて自動返信を送るようなスクリプトに変更をしようと思います。
アドバイスを、どうもありがとうございました!
script lock の機能がありますが、起こっている問題を再現させられないことには適切な回答は不可能だと思います。
再現可能なミニマルなコードを提示してくださいませんか?
ご検討くださり、どうもありがとうございます。
只今、コードを追加致しました。
アドバイスをいただけますと幸いです。
あなたの回答
tips
プレビュー