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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Google スプレッドシート

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

Google フォーム

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

Gmail

GmailとはGoogleによって提供されているウェブメールのサービスのことです。

Google Apps Script

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

Q&A

解決済

1回答

1049閲覧

GAS_Googleフォーム送信時に指定の宛先へ送信するメールにフォーム内容を抽出したPDFとスプレッドシートを添付したい

e-y

総合スコア3

Google スプレッドシート

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

Google フォーム

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

Gmail

GmailとはGoogleによって提供されているウェブメールのサービスのことです。

Google Apps Script

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

0グッド

0クリップ

投稿2022/09/03 09:59

編集2022/09/08 21:52

前提

Googleフォームを使用して依頼フォームを作成しているのですが、依頼を受領する側の作業効率アップのために
フォーム内容をスプレッドシートテンプレート①に抽出しPDF化したものと、
そのPDFとは別の用途で使用するスプレッドシートテンプレート②にフォームの回答の一部を抽出したもの、
のふたつを指定したひとつの宛先へ自動送信するGASを作成したいです。

実現したいこと

  • フォーム内容の全回答をスプレッドシートテンプレート①に抽出してPDF化する
  • フォーム内容の一部をスプレッドシートテンプレート②に抽出したスプレッドシートを作成する
  • 作成したPDFとスプレッドシートを添付したメールを、フォーム送信時に指定の宛先へ送付する

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

PDF化したものを添付して指定の宛先へ送付するコードは実装できたのですが、
複数の添付資料(PDFとスプレッドシート)を
ひとつの宛先に送付するにはどのようなコードにすればよいのかが分かりません。

エラーメッセージ

該当のソースコード

GAS

1//フォーム送信時にPDFを添付して指定宛先にメールを送信 2// FormApp.getActiveForm() 3function myFunction(event) { 4 5 //今日の日付 6 var request_date = new Date(); 7 8 // フォーム 9 var res = event.response.getItemResponses(); 10 11 var staff_name; 12 var cc_mailaddress; 13 var proposal_num; 14 var project_title; 15 var address; 16 var resuest_timing; 17//ほか項目多数(省略) 18 19 for (var n in res) { 20 var item = res[n]; 21 var name = item.getItem().getTitle(); 22 var value = item.getResponse(); 23 24 switch (name) { 25 case '担当': 26 staff_name = value; break; 27 case 'CC送付先(メールアドレス)': 28 cc_mailaddress = value; break; 29 case '番号': 30 proposal_num = value; break; 31 case '件名': 32 project_title = value; break; 33 case '住所': 34 address = value; break; 35 case '依頼タイミング': 36 resuest_timing = value; break; 37  //ほか項目多数(省略) 38 } 39 } 40 41 // スプレッドシートURLから抽出したIDを入力 42 var ssid = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; 43 var ss = SpreadsheetApp.openById(ssid); 44 45 var pdfss = ss.getSheetByName("【依頼シート】"); 46 var sheetid = ss.getActiveSheet().getSheetId(); 47 48 pdfss.getRange("U3").setValue(request_date); //依頼日 49 pdfss.getRange("C3").setValue(staff_name); //担当 50 pdfss.getRange("H3").setValue(cc_mailaddress); //CC送付先(メールアドレス) 51 pdfss.getRange("F5").setValue(proposal_num); //番号 52 pdfss.getRange("F9").setValue(project_title); //件名 53 pdfss.getRange("F10").setValue(address); //住所 54 pdfss.getRange("K5").setValue(resuest_timing); //依頼タイミング 55 //ほか項目多数(省略) 56 57 SpreadsheetApp.flush(); 58 59 // 以下PDF化コード(サイズ=A4) 60 61 var url = "https://docs.google.com/spreadsheets/d/SSID/export?".replace("SSID", ssid); 62 var url_ext = []; 63 64 var opts = { 65 format: "pdf", 66 size: "A4", 67 fzr: "false", 68 portrait: "true", 69 gridlines: "false", 70 printtitle: "false", 71 pagenumbers: "false", 72 fitw: "true", 73 sheetnames: "false", 74 gid: sheetid 75 }; 76 77 // 上記のoptsのオプション名と値を「=」で繋げて配列url_extに格納 78 for (optName in opts) { 79 url_ext.push(optName + "=" + opts[optName]); 80 } 81 82 // url_extの各要素を「&」で繋げる 83 var options = url_ext.join("&"); 84 Logger.log(options) 85 86 try { 87 // API使用のためのOAuth認証 88 var token = ScriptApp.getOAuthToken(); 89 90 var response = UrlFetchApp.fetch(url + options, { 91 headers: { 92 "Authorization": "Bearer " + token 93 } 94 }); 95 96 // ファイル名を作成「番号_件名(依頼タイミング)yyMMdd.pdf」 97 var fileName = proposal_num + "_" + project_title + "(" + resuest_timing + ")" + Utilities.formatDate(request_date, "JST", "yyMMdd"); 98 // Googleドライブ上のPDF格納先フォルダからIDを入力 99 var folder = DriveApp.getFolderById("yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"); 100 var fileBlob = response.getBlob().setName(fileName); 101 102 folder.createFile(fileBlob); 103 // メールアドレス 104 MailApp.sendEmail("abc@defg.jp", "【受付完了】" + proposal_num + "_" + project_title + "(担当:" + staff_name + ")", "---------------自動通知---------------\n" + "\n" + "依頼を受け付けましたのでご確認ください。\n" + "\n" + 105 Utilities.formatDate(request_date, "JST", "yyyy/MM/dd H:mm"), { 106 attachments : [fileBlob] 107 }); 108 109 } catch (e) { 110 Logger.log("ファイル生成に失敗しました" + e) 111 } 112}

