在庫の減少に注文が来てから気づく運用だと、欠品や機会損失につながりやすくなります。
Google Apps Scriptで在庫数を毎日チェックし、設定した閾値を下回った商品だけを自動でメール通知する仕組みを、通知の重複を防ぐ設計まで整理しています。
完成イメージと仕組み
完成すると、在庫数を記録したスプレッドシートを毎朝スクリプトがチェックし、設定した閾値を下回った商品だけがメールで担当者へ届く形になります。
仕組みは単純で、シートの各行から品名と現在の在庫数、閾値を読み取り、在庫数が閾値以下になった行だけを通知対象として抽出する形です。
通知が終わった行には通知済みの印を付けるため、翌日以降スクリプトを再実行しても同じ商品が重複して通知されることはありません。
在庫が閾値を上回るまで回復すれば印は自動でリセットされるので、再び在庫が減ったときにはまた通知が届きます。
メール以外にチャットへ通知先を切り替えたい場合は、スプレッドシートの更新をSlackへ自動通知する仕組みと組み合わせる方法もあります。

手順
シートの準備からトリガー設定まで、4つのステップで完成します。
Step1. 在庫シートを準備する
新しいスプレッドシートを作成し、1行目に「品名」「現在庫数」「閾値」「通知済み」の見出しを入れます。
2行目以降に、管理したい商品を1件1行で入力し、現在庫数と閾値にはそれぞれ数値を入力してください。
続けてスプレッドシート上部のメニューから拡張機能を開き、Apps Scriptを選ぶとスクリプトエディタが立ち上がります。
Step2. コードを貼り付ける(コード全文)
スクリプトエディタに表示されているコードを全て消し、次のコードを貼り付けます。
function checkInventoryAndAlert() {
const sheetName = '在庫管理'; // ★ここを変える: 対象シート名
const notifyEmail = 'example@example.com'; // ★ここを変える: 通知先メールアドレス
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
if (!sheet) {
throw new Error(`シート「${sheetName}」が見つかりません`);
}
const lastRow = sheet.getLastRow();
if (lastRow < 2) {
return;
}
const data = sheet.getRange(2, 1, lastRow - 1, 4).getValues();
const alerts = [];
data.forEach((row, index) => {
const [itemName, currentStock, threshold, alerted] = row;
if (typeof currentStock !== 'number' || typeof threshold !== 'number') {
return;
}
const rowNumber = index + 2;
if (currentStock > threshold) {
if (alerted === '通知済み') {
sheet.getRange(rowNumber, 4).setValue('');
}
return;
}
if (alerted === '通知済み') {
return;
}
alerts.push(`${itemName}:残り${currentStock}(閾値${threshold})`);
sheet.getRange(rowNumber, 4).setValue('通知済み');
});
if (alerts.length === 0) {
return;
}
const subject = '在庫アラート:閾値を下回った商品があります';
const body = [
'以下の商品が設定した在庫数を下回りました。補充を確認してください。',
'',
...alerts,
].join('\n');
GmailApp.sendEmail(notifyEmail, subject, body);
} data.forEach の中で行ごとに在庫数と閾値を比較し、在庫数が閾値を上回っていれば通知済みの印を消して次回また通知できる状態に戻す処理です。
在庫数が閾値以下でまだ通知していない行だけをalerts配列にため、最後にまとめて1通のメールで送信します。
1件ずつ個別のメールを送らずまとめて送るのは、対象商品が多い日にメールが大量に届いて見落とされるのを防ぐためです。
Step3. 閾値を自分の業務に合わせる(書き換え表)
書き換える箇所は主にシートの閾値の値と、通知先のメールアドレスです。
| 設定したいこと | 変更する箇所 | 設定例 |
|---|---|---|
| 商品ごとに減り方が違う場合の閾値 | シートの閾値列 | 商品Aは10・商品Bは50 |
| 通知先を複数人にする | notifyEmailの値 | カンマ区切りで複数指定 |
| 単位を個数以外にする | 現在庫数・閾値の入力値 | ケース数・重量など数値であれば可 |
| 商品ごとに通知先を分ける | GmailApp.sendEmailの呼び出し箇所 | 行ごとに宛先列を追加して参照 |
閾値は全商品で同じ値にする必要はなく、回転が速い商品ほど高めの数値を設定すると欠品までの猶予を確保できます。
商品ごとに通知先を分けたい場合は、シートに担当者メール列を追加し、alertsにためず行ごとにGmailApp.sendEmailを呼び出す形へ書き換えれば対応できます。
Step4. 時間トリガーを設定する
スクリプトエディタの左側にある時計マークの「トリガー」を開き、右下の「トリガーを追加」から設定してください。
実行する関数にはcheckInventoryAndAlertを選び、イベントのソースは時間主導型、種類は日付ベースのタイマーを選んで、毎日の実行時刻を指定します。
保存すれば、指定した時刻に在庫チェックと通知が自動で繰り返される状態になります。
受信メールから在庫の入出庫を転記する運用を自動化したい場合は、期限管理の通知設計と合わせて検討すると仕組み全体の見通しが良くなるはずです。

