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

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

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

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

0回答

2970閲覧

Google apps Script使用の簡易申請フォーム、TypeErrorについて

bigi_bigi

総合スコア10

Google Apps Script

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2018/09/28 07:40

編集2022/01/12 10:55

前提・実現したいこと

Google apps Scriptを使用して簡易休日申請ワークフローを作成したい。
ソースコードはエラーになっておらず、実行すると多数のエラーが出ています。

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

1、doPost TypeError: undefined からプロパティ「shonin」を読み取れません。(行 3、ファイル「doPost」) formSubmit 2、sendMail TypeError: undefined のメソッド「forEach」を呼び出せません。(行 73、ファイル「doPost」) formSubmit 3、doGet TypeError: undefined からプロパティ「row」を読み取れません。(行 4、ファイル「doGet」) formSubmit 4、headerKeys TypeError: オブジェクト [object Object] で関数 getRange が見つかりません。(行 17、ファイル「getUser」) formSubmit 5、rowToHash TypeError: オブジェクト [object Object] で関数 forEach が見つかりません。(行 22、ファイル「getUser」) formSubmit

該当のソースコード

googleappscript

1function getUserBy(key, value){ 2 var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 3 var sh = spreadsheet.getSheetByName('users'); 4 var values = sh.getDataRange().getValues(); 5 var keys = headerKeys(sh); 6 7 for (var i = 0; i < values.length; i++) { 8 var row = values[i]; 9 row = rowToHash(row, keys); 10 if (row[key] == value) { 11 return row; 12 } 13 } 14} 15// ヘッダ行を取得 16function headerKeys(sh) { 17 return sh.getRange(1,1,1, sh.getLastColumn()).getValues()[0]; 18} 19//行の情報をオブジェクトに変換 20function rowToHash(array, keys) { 21 var hash = {}; 22 array.forEach(function(value, i) { 23 hash[keys[i]] = value; 24 }) 25 return hash; 26 console.log(e); 27}

googleappscript