GAS

1FormApp.getActiveForm(); 2 3// var targetFolderId = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" 4 5function renrakuhyo(e) { 6 7 // テンプレが格納されているフォルダを定義する 8 var folder = DriveApp.getRootFolder(); 9 var folderFiles = folder.getFiles(); 10 11 // テンプレートファイルIDを設定する 12 var fileId = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" 13 14 var staff_name = ""; // staff_name 15 var request_date = ""; // request_date 16 var proposal_num = ""; // proposal_num 17 var project_title = ""; // project_title 18//中略 19 var fin_num = ""; // fin_num 20 var results = ""; // 全結果 21 22 //フォームの回答データ部分を取得 // get data from the form 23 var itemResponses = e.response.getItemResponses(); 24 // store results and several keys 25 // 項目と回答を抽出する 26 var x = ""; // contents 27 var y = ""; // results 28 itemResponses.forEach(function(itemResponse){ 29 x = itemResponse.getItem().getTitle() 30 y = itemResponse.getResponse() 31 results += '【' + x + '】\n' 32 results += y + '\n\n' 33 if(x == "担当"){ 34 staff_name = y;} 35 else if (x == "依頼日"){ 36 request_date = y;} 37 else if (x == "番号"){ 38 proposal_num = y;} 39 else if (x == "件名"){ 40 project_title = y;} 41//中略 42 else if (x == "最終番号"){ 43 fin_num = y;} 44 }); 45 46 // スプレッドシートのコピーと更新 47 var date = new Date(); //ファイル名の日付部分作成 48 var formattedDate = Utilities.formatDate(date, "JST", "yyyy'年'MM'月'dd'日'"); 49 //コピー元のファイルを開く 50 var file = DriveApp.getFileById(fileId); 51 //コピーを作成,作成したコピーを参照 52 var newFile = file.makeCopy(proposal_num); 53 //コピーしたファイルをすぐに更新するため,IDを取得 54 var newid = newFile.getId(); 55 var spreadsheet = SpreadsheetApp.openById(newid) 56 57 //シートを取得する 58 var sheet = spreadsheet.getSheets()[0] ; 59 var textFinder = sheet.createTextFinder('input1'); 60 textFinder.replaceAllWith(staff_name); 61 var textFinder = sheet.createTextFinder('input2'); 62 textFinder.replaceAllWith(request_date); 63 var textFinder = sheet.createTextFinder('input3'); 64 textFinder.replaceAllWith(proposal_num); 65 var textFinder = sheet.createTextFinder('input4'); 66 textFinder.replaceAllWith(project_title); 67//中略 68 var textFinder = sheet.createTextFinder('input14'); 69 textFinder.replaceAllWith(fin_num); 70 71 // 変更内容を即反映 72 SpreadsheetApp.flush(); 73 74 // ファイルを開き直す 75// var newid = newFile.getId(); 76 var document = DriveApp.getFileById(newid) 77 var url = 'https://docs.google.com/document/d/'+newid 78 results += 'Your spreadsheet is created at ' + url; 79 80 // ファイル名を作成「番号_◯◯yyMMdd」 81 var fileName = proposal_num + "_" + "◯◯" + Utilities.formatDate(request_date, "JST", "yyMMdd"); 82 // Googleドライブ上のスプレッドシート格納先フォルダからIDを入力 83 var folder = DriveApp.getFolderById("vvvvvvvvvvvvvvvvvvvvvvvvvvvvv"); 84 var fileBlob = response.getBlob().setName(fileName); 85 86 folder.createFile(fileBlob); 87 88//このうしろにPDFの記述&さいごにメール本文??? 89 90}