通知が来すぎるときの調整
このスクリプトが通知を送りすぎないのは、閾値の比較と通知済み列の書き戻しが連動しているためです。
在庫数が閾値を上回った時点で通知済みの印を消すため、補充と減少を繰り返す商品でも、閾値を下回るたびに1回だけ通知されます。
逆に閾値ぎりぎりの数量で入出庫が頻発する商品があると、閾値をまたぐたびに通知が届いてしまい、担当者が慣れてメールを読み飛ばすようになりがちです。
その場合は閾値そのものを下げるより、閾値と別に「復帰ライン」を設ける方法が有効です。
たとえば閾値10で通知した商品は、在庫が15を超えるまで通知済みの印を戻さないようにします。
コードの上では、在庫が閾値を上回ったかを判定しているcurrentStock > thresholdはそのまま残し、その内側で印を消している処理に「在庫が15を超えているか」の条件を追加します。
こうすると通知の基準は閾値のままで、印のリセットだけが復帰ラインまで持ち越されるので、閾値と15の間で在庫が行き来しても再通知されません。
ちなみに、棚卸しのタイミングで在庫数を一括更新すると、更新直後の実行で複数商品が同時に閾値を下回り、まとめて通知が届くことがあります。
これは仕組みとしては正常な動作ですが、棚卸し直後だけトリガーを一時停止しておくと落ち着きます。
Google Apps Scriptでの在庫管理について相談してみませんか?
「閾値をどう設定すればちょうど良いか判断できない」「商品数が多くシート設計から見直したい」「社内にGoogle Apps Scriptを設計できる人材がいない」
少しでもお心当たりがあれば、お気軽にご相談ください。
現在、Google Apps Scriptを使った業務自動化のお悩みをお伺いする 無料の個別相談 を実施しています。
よくある質問
Q. 商品数が数百件あっても動きますか?
動きます。
getRangeで必要な範囲を1回にまとめて取得しているため、商品数が増えても読み取り回数は変わりません。
ただし通知対象が非常に多い日は本文が長くなるため、件数が多い場合は上位何件かに絞って通知する条件を追加すると読みやすくなります。
Q. 通知済みの印はいつリセットされますか?
在庫数が閾値を上回った時点で自動的にリセットされます。
手動でシートを操作する必要はなく、補充によって在庫数が回復すればスクリプトの次回実行時に印が消え、再度閾値を下回ったときにまた通知が届く仕組みです。
Q. メールではなくチャットに通知したい場合はどうすればよいですか?
GmailApp.sendEmailの部分をチャットツールへの送信処理に置き換える必要があります。
スプレッドシートの更新をチャットへ通知する仕組みを別記事で扱っているので、そちらの送信部分を参考に組み合わせると対応できます。
Q. トリガーの実行時刻はいつに設定すればよいですか?
発注や補充の判断ができる時間帯に設定するのが基本です。
始業前に在庫状況を確認して当日中に発注したい場合は、平日の朝7時から8時台に実行する運用が多く見られます。