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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Google フォーム

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

Google カレンダー

Google カレンダーは、Google社が提供する無料のスケジュール管理ツールです。パソコンやスマートフォン、タブレットなどからアクセスし、スケジュールの追加・変更が可能。Googleアカウントがあれば誰でも使用できます。

Google API

Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

Google

Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

Q&A

解決済

1回答

1521閲覧

googleフォームからGASを利用したワークフローの作成について

greentea

総合スコア1

Google フォーム

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

Google カレンダー

Google カレンダーは、Google社が提供する無料のスケジュール管理ツールです。パソコンやスマートフォン、タブレットなどからアクセスし、スケジュールの追加・変更が可能。Googleアカウントがあれば誰でも使用できます。

Google API

Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

Google

Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

0グッド

2クリップ

投稿2022/08/04 04:55

前提

googleフォームを使用し、フォーム送信が発生した際に、上長宛にメールを送信し、申請の承認可否を決定させようと、拾い物のGASを変更しながら作成していたところ、以下のエラーメッセージが発生しました。

実現したいこと

①googleフォームの送信⇒上長に承認可否メールを送信
②メール上に承認可否のリンクを設定し、承認または不可を決定。スプレッドシートに記載。
③承認となった申請をgoogleカレンダーに反映

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

TypeError: Cannot read property 'response' of undefined(行 9、ファイル「コード」)

該当のソースコード

FormApp.getActiveForm()