試したこと

PDFを添付して送信するコードが完成したのですが、スプレッドシートテンプレート②にフォームの一部の項目を
反映させるコードを途中まで書いたのですがメール送信GASにどのように追加すれば良いのかがわかりません。
下記のサイトを参考にスプレッドシートテンプレート②用のコードを作成してみましたが、
PDF化したいわけではないのでつなげ方が分からず困っております。
■GoogleスプレッドシートからPDF生成とメール送信
https://qiita.com/yamadasuzaku/items/fdec0813c704a6a2784a

それとも同じフォームの回答を使用するので全く別のコードになるのでしょうか。
お力をお貸しください。よろしくお願いいたします。

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

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

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

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

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

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

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

e-y

2022/09/04 12:42 編集

回答いただいたスクリプトを参考に組合せてみましたがエラーで先に進めません。 保存しようとすると下記のようなエラーが出ます。 「構文エラー: SyntaxError: Identifier 'ssid2' has already been declared 行: 360 ファイル: 自動通知.gs」 おそらくPDF作成のところと被っているよと言われているのではないかと思いますが、どう直せば良いのかわかりません。 PDFだけ添付する場合は問題なく動作したのですが、その同じメールに同じフォームから回答を抽出したエクセルを添付するコードがうまく組み込めません。どこが間違えているのか教えていただけると幸いです。 ```GAS //フォーム送信時にPDFとスプシを添付して指定宛先にメールを送信 // FormApp.getActiveForm() function myFunction(event) { //今日の日付 var request_date = new Date(); // フォーム var res = event.response.getItemResponses(); var staff_name; var cc_mailaddress; var proposal_num; var project_title; var address; var resuest_timing; for (var n in res) { var item = res[n]; var name = item.getItem().getTitle(); var value = item.getResponse(); switch (name) { case '担当': staff_name = value; break; case 'CC送付先(メールアドレス)': cc_mailaddress = value; break; case '番号': proposal_num = value; break; case '件名': project_title = value; break; case '住所': address = value; break; case '依頼タイミング': resuest_timing = value; break; } } // スプレッドシートURLから抽出したIDを入力 var ssid1 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; var ss = SpreadsheetApp.openById(ssid1);  // 変換元のスプレッドシート名(タブ名) var pdfss = ss.getSheetByName("【依頼】"); var sheetid = ss.getActiveSheet().getSheetId(); pdfss.getRange("U3").setValue(request_date); //依頼日 pdfss.getRange("C3").setValue(staff_name); //担当 pdfss.getRange("H3").setValue(cc_mailaddress); //CC送付先(メールアドレス) pdfss.getRange("F5").setValue(proposal_num); //番号 pdfss.getRange("F9").setValue(project_title); //件名 pdfss.getRange("F10").setValue(address); //住所 pdfss.getRange("K5").setValue(resuest_timing); //依頼タイミング SpreadsheetApp.flush(); // 以下PDF化コード(サイズ=A4) var url = "https://docs.google.com/spreadsheets/d/SSID/export?".replace("SSID", ssid); var url_ext = []; var opts = { format: "pdf", size: "A4", fzr: "false", portrait: "true", gridlines: "false", printtitle: "false", pagenumbers: "false", fitw: "true", sheetnames: "false", gid: sheetid }; // 上記のoptsのオプション名と値を「=」で繋げて配列url_extに格納 for (optName in opts) { url_ext.push(optName + "=" + opts[optName]); } // url_extの各要素を「&」で繋げる var options = url_ext.join("&"); Logger.log(options) try { // API使用のためのOAuth認証 var token = ScriptApp.getOAuthToken(); var response = UrlFetchApp.fetch(url + options, { headers: { "Authorization": "Bearer " + token } }); // ファイル名を作成「番号_依頼(依頼タイミング)yyMMdd.pdf」 var fileName = proposal_num + "_" + project_title + "(" + resuest_timing + ")" + Utilities.formatDate(request_date, "JST", "yyMMdd"); // Googleドライブ上のPDF格納先フォルダからIDを入力 var folder = DriveApp.getFolderById("yyyyyyyyyyyyyyyyyyyyyyyyyyyyy"); const pdf = response.getBlob().setName(pdfName); folder.createFile(pdf); // メールアドレス MailApp.sendEmail("abc@def.jp", "【新規依頼】" + proposal_num + "_" + project_title + "(担当:" + staff_name + ")", "---------------自動通知---------------\n" + "\n" + "新規依頼を受け付けました。\n" + "エクセルファイルは必要に応じてダウンロードしてください。\n" + "\n" + Utilities.formatDate(request_date, "JST", "yyyy/MM/dd H:mm"), { attachments : [pdf,excel] }); } catch (e) { Logger.log("ファイル生成に失敗しました" + e) } } //以下はエクセルファイル作成用 // ssid2;スプレッドシートID、 // sheetname2;シート名 // filename2;保存するファイル名 function getExcel(ssid2, sheetname2, filename2) { const ssid2 = 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'; const sheetname2 = 'フォーマット'; // 変換元のシート名(タブ名) const filename2 = proposal_num + "_" + "ファイル名" + "_" + Utilities.formatDate(request_date, "JST", "yyMMdd"); const url2 = 'https://docs.google.com/spreadsheets/d/' + ssid2 + '/export?format=xlsx&gid=' + sheetid2; const option = { "headers" : { Authorization: "Bearer " + ScriptApp.getOAuthToken() }, "muteHttpExceptions" : true }; const blob = UrlFetchApp.fetch(url2, option).getBlob().setName(filename2); return blob;  //シートを取得する var textFinder = sheet.createTextFinder('input1'); textFinder.replaceAllWith(staff_name); var textFinder = sheet.createTextFinder('input2'); textFinder.replaceAllWith(request_date); var textFinder = sheet.createTextFinder('input3'); textFinder.replaceAllWith(proposal_num); var textFinder = sheet.createTextFinder('input4'); textFinder.replaceAllWith(project_title); } ```
退会済みユーザー

