お久しぶりです。久しぶりに記事を書きます。
実は最近、転職したので、これまで使っていないGoogleスプレッドシートやGoogleドライブを仕事で利用することになりました。
Excelも引き続き使うのですが、これまでExcel VBAで出来ていたことができなくなる可能性が高いので、GASを勉強し始めています。
※エンジニアではないので、間違っていること書いていたらご指摘ください。
VBAのときもだいたいそうだったのですが、GASを実行する際に、処理に時間がかかるものだと、現在正常に処理中なのか、そもそも処理自体が何かの間違いで開始していないのか結構不安になります。
そのため、私がGASを作成するときには、処理完了後に必ず処理完了メッセージを表示するようにしていました。
function example1() {
SpreadsheetApp.getUi().alert('処理が完了しました');
}
しかし、困ったことが起きる場合がありました。
ui.alertメソッドだとタイムアウトになることがある
Googleドライブ内にあるファイルのフォルダ階層やURLを書き出しするGASを実行したのですが、共有ドライブとかを指定すると、かなり時間がかかります。
(会社のアカウントなので、いわゆる壁は6分ではなく30分ですが…。)
ずっと実行画面を見続けて待っている訳にもいかないので、実行中は他の作業をしたりMTGに出席したりします。
そうこうしている間に処理は完了するのですが、処理結果はタイムアウトになっていたんですよね。
出力されたものを見るに、ファイル一覧を網羅的に出力できていそうなのですが、原因は、getUi().alertはユーザーが押すまで処理を止める同期操作であるため、OKを押さず放置したことでGASは動作し続け、タイムアウトしてしまったようでした。
したがって、処理完了メッセージを出力する他の方法を探しました。
toastメソッドだと表示時間が短すぎるが、負の値を指定で回避可能
そこで見つけたのが、toastメソッドです。
function example2() {
SpreadsheetApp.getActiveSpreadsheet().toast("処理が完了しました");
}
toastメソッドは、非同期通知なのでタイムアウトのリスクは避けられます。
でも、toastメソッドは既定だと表示時間が5秒と短すぎなんですよね。
タイム時間は、下記のように引数でtoast(msg, title, timeoutSeconds)のように指定可能です。
秒数指定だとずっと表示することは難しいように見えますが、一応指定はできましてユーザーが閉じるボタンを選択するまで、ずっと表示させることができるようです。
function example3() {
SpreadsheetApp.getActiveSpreadsheet().toast("処理が完了しました","処理完了通知",-1);
}
toastメソッド以外の方法も
実は、toastメソッドでずっとメッセージを表示させる方法を勘違いしていて別の解決策もわかりました。
(最初に『0未満の数値を指定した場合はユーザが閉じるまで表示されます。』という解説を読み違えて、timeoutSecondsを0.1とかで指定して、『すぐ消えちゃうじゃん…』とか思ってたんですよね…恥)
面倒なので、別にこの方法を採用しなくてよいと思いますが、HTMLを利用すればtoastメソッドと同様に、タイムアウトを避けられるようです。
function showDoneMessage() {
const html = HtmlService
.createHtmlOutputFromFile("doneMessage")
.setWidth(300)
.setHeight(200);
SpreadsheetApp.getUi().showModalDialog(html, "処理完了");
}
<!DOCTYPE html>
<html>
<body style="font-family: sans-serif; padding: 10px;">
<h3>処理が完了しました</h3>
<p>OKボタンを押して閉じてください。</p>
<button onclick="google.script.host.close();">
OK
</button>
</body>
</html>
実際には下記のようなHTMLファイルを保存します。
ただ結構、面倒なので、今後はtoastメソッドで統一すると思います。
