GASでタイムアウトエラーを回避したい
Q&A
解決したいこと
タイムアウトエラーを回避したいです。
以下のコードを作成したのですが、正しく動かず難儀しております。
スプレッドシートにて、アイテム所持数シートと各キャラクターチェックシートのアイテム数を比較し、アイテムが足りていたら条件付き書式で#4285f4でセルに色を塗る。
その後GASで一行ずつ「データ入っている場所、色が塗ってない場所」を探し、あれば終わり
なければ(材料がすべて足りている状態だったら)制作可能の◯をつける。
連続処理時間の上限が5分半なので、5分経過した段階で一度処理を終了し続きから処理を再開するようにしたいです。
その、次の処理が始まらずに困っています。
発生している問題・エラー
出ているエラーメッセージを入力
エラーメッセージ等は出ておらず、処理時間の限界で
処理が途中で止まってしまう状態です。
該当するソースコード
function MaterialCheck() {
let startTime = new Date();
//各ページを取得
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheetS = ss.getSheetByName("アイテム所持数")
const sheetM = ss.getSheetByName("必要素材シート1")
const sheetK = ss.getSheetByName("必要素材シート2")
const sheetT = ss.getSheetByName("必要素材シート3")
let charaSheet = [sheetM,sheetT,sheetK]
//所持素材リストのどの行を使うか
let charaRows = [2,3,4]
let creatCheck = new Array()
let rowCheck = new Array()
let startPage = Number(PropertiesService.getScriptProperties().getProperty('nextr'));
let startRow = Number(PropertiesService.getScriptProperties().getProperty('nexti'));
if (!startRow) startRow = 4; // もしstartIndexがnullの場合は1を代入
if (!startPage) startPage = 0; // もしstartIndexがnullの場合は1を代入
for(let r = startPage; r <= 3; r++){//むくたいかきのページと行の切り替え
for(i = startRow; i <= charaSheet[r].getLastRow(); i++){
Logger.log(i)
Logger.log(r)
charaSheet[r].getRange(i,1).setBackground("#FFFFFF")
let currentTime = new Date(); // ②ループx周目時点の日時
let seconds = (currentTime - startTime)/1000; // 経過秒数を計算(①と②の差分)
if(charaSheet[r].getRange(i,1).getValue() != "⚫︎"){ //左に⚫︎が入ってる場合行をスルー
for(j = 3; j <= charaSheet[r].getLastColumn(); j++){
if(charaSheet[r].getRange(i,j).getValue() != "" && charaSheet[r].getRange(i,j).getBackground() != "#4285f4"){
creatCheck[i - 1] = ""
break
}else if(j >= charaSheet[r].getLastColumn()){
creatCheck[i - 1] = "◯"
}
}
}else{
creatCheck[i - 1] = "⚫︎"
}
if(seconds > 300){
// 次回のチェック対象
let nextPage = r;
let nextRow = i + 1;
if (nextRow > charaSheet[r].getLastRow()) {
nextPage++;
nextRow = 4;
}
// トリガーを設定
PropertiesService.getScriptProperties().setProperty('nextr', nextPage);
PropertiesService.getScriptProperties().setProperty('nexti', nextRow);
setTrigger();
// 300秒経過したらreturnして強制的に実行を中断する
return;
}
}
startRow = 4
}
// 全ての素材をチェック完了
Logger.log('全ての素材をチェック完了しました。');
}
function setTrigger() {
let triggers = ScriptApp.getProjectTriggers()
for(let trigger of triggers){
if(trigger.getHandlerFunction() == "MaterialCheck"){
ScriptApp.deleteTrigger(trigger);
}
}
// 1分後にトリガーをセット(1分 = 60秒 = 1秒*60 = 1000ミリ秒 * 60)
ScriptApp.newTrigger("MaterialCheck").timeBased().after(1000 * 60).create();
}
自分で試したこと
・バグがある?と見たので8ランタイムを無効にしてみた
・コードを書き直す必要が出てきたので、断念
・画面上部の実行ボタンではなく、スプレッドシートの図形にスクリプトをつけてそこから実行してみる