退会済みユーザー

2022/09/06 11:17

回答を書いていますのでしばらくお待ち下さい。 (回答に対するコメントは、この欄=元質問のコメント欄ではなく回答の下にあるコメント欄に書いていただけますと助かります。質問の方にコメントが書かれても回答者には通知が来ません。回答の方にコメントがあれば、回答者に通知が来てコメントされたことがすぐわかります。お手数ですがよろしくお願いします。)
退会済みユーザー

退会済みユーザー

2022/09/06 13:09

回答欄に追記しました。
guest

回答1

0

ベストアンサー

エクセルファイルの生成方法

下記のような関数で、指定したスプレッドシートからエクセルファイルのBlobを取得することができます。

js

1// ssid;スプレッドシートID、 2// sheetname;シート名 3// filename;保存するファイル名 4function getExcel(ssid, sheetname, filename) { 5 const ss = SpreadsheetApp.openById(ssid); 6 const sh = ss.getSheetByName(sheetname) 7 const sheetid = sh.getSheetId() 8 const url = 'https://docs.google.com/spreadsheets/d/' + ssid + '/export?format=xlsx&gid=' + sheetid; 9 const option = { 10 "headers" : { Authorization: "Bearer " + ScriptApp.getOAuthToken() }, 11 "muteHttpExceptions" : true 12 }; 13 const blob = UrlFetchApp.fetch(url, option).getBlob().setName(filename); 14 return blob; 15}
上の関数の使い方の例:

指定したスプレッドシートを、指定したファイル名で添付し、指定した宛先にメール送付する。

js

1const ssid = '変換したいスプレッドシートのスプレッドシートID'; 2const sheetname = 'シート1'; // 変換元のシート名(タブ名) 3const excel= getExcel(ssid, sheetname, '添付ファイル名.xlsx'); 4 5MailApp.sendEmail('宛先メールアドレス', ’件名’, '本文', {attachments:[excel]});

複数の添付ファイルをメールで送信する方法

attachments に複数の添付ファイルの配列を指定します。

js

1(略) 2const pdf = response.getBlob().setName(pdfName); 3(略) 4const excel= getExcel(ssid, sheetname, '添付ファイル名.xlsx'); 5 6MailApp.sendEmail('宛先メールアドレス', ’件名’, '本文', {attachments:[pdf, excel]});

コメント追記のコードの添削

コメントに追記されたコードを直すとしたら下記のようになります。
(変更が最小限になるようにしているので、冗長な部分があったりして最適化されていません。あしからず)

js

