電話・店頭・HPという3つの入り口から入る注文を、Google Apps Script(GAS)で1枚のスプレッドシートに集約し、そこから「生産計画」を自動生成する仕組みを作りました。
結果、毎日やっていた注文の転記作業が約30分から約5分(およそ83%減)になり、予約の転記ミスは実質ゼロになりました。この記事では、その考え方とそのまま動かせるサンプルコードを公開します。
自動化する前は、毎日「二度手間」をやっていた
私は人口5万人未満の地方都市で、弁当・惣菜店を2店舗やっています(詳しくはこの人について)。注文は電話・店頭・ホームページの3か所から入ってきます。問題は、その3つがバラバラだったことです。
以前のやり方はこうでした。まず予約の抜け漏れがないかをノートで確認し、それを今度はバイトへの指示用にホワイトボードへ書き写す。プロフィール記事でも触れた、あの「書き写し」です。やること自体は単純ですが、毎日約30分かかり、しかも手で写す以上、必ず写し間違いのリスクがありました。
「予約が1件、ホワイトボードに転記されていなかった」——これは小さな店にとって、その日の信用に直結する事故です。だから、ここを真っ先に仕組みで潰すことにしました。
設計の考え方:入り口は分けても、ためる場所は1つにする
自動化でいちばん大事なのは、いきなりコードを書くことではなく「データの流れを1本にまとめる」設計です。私は次のように整理しました。
| 入り口 | 記録の方法 | ためる場所 |
|---|---|---|
| ホームページ | 注文時に自動でGASへ送信 | スプレッドシート 「注文ログ」に集約 |
| 電話・店頭 | スタッフが専用フォームに入力 |
入り口は3つでも、注文が最終的にたどり着く場所を「注文ログ」という1枚のシートに統一しました。こうすると、その後の集計は入り口の違いを気にせず1つのプログラムで処理できます。ここが自動化の肝です。
そして「注文ログ」から、受取日ごと・商品ごとの作る数量を自動で集計し、「生産計画」シートに毎回まっさらに書き出します。これで、ノートもホワイトボードへの書き写しも要らなくなりました。
【コード公開】注文を集計して生産計画を作る部分
ここが仕組みの中心です。「注文ログ」を読み込み、指定した日の商品別合計を出して「生産計画」シートに書き出す関数を、そのまま載せます。引数なしで呼ぶと「明日の分」を作ります。
// 注文ログを集計して「生産計画」シートを作り直す
function buildProductionPlan(targetDate) {
const ss = SpreadsheetApp.openById(SS_ID);
const orders = ss.getSheetByName(SHEET_ORDER).getDataRange().getValues().slice(1); // 見出し除く
const tz = Session.getScriptTimeZone();
// 対象日(指定がなければ「明日」)を yyyy-MM-dd に整形
const target = targetDate
|| Utilities.formatDate(new Date(Date.now() + 86400000), tz, 'yyyy-MM-dd');
// 受取日が対象日の注文だけ、商品ごとに数量を合算
const totals = {};
orders.forEach(function (row) {
const pickup = Utilities.formatDate(new Date(row[1]), tz, 'yyyy-MM-dd');
if (pickup !== target) return;
const item = row[2];
const qty = Number(row[3]) || 0;
totals[item] = (totals[item] || 0) + qty;
});
// 集計結果を「生産計画」シートへ出力(毎回まっさらに作り直す)
const plan = ss.getSheetByName(SHEET_PLAN);
plan.clearContents();
plan.getRange(1, 1, 1, 3).setValues([['受取日', '商品', '作る数']]);
const rows = Object.keys(totals).sort().map(function (item) {
return [target, item, totals[item]];
});
if (rows.length) plan.getRange(2, 1, rows.length, 3).setValues(rows);
return rows.length;
}
設定値(SS_ID=スプレッドシートID、シート名など)と、電話・店頭フォームの送信を受ける処理、HPからの自動受信処理を含む完全なサンプルコード一式は、この記事の末尾からダウンロードできます。
電話・店頭の注文は「フォーム送信時」に走らせる
電話と店頭の注文は、スタッフが入力する専用のGoogleフォームを用意し、送信されるたびに注文ログへ追記して生産計画を作り直します。フォーム送信をきっかけに動かすには、トリガーで onFormSubmit を指定します。
// 電話・店頭フォームが送信されたら走る
function onFormSubmit(e) {
const v = e.values; // [タイムスタンプ, 受取日, 商品, 数量, 名前]
appendOrder_({
pickupDate: v[1],
item: v[2],
qty: Number(v[3]),
source: '電話・店頭',
customer: v[4] || ''
});
buildProductionPlan(); // 入力のたびに生産計画を最新化
}
HP経由の注文は、ウェブアプリとして公開したGASのURLに注文データをPOSTする形(doPost)で、同じ「注文ログ」へ自動で入ります。3つの入り口が、最終的に同じ1枚へ流れ込む構造です。
結果:30分→5分、そして転記ミスがゼロに
仕組みが回り始めてから、変化は明確でした。
- 毎日の転記作業が約30分 → 約5分(残った5分は最終確認の時間)
- ノート・ホワイトボードへの手書き写しが消滅 → 予約の転記ミスが実質ゼロに
- 生産計画が誰でも同じ画面で見られるので、「私しか分からない」状態が解消した
削減できたのは1日25分ですが、これは年間に直すと約150時間です。それ以上に大きいのが、ミスが「気をつける」ではなく「構造的に起きない」状態になったこと。人が転記しなければ、転記ミスは原理的に発生しません。
つまずいた点・注意したこと
正直に書くと、すんなりとはいきませんでした。実際にハマったのは次の3点です。
- 商品名の表記ゆれ:「唐揚弁当」と「からあげ弁当」が別商品として集計される。入力をフォームの選択式にして根本から防ぎました。
- 権限の承認:初回実行時にGoogleの承認画面が出ます。これは正常な動作なので、内容を確認して許可します。
- 実行のタイミング:受注のたびに全件を再集計すると、注文が増えたとき重くなります。対象日を絞る(明日の分だけ作る)ことで軽くしています。
これから:発注・在庫・棚卸へ広げる(準備中)
注文の一元化ができると、その先が一気につながります。いま準備しているのは、この「注文ログ」を起点にした発注計画・在庫管理・棚卸の自動化です。必要な仕入れ量が注文から逆算でき、棚卸の手間も減らせる見込みです。動き出したら、また仕組み化カテゴリで報告します。
まとめ
注文管理の自動化は、派手なAIの話ではありません。バラバラの入り口を1枚に集約し、人の手による転記をなくす。たったこれだけで、毎日30分と、ミスの不安が同時に消えました。
まずは「自分の店で、毎日同じことを手で書き写している作業はどれか」を1つ見つけてみてください。そこが、最初に仕組み化すべき場所です。
よくある質問FAQ
プログラミングの知識がなくてもGASで注文管理を自動化できますか?
完全にゼロからは難しいですが、本記事のような動くサンプルコードを土台にすれば、設定値の書き換えと簡単な調整で動かせる範囲は広いです。最初は「コピペして、自分の環境名に直す」ところから始めるのが現実的です。
GAS(Google Apps Script)の利用に費用はかかりますか?
Googleアカウントがあれば基本的に無料で使えます。ただし1日あたりの実行時間やトリガー数に上限があるため、注文件数が非常に多い場合は処理の作り方を工夫する必要があります。
注文の入り口が電話・店頭・HPと複数でも、ひとつにまとめられますか?
まとめられます。コツは、入り口ごとに処理を分けず、すべての注文を1枚の「注文ログ」シートに集約することです。HPは自動POST、電話・店頭はスタッフ入力用のフォームと、入り口は違っても、ためる場所を1つにすれば集計は共通化できます。
自動化で本当にミスは減りますか?
減ります。私の店では、ノートからホワイトボードへ予約を手で書き写す工程をなくしたことで、写し間違いや抜け漏れが構造的に発生しなくなり、転記ミスが実質ゼロになりました。人が転記しなければ、転記ミスは起きないという考え方です。