実現したいこと
Google Apps Scriptにて
処理の途中でグローバル変数の値を変更することで、
関数の実行状況をサイドバーに表示したい
- グローバル変数を定義する
- サイドバーを表示する
- メインの関数の中で一定の処理ごとにグローバル変数に値を再代入する
- サイドバー(html)側から、受け渡し用の関数を呼びだして変更したグローバル変数の値を受け取る
- 実行ログとして表示させる
(特定のセルに値を保存して呼び出すことも考えましたが、
できるだけシートへの干渉は減らしたいと思っています)
発生している問題・エラーメッセージ
グローバル変数の値が更新されないため
以下のコードを実行すると
foo
foo
...
というような結果になってしまいます
(first
second
...
という結果が得たいです)
私がわからない部分は以下の2点です
- グローバル変数はただしく更新(再代入)できているのか
- getProgress内でreturnをする前に何らかの処理が必要なのか
つたない質問で申し訳ないのですが、教えていただけると幸いです。
どうぞよろしくお願いいたします。
該当のソースコード
コード.gs
js
1// グローバル変数を定義 2var progress = "foo"; 3 4// htmlから呼び出して最新のprogressを返したい 5function getProgress() { 6 return progress; 7} 8 9// スタート 10function start() { 11 // サイドバーを表示 12 const html = HtmlService.createHtmlOutputFromFile("サイドバー"); 13 SpreadsheetApp.getUi().showSidebar(html); 14 // 実行 15 myFunction(); 16} 17 18function myFunction(){ 19 progress = "first"; 20 // なにかの処理 21 Utilities.sleep(1000); 22 23 progress = "second"; 24 Utilities.sleep(1000); 25 26 progress = "third"; 27 Utilities.sleep(1000); 28 29 progress = "finish"; 30}
サイドバー.html
html
1<!DOCTYPE html> 2<html> 3 <head> 4 <base target="_top" /> 5 6 <script> 7 function run() { 8 // 0.5秒ごとにgetProgressを実行 9 id = setInterval(function() { 10 // getProgressの返り値をresponceで受けてサイドバーに表示 11 google.script.run.withSuccessHandler(function(response) { 12 // 最後まで到達したらタイマー処理を終了 13 if(response === "finish"){ 14 clearInterval(id); 15 document.getElementById("progress").insertAdjacentHTML('beforeend', `<div>終了しました<div>`); 16 } else { 17 document.getElementById("progress").insertAdjacentHTML('beforeend', `<div>${response}<div>`); 18 } 19 }).getProgress(); 20 }, 500); 21 } 22 </script> 23 </head> 24 25 <body onload="run()"> 26 <span id="progress"></span> 27 </body> 28</html>
試したこと
グローバル変数について調べてみたものの、
問題の原因がわからず、他の実装を考えてみました
1. 受け渡し用関数に直接引数を渡すように変更してみました
以下の結果になり、うまくいきませんでした
null
null
...
diff
1-function getProgress() { 2- return progress; 3-} 4+function getProgress(progress) { 5+ return progress; 6+} 7 8~~~ 9 10- progress = "first"; 11+ getProgress("first");
2. 次に、プロパティサービスを利用する方法を考えました
この方法では望むものに近い結果が得られましたが、値の反映まで多少のラグがあるような気がしました
diff
1-function getProgress() { 2- return progress; 3-} 4+function getProgress(progress) { 5+ var progress = PropertiesService.getScriptProperties().getProperty("progress"); 6+ return progress; 7+} 8 9~~~ 10 11- progress = "first"; 12+ PropertiesService.getScriptProperties().setProperty("progress","first");
補足情報(FW/ツールのバージョンなど)
参考にしたサイト
公式リファレンス
https://developers.google.com/apps-script/guides/html/reference/run?hl=ja
☆『GASとJSを使ってサイドバーで進行状況や途中結果を表示させる』
https://qiita.com/bonotake/items/f5f99e7b67460be356ac
『JavaScriptでのグローバル変数の宣言方法』
https://uxmilk.jp/11598
『プロパティサービスを使ってGASで秘密情報を管理する』
https://note.com/crefil/n/n2b68b3c4aa6b