1var URL = "https://script.google.com/a/ウェブアプリとして公開したこのソースのURL/exec"; 2var sheetName = "answers"; 3 4function sendFormMail(e){ 5 6 // 追加行 7 var row = e.range.getRow(); 8 var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 9 var sheet = spreadsheet.getSheetByName(sheetName); 10 11 var name = e.namedValues["氏名"]; 12 var user = getUserBy("name", name); 13 14 // 承認者 15 var authorizer= getUserBy("id", user['authorizer_id']); 16 var address = authorizer['mail']; 17 18 var cols = ["タイムスタンプ","氏名","申請日","休暇取得開始日","休暇取得終了日","休暇種類","理由/備考"]; 19 var body=""; 20 cols.forEach(function(col){ 21 body += col; 22 body += ":" 23 body += e.namedValues[col]; 24 body += "\n"; 25 }); 26 27 28 body += "url:" 29 body += URL; 30 body += "?row=" + row; 31 body += "&name=" + encodeURI(authorizer['name']); 32 33 MailApp.sendEmail(address,"休暇申請",body); 34 console.log(e); 35}

googleappscript

1// 承認ページ表示時 2function doGet(e) { 3 //必要な値を画面に持たせておく 4 var row = e.parameter.row; 5 var name = e.parameter.name; 6 var html = HtmlService.createTemplateFromFile("shonin"); 7 html.row = row; 8 html.name = name; 9 html.url = URL; 10 html.method = "get"; 11 return html.evaluate(); 12 console.log(e); 13}

googleappscript

1function doPost(e) { 2 3 var shonin = e.parameter.shonin; 4 var row = e.parameter.row; 5 var name = e.parameter.name; 6 7 // シートに承認を記入 8 var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 9 var sheet = spreadsheet.getSheetByName(sheetName); 10 var values = sheet.getDataRange().getValues(); 11 12 var rowData = values[row-1]; 13 var idx = rowData.length; 14 15 var status = ""; 16 var timestamp = Utilities.formatDate( new Date(), 'Asia/Tokyo', 'yyyy/MM/dd hh:mm:ss'); 17 18 var cur = -1; 19 rowData.some(function(col,i){ 20 if (!col){//空の列を取得 21 idx = i; 22 return true; 23 } 24 }); 25 idx++; 26 27 if (shonin == 1) { 28 status = "承認"; 29 } else { 30 status = "却下"; 31 } 32 33 sheet.getRange(1, idx).setValue("状態"); 34 sheet.getRange(row, idx).setValue(status); 35 idx++; 36 37 sheet.getRange(1, idx).setValue("承認者"); 38 sheet.getRange(row, idx).setValue(name); 39 idx++; 40 41 sheet.getRange(1, idx).setValue("処理日次"); 42 sheet.getRange(row, idx).setValue(timestamp); 43 44 // 承認者をメールに記載するため再取得 45 values = sheet.getDataRange().getValues(); 46 47 if (shonin == 1) { 48 49 // 次の承認者をさがす 50 var user = getUserBy("name", name); 51 Logger.log(user); 52 53 var authorizer_id = user['authorizer_id']; 54 55 if (authorizer_id) {//上位承認者がいる場合 56 // 次の承認者にメール送信 57 var authorizer = getUserBy("id", authorizer_id); 58     sendMail(values, row, authorizer, true); 59 } 60 } else { 61 // 申請者にメール送信 62 var name = sheet.getRange(row, 2).getValue(); 63 var user = getUserBy("name", name); 64 sendMail(values, row, user, false); 65 } 66 var html = HtmlService.createTemplateFromFile("complete"); 67 return html.evaluate(); 68} 69 70function sendMail(values, row, user, approved){ 71 var rowData = values[row-1]; 72 var body=""; 73 rowData.forEach(function(col,idx){ 74 if (!col) return true; 75 var key = values[0][idx]; 76 body += key; 77 body += ":"; 78 if (['申請日','休暇取得開始日','休暇取得終了日'].indexOf(key) > -1) { 79 body += Utilities.formatDate( col, 'Asia/Tokyo', 'yyyy年M月d日'); 80 } else if (['処理日時'].indexOf(key) > -1) { 81 body += Utilities.formatDate( col, 'Asia/Tokyo', 'yyyy年MM月dd日 hh:mm:ss'); 82 } else { 83 body += col; 84 } 85 body += "\n"; 86 }); 87 88 body += "url:" 89 body += URL; 90 body += "?row=" + row; 91 body += "&name=" + encodeURI(user['name']); 92 93 var address = user['mail']; 94 var title = approved ? "休暇申請" : "休暇申請が却下されました"; 95 MailApp.sendEmail(address, title, body); 96 console.log(e); 97}

html

1<!DOCTYPE html> 2<html> 3 <head> 4 <base target="_top"> 5 <style> 6 table, td, th { 7 border-collapse: collapse; 8 padding: 0px; 9 10 border: 1px black solid; 11 } 12 td { 13 margin: 5px; 14 } 15 </style> 16 </head> 17 <body> 18 <h1>休暇申請承認</h1> 19 <? var html = ''; ?> 20 <? var json = getRowData(row); ?> 21 <table> 22 <? for(key in json){ ?> 23 <? if (!json[key]) break; ?> 24 <tr> 25 <td><?= key ?></td> 26 <? if (['申請日','休暇取得開始日','休暇取得終了日'].indexOf(key) > -1) { ?> 27 <td><?= Utilities.formatDate( json[key], 'Asia/Tokyo', 'yyyy年M月d日'); ?></td> 28 <? } else { ?> 29 <td><?= json[key] ?></td> 30 <? } ?> 31 </tr> 32 <? } ?> 33 </table> 34 <form action="<?= url ?>" method="post"> 35 <input type="radio" name="shonin" value="1" checked="checked">承認 36 <input type="radio" name="shonin" value="">却下 37 <input type="hidden" name="row" value="<?= row ?>"> 38 <input type="hidden" name="name" value="<?= name ?>"> 39 <input type="submit" value="送信"> 40 </form> 41 </body> 42</html>

html

1<!DOCTYPE html> 2<html> 3 <head> 4 <base target="_top"> 5 </head> 6 <body> 7 処理が完了しました 8 </body> 9</html>

試したこと

APIライブラリの追加(スクリプトエディタ、クラウドプラットフォーム両方)

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

まだ業界に入って2ヶ月くらいで、解説サイトなどの文言も把握できていなくて逐一検索したりしながら手探りで行っています。
googleフォームで入力した情報をスプレッドシートへ保存。
(スプレッドシートにはデータ保存のanswersシートと、従業員情報のusersシートが2枚あります。)usersの情報を元に承認権限のあるもの(authorizer_id)にメールを送ってそのメールを開くと承認画面、と動かしたいのですが上記エラーで承認画面が開けません。

https://qiita.com/kwgch/items/e2f666806503af4bb695
https://gist.github.com/kwgch/942595bca5c7668fe3b97c86eed171d9

こちらを拝見して実装したので、コードは誤りはないと思うのですがなぜエラーが出るのか全く分かりません。お力添えいただけたら嬉しいです。なにとぞよろしくお願いいたします。

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

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

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

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

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

papinianus

2018/09/28 09:12

エラーが出ているのは、パラメータが正常に指定されていないからです((e)が渡されていない)。どのように実行したときに、どのエラーがでるか、操作とエラーを対応付けてください。また処理の流れをかいてください。多分sendformmailがきっかけじゃないかと思うのですが、urlは正常に作れていますか?webアプリケーションは最新バージョンに更新しなおしていますか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

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

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

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問