1//フォーム送信時にPDFとスプシを添付して指定宛先にメールを送信 2// FormApp.getActiveForm() 3function myFunction(event) { 4 5 //今日の日付 6 var request_date = new Date(); 7 8 // フォーム 9 var res = event.response.getItemResponses(); 10 11 var staff_name; 12 var cc_mailaddress; 13 var proposal_num; 14 var project_title; 15 var address; 16 var resuest_timing; 17 18 for (var n in res) { 19 var item = res[n]; 20 var name = item.getItem().getTitle(); 21 var value = item.getResponse(); 22 23 switch (name) { 24 case '担当': 25 staff_name = value; break; 26 case 'CC送付先(メールアドレス)': 27 cc_mailaddress = value; break; 28 case '番号': 29 proposal_num = value; break; 30 case '件名': 31 project_title = value; break; 32 case '住所': 33 address = value; break; 34 case '依頼タイミング': 35 resuest_timing = value; break; 36 } 37 } 38 39 // スプレッドシートURLから抽出したIDを入力 40 var ssid1 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; 41 var ss = SpreadsheetApp.openById(ssid1); 42 // 変換元のスプレッドシート名(タブ名) 43 var pdfss = ss.getSheetByName("【依頼】"); 44 var sheetid = ss.getActiveSheet().getSheetId(); 45 46 pdfss.getRange("U3").setValue(request_date); //依頼日 47 pdfss.getRange("C3").setValue(staff_name); //担当 48 pdfss.getRange("H3").setValue(cc_mailaddress); //CC送付先(メールアドレス) 49 pdfss.getRange("F5").setValue(proposal_num); //番号 50 pdfss.getRange("F9").setValue(project_title); //件名 51 pdfss.getRange("F10").setValue(address); //住所 52 pdfss.getRange("K5").setValue(resuest_timing); //依頼タイミング 53 54 SpreadsheetApp.flush(); 55 56 // 以下PDF化コード(サイズ=A4) 57 var url = "https://docs.google.com/spreadsheets/d/SSID/export?".replace("SSID", ssid1); //////////// 58 var url_ext = []; 59 60 var opts = { 61 format: "pdf", 62 size: "A4", 63 fzr: "false", 64 portrait: "true", 65 gridlines: "false", 66 printtitle: "false", 67 pagenumbers: "false", 68 fitw: "true", 69 sheetnames: "false", 70 gid: sheetid 71 }; 72 73 // 上記のoptsのオプション名と値を「=」で繋げて配列url_extに格納 74 for (optName in opts) { 75 url_ext.push(optName + "=" + opts[optName]); 76 } 77 78 // url_extの各要素を「&」で繋げる 79 var options = url_ext.join("&"); 80 Logger.log(options) 81 82 try { 83 // API使用のためのOAuth認証 84 var token = ScriptApp.getOAuthToken(); 85 86 var response = UrlFetchApp.fetch(url + options, { 87 headers: { 88 "Authorization": "Bearer " + token 89 } 90 }); 91 92 // Googleドライブ上のPDF格納先フォルダからIDを入力 93 var folder = DriveApp.getFolderById("yyyyyyyyyyyyyyyyyyyyyyyyyyyyy"); 94 95 // PDFファイルを作成:ファイル名「番号_依頼(依頼タイミング)yyMMdd.pdf」 96 var pdfName = proposal_num + "_" + project_title + "(" + resuest_timing + ")" + Utilities.formatDate(request_date, "JST", "yyMMdd") + '.pdf'; 97 var pdf = response.getBlob().setName(pdfName); 98 folder.createFile(pdf); 99 100 // テンプレートシートの取得 101 var ssid2 = 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'; 102 var sheetname2 = 'フォーマット'; // 変換元のシート名(タブ名) 103 var ss2 = SpreadsheetApp.openById(ssid2); 104 var sheet = ss2.getSheetByName(sheetname2); 105 106 // テンプレートシートの内容をフォーム入力値に置き換える。 107 sheet.createTextFinder('input1').replaceAllWith(staff_name); 108 sheet.createTextFinder('input2').replaceAllWith(request_date); 109 sheet.createTextFinder('input3').replaceAllWith(proposal_num); 110 sheet.createTextFinder('input4').replaceAllWith(project_title); 111 112 // エクセルファイルを作成:ファイル名「番号_ファイル名_yyMMdd.xlsx」 113 var excelName = proposal_num + "_" + "ファイル名" + "_" + Utilities.formatDate(request_date, "JST", "yyMMdd") + '.xlsx'; 114 var excel = getExcel(ssid2, sheetname2, excelName); 115 folder.createFile(excel); 116 117 // メールを送信する。 118 MailApp.sendEmail("abc@def.jp", "【新規依頼】" + proposal_num + "_" + project_title + "(担当:" + staff_name + ")", "---------------自動通知---------------\n" + "\n" + "新規依頼を受け付けました。\n" + "エクセルファイルは必要に応じてダウンロードしてください。\n" + "\n" + Utilities.formatDate(request_date, "JST", "yyyy/MM/dd H:mm"), {//------- 119 attachments: [pdf, excel] 120 }); 121 } catch (e) { 122 Logger.log("ファイル生成に失敗しました\n" + e.stack); 123 } 124} 125 126//以下はエクセルファイル作成用 127// ssid;スプレッドシートID、 128// sheetname;シート名 129// filename;保存するファイル名 130function getExcel(ssid, sheetname, filename) { 131 const ss = SpreadsheetApp.openById(ssid); 132 const sh = ss.getSheetByName(sheetname) 133 const sheetid = sh.getSheetId() 134 const url = 'https://docs.google.com/spreadsheets/d/' + ssid + '/export?format=xlsx&gid=' + sheetid; 135 const option = { 136 "headers": { Authorization: "Bearer " + ScriptApp.getOAuthToken() }, 137 "muteHttpExceptions": true 138 }; 139 const blob = UrlFetchApp.fetch(url, option).getBlob().setName(filename); 140 return blob; 141}

