前提・実現したいこと
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="0">却下 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
こちらを拝見して実装したので、コードは誤りはないと思うのですがなぜエラーが出るのか全く分かりません。お力添えいただけたら嬉しいです。なにとぞよろしくお願いいたします。
あなたの回答
tips
プレビュー