1. 「欠品が月5件、その度に急ぎ発注していた」という現実
私が担当していた在庫管理業務では、300種類のSKUをExcelで管理していました。在庫数は手入力で更新し、発注点の確認も目視で行っていたため、月に5〜6件の欠品が発生していました。欠品に気づくのはたいてい顧客から「在庫ありますか?」と問い合わせがあったときで、そのたびに急ぎの発注対応と顧客への謝罪が必要でした。
「自動でアラートが来れば欠品を事前に防げるのに」と思い、Claude Codeに相談しました。Claude Codeはチャット画面で日本語の要件を伝えるだけでPythonコードを生成してくれるAIです。Pythonの知識がなくても、業務の内容さえ説明できれば、Claude Codeが最適なコードを書いてくれます。
| 課題 | 従来(手作業) | Claude Code自動化後 |
|---|---|---|
| 在庫数確認 | 毎日目視確認(約30分) | Claude Codeが自動監視(0分) |
| 発注点チェック | 手動でフィルター・確認(見落とし多数) | Claude Code生成コードが自動抽出 |
| 欠品アラート | 顧客からの問い合わせで初めて気づく | 発注点割れを即時メール通知 |
| 発注書作成 | 手動でExcelに入力(約1時間) | Claude Code生成コードが自動作成 |
| 在庫推移分析 | ほぼ未実施 | Claude Codeが在庫回転率・トレンドを自動計算 |
2. Claude Codeへの最初のプロンプト ——「発注点を下回ったら教えてほしい」
まずClaude Codeのチャット画面を開き、現在のExcelの構造と困っていることを伝えました。Claude Codeは技術的な知識がなくても、業務の内容を日本語で説明するだけでコードを生成してくれます。
プロンプト例 1
ファイル名は「inventory.xlsx」で、以下の列があります。
– SKUコード
– 商品名
– 現在庫数
– 発注点(この数を下回ったら発注が必要)
– 発注リードタイム(日数)
– 担当仕入れ先
毎日このExcelを読み込んで、「現在庫数」が「発注点」を下回っているSKUを抽出し、
担当者(私)のメールアドレスにアラートメールを自動送信するPythonスクリプトを作ってください。
メールの件名は「【在庫アラート】発注が必要な商品があります」にしてください。
本文には発注が必要なSKUの一覧(SKUコード・商品名・現在庫数・発注点・仕入れ先)を表形式で含めてください。
Claude Codeは数秒で要件を理解し、Pythonコードを生成してくれました。Claude Codeが生成したコードには、Excelの読み込み・発注点チェック・メール本文の表形式フォーマット・SMTP送信まで全ての要素が含まれていました。
「指定の要件を満たすスクリプトを生成しました。pandasでExcelを読み込み、現在庫数 < 発注点の条件でフィルタリングします。アラートメールはsmtplibで送信します。実行前にGmailアプリパスワードを環境変数に設定してください。」
3. Claude Codeが生成した在庫アラートスクリプト
以下がClaude Codeが生成した完全なPythonスクリプトです。Claude Codeが生成するコードは、Pythonを知らない人でもロジックが読み取れるよう、丁寧なコメント付きで出力されます。
# Claude Codeが生成したコード: Excel在庫監視 → アラートメール自動送信 import os import smtplib import pandas as pd from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from datetime import datetime # ── 設定 ───────────────────────────────────────────── GMAIL_USER = os.environ["GMAIL_USER"] GMAIL_PASS = os.environ["GMAIL_APP_PASS"] ALERT_EMAIL = os.environ["ALERT_EMAIL"] # アラート送信先 EXCEL_PATH = "inventory.xlsx" def load_inventory() -> pd.DataFrame: """Excelから在庫データを読み込む""" df = pd.read_excel(EXCEL_PATH) print(f"在庫データ読み込み: {len(df)}件のSKU") return df def get_alert_items(df: pd.DataFrame) -> pd.DataFrame: """発注点を下回っているSKUを抽出する""" alert_df = df[df["現在庫数"] < df["発注点"]].copy() # 不足数と発注推奨量を計算 alert_df["不足数"] = alert_df["発注点"] - alert_df["現在庫数"] alert_df["緊急度"] = alert_df["現在庫数"].apply( lambda x: "★★★ 緊急" if x == 0 else ("★★ 警戒" if x < 5 else "★ 注意") ) return alert_df.sort_values("現在庫数") # 在庫が少ない順に並べる def build_alert_body(alert_df: pd.DataFrame) -> str: """アラートメールの本文を生成する""" now = datetime.now().strftime("%Y年%m月%d日 %H:%M") lines = [ f"在庫アラートレポート ({now})", f"発注が必要なSKU: {len(alert_df)}件\n", f"{'緊急度':<10}{'SKUコード':<15}{'商品名':<30}{'現在庫':<8}{'発注点':<8}{'不足数':<8}仕入れ先", "-" * 90, ] for _, row in alert_df.iterrows(): lines.append( f"{row['緊急度']:<10}{str(row['SKUコード']):<15}{str(row['商品名']):<30}" f"{int(row['現在庫数']):<8}{int(row['発注点']):<8}{int(row['不足数']):<8}{row['担当仕入れ先']}" ) lines.append("\n--- このメールはClaude Codeが生成した自動化スクリプトから送信されています ---") return "\n".join(lines) def send_alert(body: str, item_count: int) -> None: """アラートメールを送信する""" msg = MIMEMultipart() msg["From"] = GMAIL_USER msg["To"] = ALERT_EMAIL msg["Subject"] = f"【在庫アラート】発注が必要な商品があります({item_count}件)" msg.attach(MIMEText(body, "plain", "utf-8")) with smtplib.SMTP_SSL("smtp.gmail.com", 465) as server: server.login(GMAIL_USER, GMAIL_PASS) server.send_message(msg) print(f"アラートメールを送信しました ({item_count}件のSKU)") def main(): df = load_inventory() alert_df = get_alert_items(df) if alert_df.empty: print("発注が必要なSKUはありません。全在庫正常です。") return body = build_alert_body(alert_df) send_alert(body, len(alert_df)) if __name__ == "__main__": main()
実際に実行したときのターミナル出力です。
在庫データ読み込み: 300件のSKU アラートメールを送信しました (7件のSKU) 緊急度 SKUコード 商品名 現在庫 発注点 不足数 仕入れ先 ------------------------------------------------------------------------------------------ ★★★ 緊急 SKU-0042 ネジM4×10(100本入り) 0 50 50 株式会社A商会 ★★★ 緊急 SKU-0103 防錆スプレー 420ml 0 20 20 B工業 ★★ 警戒 SKU-0018 ボルトM6×20(50本入り) 3 30 27 株式会社A商会 ★ 注意 SKU-0201 グリース 500g 8 20 12 C潤滑材
Claude Codeを使った結果
- コード生成にかかった時間: 約3分

