
Google Apps Script (GAS) で業務の自動化やデータ処理を実装していると、誰もが一度はぶつかる巨大な壁。
それが「1日の実行上限(Quotas)」です。

1日の送信制限に引っかかって止まってしまった…



APIを叩きすぎて、翌日までスクリプトが実行不能になった…
この制限のせいで、



GASは便利だけど、大規模な処理には使えない…
と諦めてしまうのは、すごくもったいないです!
実は、ちょっと工夫すれば自動で処理を中断・再開させる仕組みを作ることができます。
この記事では、GASに標準搭載されているPropertiesServiceについて解説します。
このPropertiesServiceを使えば、「1日の上限」をスマートに突破する事が出来ます。
ぜひとも最後までご覧ください。
自動化出来る作業をまだ手作業でこなしていませんか?
私は、Googleが提供するプログラミングツールである、GAS(Google App Script)を活用して面倒なスプレッドシート業務を自動化や効率化するサービスを提供しています。
もし今の業務の中で
- 毎回の手作業に手間を感じる
- もっと業務を効率化したい
- ルーティン業務を自動化したい
このような不満を抱えてらっしゃるなら是非一度ご連絡ください。



「こんなことできる?」くらい軽めのご相談でも大歓迎です!
PropertiesServiceとは何か?
PropertiesServiceとは、簡単にいうと、スクリプト専用の、シンプルなデータベースのことです。
複雑なデータベースとは違い、Google側で管理されている場所に、テキストデータをキーと値のペアで手軽に保存と読込ができる機能です。
なぜ1日の上限を破る鍵になるのか?
GASがQuotas上限に達するとき、スクリプト内で実行された処理の記録(変数)は、全て消滅してしまいます。
例えば「メールを1000件送る」処理を実行したい時、仮に300の時点で強制終了したら、再度実行する時、また1件目のメールから実行されるということです。
これでは永久に処理が終わりません。
ここで PropertiesService の出番です。
PropertiesServiceの最大の特徴は、スクリプトの実行が終了してもデータが消えないことです。
Googleのサーバー上に、ロッカーのように安全に保管され続けます。
つまり、強制終了する直前に
「今、300件目まで終わったよ」
という情報(変数)をPropertiesServiceに書き込んでおけば、次に起動したスクリプトが「前回は300件目まで終わったから次は、301件目から始めよう」という仕組みを作る事が出来ます。
この、データを保存するという仕組みこそ、1日の上限を破る鍵です。
3種類のプロパティストア(データの保存場所)
PropertiesServiceには、データのプロパティストア(データの保存場所)が3つあります。
目的に応じて使い分けますが、今回は.getScriptProperties()をメインで使います。
| メソッド (種類) | 特徴 | こんな時に使う |
.getScriptProperties() | スクリプト全体でデータを共有する。 (今回の主役) | ・大量処理の中断・再開 ・APIキーの保存 ・チーム共有の設定値 |
.getUserProperties() | 実行する「人」ごとにデータを分ける。 | ・個人ごとのデータ管理 ・自分専用のメモ |
.getDocumentProperties() | ファイル(スプレッドシート等)に紐づく。 | ・シートごとでのデータ管理 |
getScriptProperties()の基本的な使い方
使い方は驚くほどシンプルで、たった3つのメソッドを覚えれば十分です。
データを保存する (setProperty)
'index' という名前(キー)で、'300' という値(※値は文字列として保存されます)を保存します。
PropertiesService.getScriptProperties().setProperty('index', '300');JavaScriptデータを取り出す (getProperty)
'index' という名前(キー)のデータをロッカーから取り出します。
// スクリプトプロパティから取り出す
const lastIndex = PropertiesService.getScriptProperties().getProperty('index');
// lastIndex の中身は '300' (文字列)
// ※もし 'index' が存在しない場合は null が返るJavaScript3. データを削除する (deleteProperty)
処理がすべて完了した際など、不要になったデータを削除します。
// スクリプトプロパティから 'index' を削除
PropertiesService.getScriptProperties().deleteProperty('index');JavaScriptこのように、たった3つのメソッドで「データの保存・読込・削除」が完結します。
難しいデータベースの知識は一切不要です
では次に、この仕組みを使って、具体的にどうやって「中断」と「再開」のロジックを設計するのかを見ていきましょう。
「1日の上限」を突破する「中断・再開ロジック」の作り方
「1日の上限」を突破するためのコードは、複雑に見えますが、4つのステップを踏むだけで大丈夫です。
ここでは、別記事(GAS利用枠(Quotas)の超過の解決法)で紹介した
「メール送信上限を検知して止まるコード」
を例にして、どうすれば自動再開できるコードに進化させるのかを解説します。
ベースとなるコードはこちらです。
function safeEmailSender() {
let emailList = [ /* ... 1600件のアドレス ... */ ];
// ★ Step 1, 2:スタート地点の確認と開始
for (let i = 0; i < emailList.length; i++) {
// ▼▼▼ ここからが防御コード(Step 3:監視) ▼▼▼
let quotaLeft = MailApp.getRemainingDailyQuota();
if (quotaLeft <= 10) {
// ★ Step 4:中断処理(記録して止める)
Logger.log("メール上限に達するため、" + i + "件目で処理を中断します。");
break;
}
// ▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲
GmailApp.sendEmail(emailList[i], "件名", "本文");
}
// ★ Step 4:完了処理(記録を消す)
}JavaScriptこの中の星マーク(★)がついている箇所に、PropertiesServiceのコードを追加していきます。
では、この★部分を具体的にどう書き換えるのか、4つのステップで見ていきましょう。
Step 1 & 2:スタート地点の確認と開始
いきなり 0(1件目)からスタートするのではなく、「前回どこで終わったか?」をPropertiesServiceに問い合わせます。
PropertiesServiceに問い合わせた後にループを回します。
// (PropertiesService)の準備
const props = PropertiesService.getScriptProperties();
// 「前回の続き」を取り出す(もしあれば)
const savedIndex = props.getProperty('EMAIL_INDEX');
// データがあれば数値に変換、なければ 0 (最初から) をセット
let startIndex = savedIndex ? parseInt(savedIndex) : 0;
// 初期値を 0 ではなく「startIndex」にしてループを回す
for (let i = startIndex; i < emailList.length; i++) { ... }JavaScriptStep 3:限界の監視
ここは元のコードの「防御コード」をそのまま活用します。
// ▼ Step 3:限界の監視
let quotaLeft = MailApp.getRemainingDailyQuota();
// もし残り枠が10通以下になったら...(Step 4へ)
if (quotaLeft <= 10) {
// ...
}JavaScript「残り枠が10通以下(quotaLeft <= 10)」になった時が、中断の合図です。
Step 4:分岐処理(記録と削除)
ここが最も重要です。
この分岐処理で「次回のために中断する」のか、「全て完了してリセットする」のかを決定します。
中断する場合の処理
まだ処理リストが残っているのに、Step 3の制限に引っかかった場合です。
「次は i 番目から」と記録して、スクリプトを強制終了(return)します。
// ▼ Step 4-A:中断処理
// 「次は i 番目から(まだ送ってない)」と記録する
props.setProperty('EMAIL_INDEX', i);
console.log(`⚠️ 上限間近。${i}件目で中断します。`);
return; // ★ break ではなく return で関数ごと終了させるJavaScript完了した場合の処理
ループを最後まで回りきった場合です。
次回の誤作動を防ぐため、記録を削除(deleteProperty)します。
// ループの外側(全件完了後)
// ▼ Step 4-B:完走処理
// 全件完了したら、必ず記録を削除する(重要!)
props.deleteProperty('EMAIL_INDEX');
console.log("🎉 全件送信完了!記録をリセットしました。");
}JavaScript【完成版】Quotas上限突破コード
これら4つのステップを全て合体させた完成コードがこちらです。
function safeEmailSender_Complete() {
// 1. 送信リスト(実際はスプレッドシート等から取得)
const emailList = [ /* ... 1600件のアドレス ... */ ];
// 2. ロッカー(PropertiesService)の準備
const props = PropertiesService.getScriptProperties();
// ▼ Step 1:スタート地点の確認
const savedIndex = props.getProperty('EMAIL_INDEX');
// 取り出したデータは文字列なので parseInt で数値化が必要
let startIndex = savedIndex ? parseInt(savedIndex) : 0;
console.log(`📩 ${startIndex}件目から処理を開始します...`);
// ▼ Step 2:変則的なループ開始
// 初期値を 0 ではなく「startIndex」にしてループを回す!
for (let i = startIndex; i < emailList.length; i++) {
// ▼ Step 3:限界の監視(残り枠チェック)
let quotaLeft = MailApp.getRemainingDailyQuota();
// もし残り枠が10通以下になったら...
if (quotaLeft <= 10) {
// ▼ Step 4-A:中断処理(記録して終わる)
props.setProperty('EMAIL_INDEX', i);
console.log(`⚠️ 上限間近(残り${quotaLeft}通)。${i}件目で中断します。`);
return; // 自主的に終了
}
// --- メイン処理 ---
try {
GmailApp.sendEmail(emailList[i], "件名", "本文");
Utilities.sleep(1000); // 連続送信エラー防止の待機
} catch(e) {
console.error(`❌ ${i}件目でエラー: ` + e);
}
}
// ▼ Step 4-B:完走処理(記録を消す)
// 全件完了したら、必ず記録を削除する。
props.deleteProperty('EMAIL_INDEX');
console.log("🎉 全件送信完了!記録をリセットしました。");
}JavaScriptこれをコピペして、emailList を書き換えるだけで、上限を気にせず大量のメール送信が可能になります。
このコードを使えば、1日100通の制限がある無料アカウントでも、数日かけて数千件のメールを安全に送り切ることができます。
まとめ
今回は、GASの大きな課題である「1日の上限」を、PropertiesService を使ってスマートに突破する方法を解説しました。
ポイントを振り返りましょう。
- PropertiesService
-
データを保存出来ます。
変数は消えても、ここに保存したデータは消えません。
- 4ステップの鉄則
-
状態の確認→開始→状態の監視→記録と削除
このサイクルを守れば、どんな処理でも安全に中断できます。
これで、あなたのスクリプトは、上限が来たら一旦休憩し、翌朝になったら続きから働き始めるというシステムに生まれ変わります。
「GASじゃ無理だ…」と諦めていた大量のデータ処理も、この仕組みを使えば実現可能です。
ぜひこの4ステップを取り入れて、GASの可能性を最大限に引き出してください!
私はGoogleが提供するプログラミングツールである、GAS(Google App Script)を活用して面倒なスプレッドシート業務を自動化や効率化するサービスを提供しています。
もし今の業務の中で
- 毎回の手作業に手間を感じる
- もっと業務を効率化したい
- ルーティン業務を自動化したい
このような不満を抱えてらっしゃるなら是非一度ご連絡ください。



「こんなことできる?」くらい軽めのご相談でも大歓迎です!