GAS、遅いんじゃあああ
概要
カスタムメニューからスクリプト実行できるようにしたのはいいが、遅いわ、中でも何してるかわからんわ、つらい、、、タイムアウトを待つだけの日々は嫌なんや。
進行状況を表示したいが、特にUI用意されてないやんけ。
出せるのは、、、サイドバーだけか。。。
サイドバーで表示するページを作る
まずはテンプレートのHTMLを適当に書き、適当に変数をセットして表示できるようにする
function showProgressSidebar(action, steps, finished){
var template = HtmlService.createTemplateFromFile('Progress')
template.title = "hogefuga"
template.action = action
template.steps = steps
template.finished = finished === undefined ? false : finished
SpreadsheetApp.getUi().showSidebar( template.evaluate() )
}
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<H1><?= title ?></H1>
<HR>
<H3><?= action ?></H3>
<br>
<br>
実行状況:<br>
<? for (var i = 0; i < steps.length; i++) { ?>
<? var step = steps[i]; ?>
<div clas="step <?= step.status ?>">
<? if( step.status == 'done' ){ ?>
<span class='mark done'>✓</span>
<? }else if( step.status == 'exec' ){ ?>
<span class='mark exec'>◇</span>
<? }else{ ?>
<span class='mark stay'>□</span>
<? } ?>
<span class="title"><?= step.title ?></span>
<span class="memo"><?= step.memo ?></span>
</div>
<? } ?>
<br>
<? if( finished ){ ?>
実行完了しました<br>
<br>
<center><input type='button' value='閉じる' onClick='google.script.host.close();'></center>
<? }else{ ?>
<marquee>実行中です</marquee>
<? } ?>
</body>
</html>
状況を保持して良きに計らうクラスを作る
上のをいちいち呼ぶの面倒臭いので、状態を保持しながらラップしてくれるクラスを作る。
// show step progress in sidebar
StepStatus = {
Done:'done', //did finish
Exec:'exec', //doing now
Stay:'stay', //yet stay
}
function StepProgress(title, memo, status){
'use strict';
this.title = title
this.memo = memo === undefined ? "" : memo
this.status = status === undefined ? 'stay' : status
}
function StepGroup(title, steps){
'use strict';
this.title = title
this.steps = steps
this.current = -1
this.times = []
}
StepGroup.prototype.show = function(){
showProgressSidebar(this.title, this.steps, this.isFinished())
}
StepGroup.prototype.start = function(){ this.step() }
StepGroup.prototype.end = function(){
if(this.current < this.steps.length){ this.step() }
}
StepGroup.prototype.update = function(memo){
this.steps[ this.current ].memo = memo
this.show()
}
StepGroup.prototype.isFinished = function(){
return this.current >= this.steps.length;
}
StepGroup.prototype.step = function (memo){
if(this.current>=0){
this.steps[this.current].status = StepStatus.Done
if(memo != undefined ){
this.steps[ this.current ].memo = memo
}
}
this.times.push( new Date().getTime() )
this.current += 1
if(this.current < this.steps.length){
this.steps[this.current].status = StepStatus.Exec
}
this.show()
}
使う
usage
function hogefuga( piyo, poyo){
var Steps = new StepGroup("この操作は["+piyo+"]", [
new StepProgress("約束された作業"),
new StepProgress("続いて行う作業"),
new StepProgress("後はおまけの作業"),
])
Steps.start()
//一つ目の作業
...
Steps.update("途中経過を報告")
...
Steps.update("まだまだやってる")
...
Steps.step("完了: "+(xxx)+"を処理")
//二つ目の作業
...
Steps.update("完了")
...
Steps.step("完了: "+(xxx)+"を処理")
//三つ目の作業
Steps.step("完了: "+(xxx)+"をおまけ")
}
まとめ
- GASの許されたインターフェイスはカスタムメニューとサイドバーのみ
- サイドバーに表示したページと相互通信するのクソ面倒いやんけ
- 画面書き捨てで出しときゃええやろ。非同期感あるし。
時間オーバーしないように最適化かけてくと、どうしても中で今何やってんのかわからなくなるんで
こういうことすると使ってる時のストレス減って良いですよね並感。