1function FormSubmit (e) { 2 // プレーンテキストのメール本文 3 var body = "勤怠申請の確認をお願いいたします。\n\n"; 4 // HTMLテキストのメール本文 5 var htmlBody = "<p>勤怠申請の確認をお願いいたします。</p>"; 6 7 // GoogleFormから回答内容を取得 8 var itemResponses = e.response.getItemResponses(); 9 var recipientMail = ""; 10 var approverMail = ""; 11 12 for (var i = 0 ; i < itemResponses.length; i++) { 13 var formData = itemResponses[i]; 14 var formLabel = formData.getItem().getTitle(); 15 var response = formData.getResponse(); 16 17 switch (formLabel) { 18 case "承認者のメールアドレス": 19 approverMail = response; 20 break; 21 case "申請者名": 22 name = response; 23 break; 24 case "申請日": 25 date = response; 26 break; 27 case "申請内容": 28 title = response; 29 break; 30 case "申請理由": 31 content = response; 32 break; 33 case "備考": 34 other = response; 35 break; 36 case "出社時間": 37 //attachedDocument = response; 38 starttime = response; 39 break; 40 default: 41 endtime = response; 42 break; 43 } 44 } 45 46 var spreadSheetId = "XXXXXXX"; // スプレッドシートのID 47 var spreadsheet = SpreadsheetApp.openById(spreadSheetId); 48 var activeSheet = spreadsheet.getActiveSheet(); 49 50 // ダミーのURL 51 var url = "https://XXXXXX/kintai"; 52 53 body = body + "【件名】:勤怠申請" + "\n【申請者名】:" + name + "\n【申請内容】:" + date + " " + title + "\n【申請理由】:" + content + "\n【出社時刻】:" + starttime + "\n【退勤時刻】:" + endtime + "\n【備考】:" + other; 54 htmlBody = htmlBody + "<span>【件名】:勤怠申請" + title + "</span><br><span>【申請者名】:" + name + "</span><br><span>【申請内容】:" + date + " " + title + "</span><br><span>【申請理由】:" + content + "</span><br><span>【出社時刻】:" + starttime + "</span><br><span>【退勤時刻】:" + endtime + "</span><br><span>【備考】:" + other + "</span><br><br>"; 55 htmlBody = htmlBody + "<a href=" + url + ">承認</a> <a href=" + url + ">否認</a>"; 56 GmailApp.sendEmail(approverMail, title, body, {htmlBody: htmlBody}); 57} 58 59function calender_part() { 60 //シートを取得 61 var activeSpreadSheet = SpreadsheetApp.getActiveSpreadsheet(); // 現在のSpreadSheetを取得 62 var Sheet = activeSpreadSheet.getSheetByName("フォームの回答 1"); // spreadsheetのシートを指定 63 64 //データのある一番下の行を取得 65 var lastRow = Sheet.getLastRow(); 66 67 //各データを取ってくる 68 var name = Sheet.getRange("C" + lastRow).getValue(); 69 var date = Sheet.getRange("D" + lastRow).getValue(); 70 var date2 = Sheet.getRange("E" + lastRow).getValue(); 71 72 //登録するカレンダーIDを呼び出してeventへ格納 73 var event = CalendarApp.getCalendarById('XXXXXXXXXXXXX'); 74 75 //createAllDayEventでカレンダーへイベントを登録 76 event.createAllDayEvent(name + ":" + date2,date); 77 78} 79

試したこと

①googleフォームを作成
②リンクするスプレッドシートを作成
③スプレッドシートからスクリプトを記述
④トリガーの設定
⑤スクリプトのデバッグ
⇒エラー発生。エラー内容は以下の通り。
「TypeError: Cannot read property 'response' of undefined(行 9、ファイル「コード」)」
⑥google先生で調査したところ、上記エラー原因が、レスポンスの呼び出しができていないことによるものだと判明。ただ、呼び出しのキーとなる「FormApp.getActiveForm()」については記述していることから、以下を追加。

{
"timeZone": "Asia/Tokyo",
"dependencies": {
},
"webapp": {
"access": "ANYONE",
"executeAs": "USER_DEPLOYING"
},
"exceptionLogging": "STACKDRIVER",
"oauthScopes": ["https://www.googleapis.com/auth/spreadsheets.currentonly", "https://www.googleapis.com/auth/spreadsheets", "https://www.googleapis.com/auth/forms", "https://www.googleapis.com/auth/gmail.send", "https://www.googleapis.com/auth/gmail.compose", "https://www.googleapis.com/auth/gmail.modify", "https://mail.google.com/", "https://www.googleapis.com/auth/gmail.addons.current.action.compose"],
"runtimeVersion": "V8"
}

⑦上記⑥を記述後、一度トリガーを削除し、再度トリガー設定。
トリガー設定は「FormSubmit」でフォームから呼び出し、フォーム送信時に都度通知が来るように設定。
⑧「FormSubmit」のデバッグをかけて同一エラーとなる。
⑨エラーが出てても、正常に動作するかもしれないと思い、フォームから送信テストを行ったが、「Summary of failures for Google Apps Script」というメールが到着し、同一エラーをはくことを確認。
⑩フォームの再作成を実施し、上記の流れを漏れなく実施してもみたが、結果は同様。
⑪スプレッドシートからスクリプトを設定したのが原因かと思い、フォームからスクリプトを設定してみたが、結果は上に同じ。

スプレッドシートへのフォーム回答は反映されているが、何が原因かが分からない状態。

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

当方、SEもどきでプログラミング開始1ヶ月の初心者です。プログラミングは参考コードを基にあーでもないこーでもないといじっているレベルの人間です。色々調べてみましたが、いきづまったため、お手伝いいただけると助かります。

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

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

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

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

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

guest

回答1

0

ベストアンサー

eのnamedValuesでフォーム回答データにアクセスするとよいかもしれません。
フォームにバインドしたスクリプトと、スプレッドシートにバインドしたスクリプトで、フォーム回答データへのアクセスの仕方が違うようです。
以下が参考になりそうです。
https://teratail.com/questions/333980

投稿2022/08/04 14:18

mmkkmm

総合スコア103

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

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

greentea

2022/08/08 00:19 編集

アドバイス有難うございます。 フォームからスクリプト:response、スプレッドシートからスクリプト:namedValuesという認識はなかったので、助かります。参考のURLも分かり易く勉強になります。 ただ、結局namedValuesでもうまく動かなかったため、別のアプローチで作成し動くようにしました。 他の方の参考まで ### 該当のソースコード function generateBodies(values){ const [timeStamp, email, name, date, content, reason, starttime, endtime, other] = values;//フォームから出力されたカラム名たち let plain = '';//送信したい内容 //文字列内で変数を宣言するときはバッククォート「`」を使用すること plain += `・申請者 : $[name] \n`; plain += `・申請日: ${date}\n`; plain += `・申請内容: ${content}\n`; plain += `・申請理由: ${reason}\n`; plain += `・出勤時間: ${starttime} \n`; plain += `・退勤時間: ${endtime}\n`; plain += `・備考: ${other}\n\n`; let html = '<ul>'; html += `<li>申請者 : ${name}</li>`; html += `<li>申請日 : ${date}</li>`; html += `<li>申請内容: ${content}</li>`; html += `<li>申請理由: ${reason}</li>`; html += `<li>出勤時間: ${starttime}</li>`; html += `<li>退勤時間: ${endtime}</li>`; html += `<li>備考: ${other}</li>`; html += '</ul>'; return { email: email, plain: plain, html: html }; } function sendMessage(e) { const row = e.range.getRow(); const sheet = e.range.getSheet(); sheet.getRange(row, 10).setValue('確認中'); const bodies = generateBodies(e.values); let url = 'https://XXXXXXXXXXXXX'; //公開したウェブアプリケーションのURL url += `?row=${row}&answer=`; const recipient = 'XXXXXXXXXXXXXXX.co.jp'; //承認者メールアドレス const subject = '休暇申請のお知らせ'; let body = ''; body += '勤怠に関する申請がありました。\n\n'; body += bodies.plain; body += '承認する場合は、以下URLをクリックしてください\n'; body += url + 'ok'; body += '却下する場合は、以下URLをクリックしてください\n'; body += url + 'ng'; let html = ''; html += '<h1>申請のお知らせ</h1>'; html += '<p>以下の申請がありました。</p>'; html += bodies.html; html += `<p>承認する場合は、<a href="${url}ok">[承認]</a>をクリックしてください</p>`; html += `<p>却下する場合は、<a href="${url}ng">[却下]</a>をクリックしてください</p>`; GmailApp.sendEmail(recipient, subject, body, {htmlBody: html}); } function doGet(e) { const row = e.parameter.row; const sheet = SpreadsheetApp.getActiveSheet(); const values = sheet.getRange(row, 1, 1, 10).getValues()[0];//承認/却下を入力する行番号 const bodies = generateBodies(values); var answer = e.parameter.answer; const result = { ok: '承認', ng: '却下' }; sheet.getRange(row, 10).setValue(result[answer]);//ここの行番号も注意 const recipient = bodies.email; const subject = `休暇申請${result[answer]}のお知らせ`; let body = ''; body += `以下の申請が${result[answer]}されました。\n\n`; body += bodies.plain; let html = ''; html += `<h1>休暇申請${result[answer]}のお知らせ</h1>`; html += `<p>以下の申請が${result[answer]}されました。</p>`; html += bodies.html; GmailApp.sendEmail(recipient, subject, body, {htmlBody: html}); html = ''; html += `<h1>休暇申請の${result[answer]}</h1>`; html += `<p>あなたは以下の申請を${result[answer]}しました</p>`; html += bodies.html; return HtmlService.createHtmlOutput(html); } function calender_part() { //シートを取得 var activeSpreadSheet = SpreadsheetApp.getActiveSpreadsheet(); // 現在のSpreadSheetを取得 var Sheet = activeSpreadSheet.getSheetByName("フォームの回答 1"); // spreadsheetのシートを指定 //データのある一番下の行を取得 var lastRow = Sheet.getLastRow(); //各データを取ってくる var name = Sheet.getRange("C" + lastRow).getValue(); var date = Sheet.getRange("D" + lastRow).getValue(); var date2 = Sheet.getRange("E" + lastRow).getValue(); var approval = Sheet.getRange("J" + lastRow).getValue(); //登録するカレンダーIDを呼び出してeventへ格納 var event = CalendarApp.getCalendarById('XXXXXXXXXXXXXXXXX/XXXXXX/XXX'); //createAllDayEventでカレンダーへイベントを登録 event.createAllDayEvent(name + ":" + date2,date); } ```
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問