Google Apps Script(GAS)を使っていると、ときどき 「DEADLINE_EXCEEDED」 というエラーが表示され、処理が途中で止まってしまうことがあります。このエラーは、GAS に設定されている「実行時間の上限」をスクリプトが超えてしまったときに出るものです。難しいエラーに見えますが、原因はシンプルで、対処法もわかりやすいので安心してください。
まず、GAS では実行時間が決まっています。たとえば、手動実行やトリガーで動かす処理は約6分、WebアプリやWebhook(doPost/doGet)は約30秒までとなっています。この時間内に処理が終わらない場合、GAS は自動的にスクリプトを止めてしまいます。
このエラーが起きる一番の理由は、「処理が重い」ことです。とくに多いのは、スプレッドシートを1行ずつ読み書きしているケースです。次のようなコードは、とても時間がかかってしまいます。
// 非効率な例:1行ずつ書き込む
for (let i = 1; i <= 1000; i++) {
sheet.getRange(i, 1).setValue("OK");
}
これを改善するには、「まとめて操作する」方法が効果的です。
// 効率の良い例:まとめて書き込む
const values = Array.from({length: 1000}, () => ["OK"]);
sheet.getRange(1, 1, 1000, 1).setValues(values);
このように処理をまとめるだけで、実行時間が大幅に短くなります。
また、大量のデータを扱うときには、いっぺんに処理しようとせず、「分割して処理する」方法もおすすめです。たとえば進捗を PropertiesService に保存しておき、次の実行時に続きから始めるやり方です。
function processInChunks() {
const prop = PropertiesService.getScriptProperties();
let start = Number(prop.getProperty("startRow") || 1);
const chunkSize = 200;
const sheet = SpreadsheetApp.getActiveSheet();
const lastRow = sheet.getLastRow();
for (let i = start; i < start + chunkSize && i <= lastRow; i++) {
// ここで必要な処理を行います
}
prop.setProperty("startRow", start + chunkSize);
if (start + chunkSize <= lastRow) {
console.log("次の回に続きます");
} else {
console.log("完了しました");
prop.deleteProperty("startRow");
}
}
このように「少しずつ処理する」ことで、時間制限を避けることができます。
外部API(UrlFetchApp)を連続で呼び出している場合も、時間オーバーの原因になります。その場合は、キャッシュを使ったり、呼び出し回数を減らしたりすると改善します。
まとめると、DEADLINE_EXCEEDED は“怖いエラー”ではなく、“改善のヒント”です。スプレッドシートやAPIを効率よく扱うようにするだけで、多くのケースで簡単に解消できます。もし今書いているコードで気になる部分があれば、貼っていただければ改善案を提案いたします。