直した点は多岐にわたっていて全部は説明しにくいのですが、主要なところだけ。
まず「「構文エラー: SyntaxError: Identifier 'ssid2' has already been declared 行: 360 ファイル: 自動通知.gs」」の原因について:
これは、関数 getExcelの引数ssid2 と 関数内での 変数宣言 const ssid2 =~ が重複していることが原因です。

function getExcel(ssid2, sheetname2, filename2) { // <---ここに引数 ssid2 がある const ssid2 = 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'; // <---重複して ssid2 を const 宣言している、。

関数の場合、引数に指定した変数は、関数の中で再度constで宣言することはできません。
const ではなくvar にすれば、一応エラーは出なくなります。
しかし、せっかく関数で引数を用意しているのですから、呼び出し元の方で関数の引数に適切な文字列等を指定して呼び出した方が良いです。

// テンプレートシートの取得 var ssid2 = 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'; var sheetname2 = 'フォーマット'; // 変換元のシート名(タブ名) var ss2 = SpreadsheetApp.openById(ssid2); var sheet = ss2.getSheetByName(sheetname2); 略 var excel = getExcel(ssid2, sheetname2, excelName); // getExcel 関数の呼び出し元

こうすることで、ssid2, sheetgname2, excelName の中身が、getExcel関数の引数(ssid, sheetname, filename)それぞれに渡されます。


また、getExcel 関数内にある「テンプレートシートのinput1~input4 をフォームの回答内容に置き換える処理」を、getExcel 関数内から、呼び出し元 (myFynction内) に移動しています。
まず、修正前は textFinder で置き換える処理より前に return してしまっているので、テンプレートシート内の文字の置き換え処理自体が実行されていません。
そこで、textFinder を getExcel 内で returnより前に移動させてみます。しかしそうすると、今度は「変数 staff_nameや request_date が定義されていない」というエラーが起きてしまいます。
これを解決するために、置き換え処理の部分を myFynction内 に移動しています。
(移動せずとも解決する方法はありますが、ここでは簡単な方を取りました)


他にも直した点はいくつかありますが、細かいので説明は割愛させていただきます。修正前のコードを見比べてみてください。

投稿2022/09/04 03:48

編集2022/09/06 14:04
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

e-y

2022/09/07 02:05 編集

ご回答いただきありがとうございます。 直していただいたコードに書き換えてフォーム送信してみたところ、実行ログの方へ下記の内容が表示され、メールが飛んできませんでした。 2022/09/07 10:30:14 情報 format=pdf&size=A4&fzr=false&portrait=true&gridlines=false&printtitle=false&pagenumbers=false&fitw=true&sheetnames=false&gid=1432586422 2022/09/07 10:30:20 情報 ファイル生成に失敗しました Exception: Unexpected error while getting the method or property replaceAllWith on object SpreadsheetApp.TextFinder. at myFunction (◯◯宛:360:39) at __GS_INTERNAL_top_function_call__.gs:1:8 PDFは作成され、もうひとつのスプレッドシートテンプレートにもフォームの内容が反映されていましたが、メールが届きません。もし原因がわかるようでしたら教えていただきたいです。 また「 // テンプレートシートの内容をフォーム入力値に置き換える。」のところのinputデータが1~12まであるのですが、10~12のセルにinput1のstaff_nameに0、1、2が追加されたものが表示されていました。 例)山田0 input2のrequest_dateについても「Wed Sep 07 2022 10:29:56 GMT+0900 (Japan Standard Time)」となっていたので表記をyy/MM/ddに変更したいのですが、下記のように変更すればいいでしょうか。 sheet.createTextFinder('input2').replaceAllWith({Utilities.formatDate(request_date, "JST", "yyMMdd")}); 大変お手数とは重々承知しております。 もしよろしければご回答いただけると大変助かります。 よろしくお願いいたします。
退会済みユーザー

退会済みユーザー

2022/09/07 03:42 編集

>「2022/09/07 10:30:20 情報 ファイル生成に失敗しました Exception: Unexpected error while getting ~~」 このエラーですが、コード中 ssid2 に指定しているIDが間違っている可能性、もしくはGASにそのシートの編集権限がない可能性があります。 コード上、ssid2に指定しているIDが正しいテンプレート用スプレッドシートのIDとなっているか、再確認してください。 -------------- > また「 // テンプレートシートの内容をフォーム入力値に置き換える。」のところのinputデータが1~12まであるのですが、10~12のセルにinput1のstaff_nameに0、1、2が追加されたものが表示されていました。 → これは input10 、input11、 input12 が部分一致で 「input1」 にもマッチして置き換えられたためです。 (元質問中のコードでは中略してinput14まである点を見落としていました。すみません。) これを回避するには、下記のように、matchEntireCell(true)を入れて完全一致検索させればよいです。 sheet.createTextFinder('input1').matchEntireCell(true).replaceAllWith(staff_name); sheet.createTextFinder('input2').matchEntireCell(true).replaceAllWith(request_date); sheet.createTextFinder('input3').matchEntireCell(true).replaceAllWith(proposal_num); sheet.createTextFinder('input4').matchEntireCell(true).replaceAllWith(project_title); (以下略) ---------- > input2のrequest_dateについても「Wed Sep 07 2022 10:29:56 GMT+0900 (Japan Standard Time)」となっていたので表記をyy/MM/ddに変更したいのですが、下記のように変更すればいいでしょうか。 sheet.createTextFinder('input2').replaceAllWith({Utilities.formatDate(request_date, "JST", "yyMMdd")}); 中括弧はいらないと思います。 sheet.createTextFinder('input2').matchEntireCell(true).replaceAllWith(Utilities.formatDate(request_date, "JST", "yyMMdd")); -------- 追記: もし、GASのエディタで同じプロジェクト内に複数のコード.gs がある場合(左側に 無題.gs◯◯宛.gs などが2つ以上並んでいるような状態の場合)、各コード内の関数名は他のコード内の関数名と名前が被らないようにしてください。 たとえば仮に「無題.gs 」の中に myFunction() と getExcel()関数があり、「◯◯宛.gs」の中にも myFunction() と getExcel()関数 というように同じ名前の関数が存在していた場合、 GASはどの関数を実行すればいいかわからないため、ランダムに実行されてしまいます。 つまりコードを修正したつもりが、修正していない方の関数が実行されている可能性がある、ということです。 これを回避するには、不要なコード(関数)は削除するか、名前がかぶらないように変える等してください。
e-y

2022/09/07 04:37

回答ありがとうございます! ・ssid2のテンプレート用スプレッドシートのIDについて、じっくり確認してみましたが間違えておりませんでした。 ・シートの編集権限についても、まっさらな状態から自分で作って、特に複雑な手を加えたり権限変更したりしたものではないので大丈夫だと思うのですが…条件付き書式などと干渉したりするのでしょうか? ・inputの件は説明不足ですみませんでした。これで解決できそうです。ありがとうございます。 ・コードgsについて、たしかに複数ありまして、もうひとつのgsに入っている関数を確認しました。  function autoEmails(e) {  function fetchShortUrl() {  上記2つが設定されておりました。どちらも名前は被っていないので今回は大丈夫そうですが、今後気をつけます。
退会済みユーザー

退会済みユーザー

2022/09/07 05:39

「情報 ファイル生成に失敗しました Exception: Unexpected error while getting the method or property replaceAllWith on object SpreadsheetApp.TextFinder. at myFunction (◯◯宛:360:39) at」 のエラーについては、 私が回答欄に追記した形(getExcel関数も含めて)で手元の環境で実行しても、同じエラーを再現することができませんでした。(エラー発生せず正常にメールが届く) 申し訳ありませんがこちらでは原因不明です。 createTextFinder が原因ならば、 応急処置として、createTextFinder で文字列を置き換えるのではなく setValue() を使って指定したセル位置に値を貼り付ける方法であれば回避できるかもしれません。
e-y

2022/09/08 03:02

代案ありがとうございます。 // テンプレートシートの内容をフォーム入力値に置き換える。 sheet.createTextFinder('input1').replaceAllWith(staff_name); のところを、すべて下記のように変更したところ、きちんとテンプレートに入力されたエクセルがPDFと共に添付されたメールが飛んできました! // テンプレートシートの内容をフォーム入力値に置き換える。 sheet.getRange('A3').setValue(staff_name); どうしても実現したい内容だったので、本当に感謝してもしきれないです。 社内に相談できる相手もおらず四苦八苦しておりましたので、本当に助けられました。 ありがとうございました!
退会済みユーザー

退会済みユーザー

2022/09/08 03:37

フィードバックありがとうございます。解決してよかったです。
e-y

2022/09/08 04:53

すみません…1点だけ追加で質問してもいいでしょうか。 添付されたエクセルに反映している内容が、どうやらイコールになっておらず、ひとつ前にフォームに入力したものが反映しているようです。 実行ログには下記の文言がありますが、「失敗しました」とはなっていません。 format=pdf&size=A4&fzr=false&portrait=true&gridlines=false&printtitle=false&pagenumbers=false&fitw=true&sheetnames=false&gid=1432586422 フォームの内容をエクセルに反映させるタイミングの問題でしょうか? 解決策がわかればご教授いただけると助かります。
退会済みユーザー

退会済みユーザー

2022/09/08 06:24

textFinderからsetValueに変えた部分で、スプレッドシートへの記入が反映されていない可能性があります。 14個のsetValue処理を行う処理のあとに SpreadsheetApp.flush(); の一行を入れてみてください。
e-y

2022/09/08 08:23

ご回答いただきありがとうございます。 SpreadsheetApp.flush(); をいれたら、きちんと送信したフォームの内容が反映されました。 すみません、もう1点不具合を見つけてしまったのですが、別の質問として依頼した方がよければそうします。 一応、こちらにいったん書かせていただきます。 出力されたPDFおよびエクセルの回答に、チェックボックスの内容(複数回答可能なもの)が含まれています。 チェックをいれた1つめしか反映していないのですが、チェックをいれたすべてを反映させることは可能でしょうか? なにとぞ、ご教授のほどよろしくお願いいたします。
e-y

2022/09/08 09:59

複数回答取得のためにチェックボックスの項目をsetValuesにすればいいのかなと思い試してみましたが、エラーとなってしまいました。 エラー Exception: The parameters (number[]) don't match the method signature for SpreadsheetApp.Range.setValues. at myFunction(◯◯宛:243:24)
退会済みユーザー

退会済みユーザー

2022/09/08 11:42 編集

そのアンケート項目を、スプレッドシートのどのセルに、どのように記入したいのかによります。 たとえば items という変数に、チェックボックスの回答が最小1個、最大5個入るとして、 B10セルから始まってF10セルまで"横一列"に記入したいならば sheet.getRange(10,2,1,items.length).setValues([items]); となりますし B10セルから始まってB14セルまで"縦一列"に記入したいならば sheet.getRange(10,2,items.length,1).setValues(items.map(e=>[e])); となります。 ※上記は、チェックボックスを1個は絶対つけなければならないという設定になっている場合です。 チェックボックスがチェック0個でもよい設定になっている場合は、別のエラートラップ処理も追加で必要になります。 わからなければ別途質問を立てていただいたたほうが良いかもしれません。その際には、「フォームアンケートの該当チェックボックス項目」の画像と、「スプレッドシートのどのセルに、どのように記入したいのか」がわかる画像も付けてください。これらの情報がないと、また手さぐりになってしまい時間がかかると思います。
e-y

2022/09/08 12:52

ご返信いただきありがとうございます。 別途質問を立てさせていただきましたので、もしよろしければご回答いただけると幸いです。 大変お手数をおかけしておりますが、なにとぞよろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問