前提・実現したいこと
Webページ内のボタンを押下した際にJavaScriptの関数からGASの関数を呼び出し、
JavaScriptからGASへ、またGASからJavaScriptへ関数の引数をわたし、戻り値を受け取りたい。
表示するWebページはGoogle Apps Scriptダッシュボード内にあるIndex.htmlとし、
またサーバ側の処理は同ダッシュボード内のコード.gsに記入する。
発生している問題・エラーメッセージ
JavaScriptで受け取った戻り値が全てUndefinedとなり、値をうまく受け取れない。
該当のソースコード
javascript
1/////////////////////////////////////////////////////////////////////////////// 2///// 定数の宣言 ///// 3/////////////////////////////////////////////////////////////////////////////// 4// スプレッドシートのID(https://docs.google.com/d/[ID]/edit) 5var DATABASE_FILE_NAME 6 = '[ID]'; 7 8var DATABASE_SS_MAIN = 'DataBase'; 9var DATABASE_SS_USER_ID = 'UserID'; 10 11// GM登録時に読み込んだセルをDataBaseに反映させる順番 12var DATABASE_CELL = 13 [ 14 'A2', // 日付 15 'B2', // 開始時刻 16 'C2', // 終了時刻 17 'D2', // システム名 18 'E2', // シナリオ名 19 'F2', // 使用ツール 20 'J2', // 募集人数 21 'G2', // 概要 22 ]; 23 24// DataBase 状態 列名 25var DATABASE_STATE_CELL = 'I2'; 26var DATABASE_SENARIO_NAME_COL = 4; 27 28// DataBase 状態 "募集中" 29var ADD_STATE = "募集中"; 30 31// DataBase GM 列名 32var DATABASE_GM_NAME_CELL = 'H2'; 33var DATABASE_MAIL_COL = 0; 34var DATABASE_USERNAME_COL = 1; 35 36/////////////////////////////////////////////////////////////////////////////// 37///// 実際の処理 ///// 38/////////////////////////////////////////////////////////////////////////////// 39/// 40///* サーバ・クライアント接続 */// 41/// 42function doGet() { 43 return HtmlService.createHtmlOutputFromFile("index.html") 44 .setSandboxMode(HtmlService.SandboxMode.IFRAME); 45} 46 47// 48///* Googleアカウントが登録されているかの検査 */// 49// 50function AccountCheck() 51{ 52 // ActiveSheetの取得 53 var databaseFileSheet 54 = SpreadsheetApp.openById(DATABASE_FILE_NAME).getSheetByName(DATABASE_SS_USER_ID); 55 56 // アカウントIDの検査 57 var ret = findRow(databaseFileSheet, 58 Session.getActiveUser().getUserLoginId(), 59 DATABASE_MAIL_COL); 60 61 if(ret == 0) 62 { 63 // Browser.msgBox("ユーザー登録がされていません"); 64 return false; 65 } 66 else 67 { 68 return true; 69 } 70} 71 72function AddSession(cellVal){ 73 // 現在編集中のシートを取得 74 var activeFileSheet 75 = SpreadsheetApp.getActiveSpreadsheet(); 76 77 // データベースファイル 78 var databaseFileSheet 79 = SpreadsheetApp.openById(DATABASE_FILE_NAME).getSheetByName(DATABASE_SS_MAIN); 80 81 // 書き込み行のInsert 82 databaseFileSheet.insertRowBefore(2); 83 84 // 読み込んだ値の書き込み 85 for (i = 0; i < DATABASE_CELL.length; i++) 86 { 87 WriteCell(databaseFileSheet, 88 DATABASE_CELL[i], 89 cellVal[i]); 90 } 91 92 // 募集状況の追加 93 WriteCell(databaseFileSheet, 94 DATABASE_STATE_CELL, 95 ADD_STATE); 96 97 // GM名(GoogleID)の追加 98 WriteCell(databaseFileSheet, 99 DATABASE_GM_NAME_CELL, 100 Session.getActiveUser().getUserLoginId()); 101} 102 103// 104///* シナリオ名かぶり検査 */// 105// 106function SenarioNameCheck(addSenarioNameVal) 107{ 108 var databaseFileSheet 109 = SpreadsheetApp.openById(DATABASE_FILE_NAME).getSheetByName(DATABASE_SS_MAIN); 110 var ret = findRow( 111 databaseFileSheet, 112 addSenarioNameVal, 113 DATABASE_SENARIO_NAME_COL); 114 if(ret != 0) 115 { 116 //Browser.msgBox("シナリオ名が被っています、別の名前を入力してください。"); 117 return false; 118 } 119 return true; 120} 121 122// 123///* 指定セルの値の取得 */// 124// 125function ReadCell(sheet, range) { 126 // 指定セル範囲取得 127 var cellrange = sheet.getRange(range); 128 129 // 値返却 130 return cellrange.getValue(); 131} 132 133// 134///* 指定セルの値の変更 */// 135// 136function WriteCell(sheet, range, setVal) { 137 // 指定セル範囲取得 138 var cellrange = sheet.getRange(range); 139 140 // 値の変更 141 cellrange.setValue(setVal); 142} 143 144// 145///* 行検索処理 */// 146// 147function findRow(sheet,val,col){ 148 //受け取ったシートのデータを二次元配列に取得 149 var dat = sheet.getDataRange().getValues(); 150 151 //値の探索、値が見つかった場合行数を返却 152 for(var i=1;i<dat.length;i++){ 153 //Browser.msgBox(dat[i][col]); 154 if(dat[i][col] === val){ 155 return i+1; 156 } 157 } 158 159 // 値がない場合0を戻す。 160 return 0; 161}
HTML
1<!doctype html> 2<html lang="ja"> 3 <head> 4 <meta charset="utf-8"> 5 <title>Sandbox Agenda</title> 6 </head> 7 8 <script type="text/javascript"> 9 10 // ボタン押下時の処理 11 function btnAddSession_Click() { 12 13 // アカウントチェック 14 var ret = google.script.run.AccountCheck(); 15 // 値がundefinedで比較できていない。 16 if(ret == false) 17 { 18 document.getElementById("txtDebug").value = "登録されてないよ"; 19 return; 20 } 21 else 22 { 23 document.getElementById("txtDebug").value = "登録されてるよ"; 24 } 25 26 /// 入力コントロール名の配列定義 27 /// これHTMLと同じ値を書いてるけどまとめられない?冗長。 28 /// C言語の#defineのような… 29 var TXT_ID = 30 [ 31 "txtStartDate", //開始日時 32 "txtStartTime", //開始時刻 33 "txtEndTime", //終了時刻 34 "txtUseRuleSystem",//システム 35 "txtSenarioName", //シナリオ名 36 "txtUseTool", //使用ツール 37 "txtRecruitNum", //募集人数 38 "txtOverview" //概要 39 ]; 40 41 // 送信用配列の宣言 42 var arrSendData = Array(TXT_ID.length); 43 44 // コントロールの値を取得 45 var i = 0; 46 for(i = 0; i < TXT_ID.length;i++) 47 { 48 // ここセンスない。Valueがnullならと書き換えたい。 49 if(document.getElementById(TXT_ID[i]).value == "") 50 { 51 document.getElementById("txtDebug").value 52 = "値を入力してください"; 53 return; 54 } 55 } 56 57 // シナリオかぶり検査 58 ret = google.script.run.SenarioNameCheck(document.getElementById("txtSenarioName").value); 59 if(ret == false) 60 { 61 // かぶっているのに被っていないと表示される。識別できていない。 62 // 値がundefinedで比較できていない。 63 document.getElementById("txtDebug").value = "シナリオかぶり"; 64 return; 65 } 66 else 67 { 68 document.getElementById("txtDebug").value = "かぶってないよ"; 69 } 70 71 // GAS へデータを送信 72 // 送信データがすべてundefinedになって出力される。なぜ? 73 google.script.run.AddSession(arrSendData); 74 } 75 </script> 76 77 <body> 78 <form> 79 <p> 80 開始日時 81 <input type="text" value="" id="txtStartDate"><br> 82 開始時刻 83 <input type="text" value="" id="txtStartTime"><br> 84 終了時刻 85 <input type="text" value="" id="txtEndTime"><br> 86 システム 87 <input type="text" value="" id="txtUseRuleSystem"><br> 88 シナリオ名 89 <input type="text" value="" id="txtSenarioName"><br> 90 使用ツール 91 <input type="text" value="" id="txtUseTool"><br> 92 募集人数 93 <input type="text" value="" id="txtRecruitNum"><br> 94 概要 95 <input type="text" value="" id="txtOverview"><br> 96 <!-- 登録ボタン --> 97 <input type="button" value="登録" onclick="btnAddSession_Click();" id="btnAddSession"><br> 98 </p> 99 <p> 100 デバッグプリント 101 <input type="text" value="" id="txtDebug"><br> 102 </p> 103 </form> 104 </body> 105</html>
追加の質問
kisojinさんの回答を元にコードを修正しました。
無事GASからJavaScriptへ戻り値を返すことができました。
しかし
- GASからの戻り値がfalseだったらreturnするという処理を記述していたが、returnで処理を終了することができなくなった。
(現在はGlobal変数gs_ExitFlagでフラグを格納して、対応している)
2.JavaScriptからGASへ引数を渡すことができない。
(シナリオ名かぶり検査SenarioNameCheckと
スプレッドシートに配列の値を順番に書き込むAddSessionが機能していない。
AddSessionで書き込まれた値がUndefinedになっている。)
javascript
1 <script type="text/javascript"> 2 /// 入力コントロール名の配列定義 3 var TXT_ID = 4 [ 5 "txtStartDate", //開始日時 6 "txtStartTime", //開始時刻 7 "txtEndTime", //終了時刻 8 "txtUseRuleSystem",//システム 9 "txtSenarioName", //シナリオ名 10 "txtUseTool", //使用ツール 11 "txtRecruitNum", //募集人数 12 "txtOverview" //概要 13 ]; 14 15 // エラーコード 16 var ERR_CODE = 17 { 18 CONTROL_EMPTY : 1, 19 NO_GOOGLE_ID : 2, 20 NOT_UNIQUE_SESSION : 3, 21 }; 22 23 // エラーメッセージ 24 var ERROR_MESSAGE = 25 [ 26 "値を入力してください", 27 "登録されてないよ", 28 "シナリオかぶり" 29 ]; 30 31 // グローバル変数 32 var gs_ExitFlag = 0; 33 34 35 // GAS呼び出し後の処理 36 // アカウントチェック呼び出し 37 function CallGas_AccountCheck(ret) 38 { 39 if(ret == false) 40 { 41 OutputErrorMessage(ERR_CODE.NO_GOOGLE_ID); 42 } 43 } 44 45 // シナリオ名かぶり検査 46 function CallGas_SenarioNameCheck(ret) 47 { 48 if(ret == false) 49 { 50 OutputErrorMessage(ERR_CODE.NOT_UNIQUE_SESSION); 51 } 52 } 53 54 // JavaScript内サブルーチン 55 // HTMLのコントロールの値を配列に格納 56 function GetAllControlValue(TXT_ID) 57 { 58 var i = 0; 59 for(i = 0; i < TXT_ID.length;i++) 60 { 61 // ここセンスない。Valueがnullならと書き換えたい。 62 if(document.getElementById(TXT_ID[i]).value == "") 63 { 64 OutputErrorMessage(ERR_CODE.CONTROL_EMPTY); 65 } 66 } 67 } 68 // 終了フラグをOnにして、エラーメッセージを出力 69 function OutputErrorMessage(MessageID) 70 { 71 if(gs_ExitFlag == 0) 72 { 73 document.getElementById("txtDebug").value 74 = ERROR_MESSAGE[MessageID]; 75 gs_ExitFlag = 1; 76 } 77 } 78 79 80 // ボタン押下時の処理 81 function btnAddSession_Click() 82 { 83 // アカウントチェック 84 google.script.run 85 .withSuccessHandler(CallGas_AccountCheck) 86 .AccountCheck(); 87 88 // コントロールの値を取得 89 var arrSendData = Array(TXT_ID.length); 90 GetAllControlValue(TXT_ID); 91 92 // シナリオかぶり検査 93 google.script.run 94 .withSuccessHandler(CallGas_SenarioNameCheck) 95 .SenarioNameCheck(document.getElementById("txtSenarioName").value); 96 97 // GAS へデータを送信 98 // 送信データがすべてundefinedになって出力される。なぜ? 99 // 変数の型の問題?? 100 if(gs_ExitFlag == 0 ) 101 { 102 google.script.run.withSuccessHandler().AddSession(arrSendData); 103 } 104 } 105 </script>
回答2件
あなたの回答
tips
プレビュー