ご訪問ありがとうございます。
Googleシートマスターのひろしです。
前回
今回は、とっても価値の高い方法をお伝えします。
これを知ることであなたは、
- GASで処理をスピードアップする方法がわかります。
- タイムアウトする際の基本的な対処方法がわかります。
なので、サクッとマスターして
と答えてあげてください。
ご質問
いただいたご質問です。
私の動画の通りやったらタイムアウトが発生したとのこと。
では、改善策を考えてみましょう。
動画はこちら
シートはこちら
*クリックすることでシートが開きます。(コピーしてお使いください)
ポイント
まず、GASには、サーバ側で実行されます。
その際に、スプレッドシートの表示を伴う関数の場合、毎回
パソコンとサーバとの通信が発生するので遅くなってしまいます。
しかも、GASには6分でタイムアウトというルールがあるのです。
今回の場合、以下のように
a.行をチャックするたびに通信が発生
b.行を削除するたびに通信が発生
しかも行を削除する際は、再描画が必要となるのでかなり負荷がかかります。
なので、これらをサーバ側で行えば、速度は改善するはずです。
スクリプト
案1。
1行ずつパソコンからデータを取得するのではなく、D列のデータを
一気に取得してやってみました。
一応、1シート2分以内なので、3シートでもなんとかいけます。
とはいえ、一応トリガーを使ってやってみました。
トリガーを使う
以下は、proA()を最初に起動します。
①proA()
②「プロジェクトA」シートに対する処理
③1分後にproB()を実行するようにトリガーを設定
④proB()
⑤「プロジェクトB」シートに対する処理
⑥1分後にproC()を実行するようにトリガーを設定
⑦「プロジェクトC」シートに対する処理
となります。
function setTrigger(function_name) {
let triggers = ScriptApp.getScriptTriggers()
for (let trigger of triggers) {
if (trigger.getHandlerFunction() == function_name) {
ScriptApp.deleteTrigger(trigger)
}
}
// 1分後にトリガーをセット(1分 = 60秒 = 1秒*60 = 1000ミリ秒 * 60)
ScriptApp.newTrigger(function_name).timeBased().after(1000 * 60).create();
}
function proA() {
deletecompData('プロジェクトA')
setTrigger('proB')
}
function proB() {
deletecompData('プロジェクトB')
setTrigger('proC')
}
function proC() {
deletecompData('プロジェクトC')
// setTrigger('proB')
}
function deletecompData(shname) {
// const SH_NAME = ['プロジェクトA', 'プロジェクトB', 'プロジェクトC']
// SH_NAME.forEach(shname => {
// const shname = 'プロジェクトA のコピー'
console.log(shname)
const sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(shname)
let buffs = sh.getRange("D4:D100").getValues()
for (let i = buffs.length - 1; i >= 0; i--) {
// console.log(buffs[i][0],"行番号 ",i+4)
if (buffs[i][0] == "完了") {
console.log("行番号 ", i + 4)
sh.deleteRow(i + 4) //行の削除
}
}
// })
}
シートまるまるコピペ
案2.
今度は、一気にすべて読み込んでやってみます。
こんなイメージです。
/**
* シートのコピーと行の削除
* 1.シートをコピーし
* 2.データの読み込み
* 3.ステータスが完了の行をバッファに入れる
* 4.コピーしたシートの不要部分を削除
* 5.バッファをシートに反映させる
*/
function sheetCopyDelline() {
const ss = SpreadsheetApp.getActiveSpreadsheet()
const ssh = ss.getSheetByName('プロジェクトA')
//1.コピー対象シートを同一のスプレッドシートにコピー
let dsh = ssh.copyTo(ss);
console.log(dsh.getSheetName())
//2.チェックする範囲をすべて読み込む
let buffs = ssh.getRange("A4:AI1003").getValues()
// let buffs = ssh.getRange(4,1,ssh.getLastRow(),"A4:AI1000").getValues()
let destbuffs = ssh.getRange("A4:AI4").getValues() //ダミーで1行読み込む
let delrows = 0 //削除する行数
//3.完了以外のデータをバッファに格納する
buffs.forEach(buff => {
if (buff[3] == '完了') {
delrows++
}
else {
destbuffs.push(buff)
}
})
console.log("delrows => ", delrows, " 完了 => ", destbuffs.length)
destbuffs.shift() //ダミーを削除する
//4.コピー先シートの不要な行を削除する
dsh.deleteRows(1003 - delrows + 1, delrows)
//5.完了以外のデータ(destbuffs)をシートに反映させる
dsh.getRange(4, 1, destbuffs.length, destbuffs[0].length).setValues(destbuffs)
}
あ、よく考えたらシートをコピペする必要はないですね。
動画では、コピペしてやっていますが、うまくいくことが確認できれば、
上記のシートのコピー処理および以下の処理は不要ですね。
//シートのリネームと削除
function renamesheet() {
const ss = SpreadsheetApp.getActiveSpreadsheet()
const ssh = ss.getSheetByName('プロジェクトA')
//コピー対象シートを同一のスプレッドシートにコピー
let dsh = ssh.copyTo(ss);
dsh.setName("プロジェクトA ★")
//シートの削除
// ss.deleteSheet(ssh)
}
最後までご覧いただきありがとうございます。
つぎはこちら
コメント