- 欠品件数: 月5〜6件 → 月0〜1件に激減
- 毎日の目視確認作業30分が: 完全ゼロに
- 緊急度別の優先順位付けも: Claude Codeが自動設計
4. 「発注書も自動で作ってほしい」とClaude Codeに追加依頼
アラートメールで発注が必要なSKUがわかるようになりましたが、次のステップとして発注書Excelも自動で作ってほしいとClaude Codeに依頼しました。Claude Codeは前のコードの文脈を理解した上で、発注書生成機能を追加してくれました。
プロンプト例 2
アラート対象のSKUについて、仕入れ先ごとに発注書Excelを自動生成してほしいです。
発注書のフォーマット:
– ヘッダー:発注書番号(自動採番)・発注日・仕入れ先名
– 明細行:SKUコード・商品名・発注数量(発注点の2倍)・単価(Excelの「単価」列から)
– フッター:合計金額
発注書ファイル名は「発注書_仕入れ先名_YYYYMMDD.xlsx」にしてください。
# Claude Codeが追加生成した発注書自動作成機能 import openpyxl from openpyxl.styles import PatternFill, Font, Alignment, Border, Side from openpyxl.utils import get_column_letter from datetime import datetime def generate_purchase_orders(alert_df: pd.DataFrame) -> list: """仕入れ先ごとに発注書Excelを生成する""" today = datetime.now() generated_files = [] order_number_base = int(today.strftime("%Y%m%d")) # 仕入れ先ごとにグループ化 for i, (supplier, group) in enumerate(alert_df.groupby("担当仕入れ先"), start=1): order_no = f"PO-{order_number_base}-{i:03d}" filename = f"発注書_{supplier}_{today.strftime('%Y%m%d')}.xlsx" wb = openpyxl.Workbook() ws = wb.active ws.title = "発注書" # ── ヘッダー部分 ────────────────────────── header_fill = PatternFill("solid", fgColor="107C41") ws["A1"] = "発注書" ws["A1"].font = Font(bold=True, size=18) ws["A2"] = f"発注書番号: {order_no}" ws["A3"] = f"発注日: {today.strftime('%Y年%m月%d日')}" ws["A4"] = f"仕入れ先: {supplier}" ws["A5"] = f"発注元: 自社 (自動発注システム by Claude Code)" # ── 明細ヘッダー ────────────────────────── col_headers = ["SKUコード", "商品名", "現在庫数", "発注数量", "単価(円)", "金額(円)"] ws.append([]) # 空行 ws.append(col_headers) header_row = ws.max_row for col in range(1, 7): cell = ws.cell(header_row, col) cell.fill = header_fill cell.font = Font(color="FFFFFF", bold=True) cell.alignment = Alignment(horizontal="center") # ── 明細行 ────────────────────────────── total = 0 for _, row in group.iterrows(): order_qty = int(row["発注点"]) * 2 # 発注数 = 発注点の2倍 unit_price = int(row.get("単価", 0)) amount = order_qty * unit_price total += amount ws.append([row["SKUコード"], row["商品名"], int(row["現在庫数"]), order_qty, unit_price, amount]) # ── フッター(合計行) ──────────────────── ws.append([]) ws.append(["", "", "", "", "合計", total]) total_row = ws.max_row ws.cell(total_row, 5).font = Font(bold=True) ws.cell(total_row, 6).font = Font(bold=True, color="107C41") # 列幅を自動調整 ws.column_dimensions["B"].width = 30 for col in ["A", "C", "D", "E", "F"]: ws.column_dimensions[col].width = 14 wb.save(filename) print(f"発注書作成: {filename} (合計: ¥{total:,})") generated_files.append(filename) return generated_files
5. 在庫回転率と欠品予測もClaude Codeに任せた
発注アラートと発注書の自動化が完成したので、次は在庫データの分析機能もClaude Codeに依頼しました。在庫回転率が低い商品(動かない在庫)と、最近の出庫トレンドから欠品リスクが高い商品を特定したいという要件です。
プロンプト例 3
以下の分析をして、結果をExcelの「分析レポート.xlsx」に出力してください:
1. SKUごとの在庫回転率(過去30日の出庫合計÷現在庫数)を計算
2. 在庫回転率が0(全く動いていない)のSKUをリストアップ
3. 過去7日の出庫トレンドから「このペースだとN日後に欠品する」という予測を計算
4. 分析結果を棒グラフ・折れ線グラフで可視化してExcelに埋め込む
# Claude Codeが生成した在庫分析スクリプト import pandas as pd import openpyxl from openpyxl.chart import BarChart, LineChart, Reference from datetime import datetime, timedelta def analyze_inventory() -> None: """在庫データと出庫履歴を分析してレポートを生成する""" # データ読み込み inv_df = pd.read_excel("inventory.xlsx") hist_df = pd.read_excel("出庫履歴.xlsx", parse_dates=["日付"]) today = datetime.now() past30 = today - timedelta(days=30) past7 = today - timedelta(days=7) # 過去30日の出庫合計を計算 recent30 = hist_df[hist_df["日付"] >= past30] turnover = recent30.groupby("SKUコード")["出庫数"].sum().reset_index() turnover.columns = ["SKUコード", "30日出庫合計"] # 在庫回転率を計算(出庫合計÷現在庫数) merged = inv_df.merge(turnover, on="SKUコード", how="left").fillna(0) merged["在庫回転率"] = (merged["30日出庫合計"] / merged["現在庫数"].replace(0, 1)).round(2) # 日次出庫平均から欠品予測日数を計算 recent7 = hist_df[hist_df["日付"] >= past7] daily_avg = recent7.groupby("SKUコード")["出庫数"].mean() merged["日次出庫平均"] = merged["SKUコード"].map(daily_avg).round(2) merged["欠品予測日数"] = ( merged["現在庫数"] / merged["日次出庫平均"].replace(0, 9999) ).round(1) # Excelに出力 with pd.ExcelWriter("分析レポート.xlsx", engine="openpyxl") as writer: # 全SKU分析シート merged.to_excel(writer, sheet_name="在庫回転率分析", index=False) # 不動在庫シート(回転率ゼロ) dead_stock = merged[merged["30日出庫合計"] == 0] dead_stock.to_excel(writer, sheet_name="不動在庫一覧", index=False) # 欠品リスク高(7日以内に欠品予測) risk = merged[merged["欠品予測日数"] <= 7].sort_values("欠品予測日数") risk.to_excel(writer, sheet_name="欠品リスク高", index=False) print(f"分析完了: 不動在庫 {len(dead_stock)}件 / 欠品リスク高 {len(risk)}件") analyze_inventory()
6. TeamsとSlackへの通知もClaude Codeに追加してもらった
メールアラートは確認が遅れることがあるため、Microsoft TeamsとSlackにもリアルタイム通知を送りたいとClaude Codeに依頼しました。Claude CodeはWebhook URLを使った通知コードをすぐに生成してくれました。
プロンプト例 4
Microsoft TeamsとSlackにも同時に通知したいです。
TeamsはIncoming WebhookのURLを使って、
Slackもincoming webhookを使って通知してください。
通知メッセージにはアラート件数と最も緊急度が高いSKUを含めてください。
# Claude Codeが追加したチャット通知機能 import requests import json TEAMS_WEBHOOK = os.environ["TEAMS_WEBHOOK_URL"] SLACK_WEBHOOK = os.environ["SLACK_WEBHOOK_URL"] def notify_teams(alert_df: pd.DataFrame) -> None: """Microsoft Teams に在庫アラートを送信する""" most_urgent = alert_df.iloc[0] # 最も緊急度が高いSKU payload = { "type": "message", "attachments": [{ "contentType": "application/vnd.microsoft.card.adaptive", "content": { "type": "AdaptiveCard", "body": [ {"type": "TextBlock", "text": f"在庫アラート: {len(alert_df)}件", "size": "Large", "weight": "Bolder", "color": "Warning"}, {"type": "TextBlock", "text": f"最優先: {most_urgent['商品名']}(在庫 {int(most_urgent['現在庫数'])}→ 発注点 {int(most_urgent['発注点'])})"}, {"type": "TextBlock", "text": "在庫管理Excelを確認し発注手続きを行ってください。", "wrap": True}, ] } }] } requests.post(TEAMS_WEBHOOK, json=payload, timeout=10) print("Teams通知送信完了") def notify_slack(alert_df: pd.DataFrame) -> None: """Slack に在庫アラートを送信する""" most_urgent = alert_df.iloc[0] text = ( f":rotating_light: *在庫アラート: {len(alert_df)}件の商品が発注点を下回っています*\n" f"最優先: `{most_urgent['商品名']}` (在庫: {int(most_urgent['現在庫数'])} / 発注点: {int(most_urgent['発注点'])})\n" f"今すぐ在庫Excelを確認し発注を行ってください。" ) requests.post(SLACK_WEBHOOK, json={"text": text}, timeout=10) print("Slack通知送信完了")
7. 消費期限管理もClaude Codeに依頼した
食品・医薬品を扱う部門から「消費期限が近い商品のアラートもほしい」という要望が来ました。Claude Codeに新機能の追加を依頼すると、既存コードに期限管理ロジックを組み込んでくれました。
プロンプト例 5
今日から30日以内に期限が切れる商品を抽出して、
メールとTeamsに「期限切れアラート」として通知してください。
7日以内・14日以内・30日以内で色分け(緊急度別)してほしいです。
期限切れ(今日以前)の商品は別途「廃棄候補リスト」として出力してください。
# Claude Codeが生成した消費期限管理コード from datetime import datetime, timedelta def check_expiry_dates(df: pd.DataFrame) -> dict: """消費期限の状況を分析して緊急度別に分類する""" today = datetime.now().date() df["消費期限"] = pd.to_datetime(df["消費期限"]).dt.date() df["残日数"] = (df["消費期限"] - today).apply(lambda x: x.days) return { "廃棄候補": df[df["残日数"] < 0], # 期限切れ "★★★ 7日以内": df[(df["残日数"] >= 0) & (df["残日数"] <= 7)], "★★ 14日以内": df[(df["残日数"] > 7) & (df["残日数"] <= 14)], "★ 30日以内": df[(df["残日数"] > 14) & (df["残日数"] <= 30)], } def export_expiry_report(expiry_dict: dict) -> None: """消費期限レポートをExcelに出力する""" with pd.ExcelWriter("消費期限レポート.xlsx", engine="openpyxl") as writer: for category, data in expiry_dict.items(): if not data.empty: data.to_excel(writer, sheet_name=category[:31], index=False) print("消費期限レポートを出力しました")
8. 導入事例
400種類の製造部品をExcelで管理していた工場では、月5〜6件の部品欠品で生産ラインが止まる問題が続いていました。Claude Codeに「発注点を下回ったら購買部担当者のTeamsに即時通知して、同時に発注書Excelを自動生成して」と伝えると、Claude Codeが1つの統合スクリプトを生成。プロンプト入力から動作確認まで約1時間で完成しました。導入後は欠品ゼロを達成し、年間240万円のコスト削減につながりました。
年間240万円削減
Claude Code導入1時間
1,200種類の商品を扱う小売店では、売れない商品の在庫が倉庫を圧迫していました。Claude Codeに「在庫回転率が低い商品を特定して、仕入れ量削減の提案レポートを作って」と依頼。Claude Codeが出庫履歴データを分析するコードを生成し、不動在庫を30%削減する具体的なアクションリストを自動生成しました。
在庫回転率自動分析
Claude Code活用
9. よくある質問(FAQ)
関連記事
Claude Codeで在庫管理を
自動化しませんか?
現在のExcel在庫管理の課題を教えていただければ、
Claude Codeへの最適なプロンプト設計と
自動化の実装方法を無料相談でご提案します。