形の違う売上CSVを、月次の Excel にまとめる
3店舗のレジから出した売上CSVを読み、月次の Excel レポートを1つ作ります。店舗ごとに違う文字コード・列名・日付の書き方は読み込むときにそろえ、おかしな行はファイル名と行番号つきで「要確認」シートに出します。
- 入力
- 店舗ごとの売上CSV(1か月分)と商品マスタ
- 出力
- Excel 1ファイル(5シート)
- 確かめること
- マイナス数量、金額の不一致、重複行など7種類
読ませた CSV
架空の雑貨店3店舗の、9月分の売上です。レジの機種が店舗ごとに違うという想定で、形がそろっていません。
honten_202609.csv日付,商品コード,商品名,数量,単価,金額,区分 2026/08/31,2000000000053,布巾 3枚組,2,550,1100,売上 2026/09/01,2000000000015,ブレンドコーヒー豆 200g,3,1280,3840,売上 2026/09/01,2000000000091,紅茶ティーバッグ 20袋,6,760,4560,売上 …
ekimae_202609.csv売上日,JAN,品名,個数,販売単価,金額,取引区分 20260901,2000000000084,キャンバストート,4,2200,8800,通常 20260901,2000000000046,ステンレスボトル 350ml,7,2232,15624,通常 20260901,2000000000114,アロマキャンドル,2,1320,2640,通常 …
kogai_202609.csvdate,商品コード,数量,単価,金額 令和8年9月1日,2000000000039,5,"1,650","8,250" 令和8年9月1日,2000000000046,5,"2,232","11,160" 令和8年9月1日,2000000000077,2,880,"1,760" …
| 本店 | 駅前店 | 郊外店 | |
|---|---|---|---|
| 文字コード | Shift_JIS | UTF-8(BOM付き) | Shift_JIS |
| 日付の列名 | 日付 | 売上日 | date |
| 商品の列名 | 商品コード | JAN | 商品コード |
| 数量・単価の列名 | 数量・単価 | 個数・販売単価 | 数量・単価 |
| 日付の書き方 | 2026/09/01 | 20260901 | 令和8年9月1日 |
| 返品の見分け | 区分=返品 | 取引区分=返品 | 列がない |
できあがった Excel
上の3ファイルから作りました。売上は 2,753,347円(返品を差し引いた額)、要確認は 11件でした。
店舗×月シート
| 年月 | 店舗 | 売上金額 | うち返品 | 販売数量 | 明細行数 | 要確認件数 |
|---|---|---|---|---|---|---|
| 2026-09 | 本店 | 1,170,986 | -1,280 | 850 | 172 | 4 |
| 2026-09 | 駅前店 | 854,537 | -2,480 | 661 | 178 | 3 |
| 2026-09 | 郊外店 | 727,824 | 0 | 532 | 159 | 4 |
| 2026-09 | 合計 | 2,753,347 | -3,760 | 2,043 | 509 | 11 |
郊外店の「うち返品」が0なのは、郊外店のCSVに区分の列がなく、返品を見分けられないためです。郊外店のマイナスの行は要確認に出しています。
要確認シート
| No | 種別 | ファイル | 行 | 数量 | 単価 | 金額 | 内容 | 集計 |
|---|---|---|---|---|---|---|---|---|
| 1 | 対象月外の日付 | honten_202609.csv | 2 | 2 | 550 | 1,100 | 対象月(2026-09)以外の日付です。集計には含めていません。 | 除外 |
| 2 | マイナス数量 | honten_202609.csv | 63 | -2 | 1,650 | -3,300 | 数量がマイナスですが、区分が「売上」で返品ではありません。 | 含む |
| 3 | 金額不一致 | honten_202609.csv | 91 | 3 | 980 | 2,490 | 数量×単価 = 2,940 ですが、金額は 2,490 です(差 -450)。 | 含む |
| 4 | 重複行 | honten_202609.csv | 127 | 6 | 1,650 | 9,900 | 126行目と同じ内容です。 | 含む |
| 5 | 単価の乖離 | ekimae_202609.csv | 87 | 2 | 198 | 396 | 標準単価 1,980円 に対して 198円(-90%)。±50% を超えています。 | 含む |
| 6 | 未登録の商品コード | ekimae_202609.csv | 109 | 1 | 300 | 300 | 商品マスタにない商品コードです。 | 含む |
| 7 | 対象月外の日付 | ekimae_202609.csv | 180 | 4 | 760 | 3,040 | 対象月(2026-09)以外の日付です。集計には含めていません。 | 除外 |
| 8 | マイナス数量 | kogai_202609.csv | 22 | -1 | 880 | -880 | 数量がマイナスです。このファイルには区分の列がないため、返品かどうか判定できません。 | 含む |
| 9 | 重複行 | kogai_202609.csv | 74 | 5 | 1,280 | 6,400 | 73行目と同じ内容です。 | 含む |
| 10 | 金額不一致 | kogai_202609.csv | 112 | 2 | 1,480 | 29,600 | 数量×単価 = 2,960 ですが、金額は 29,600 です(差 +26,640)。 | 含む |
| 11 | 読み取り不可 | kogai_202609.csv | 161 | 1 | 690 | 690 | 日付「令和8年9月31日」を読めません。 | 除外 |
店舗・日付・商品コードの列は省いています。サンプルCSVにはこの11行をわざと混ぜ、あわせて出してはいけない行(区分が返品の行、ちょうど半額の行)も入れてあります。11件を過不足なく出すことをテストで確かめています。
そのほかのシート
- 商品ランキング
- 売上金額の順。構成比と、店舗ごとの内訳
- 日別推移
- 毎日の、店舗ごとの売上と合計
- 読込ファイル
- 読んだファイル、判定した文字コード、行数、読めなかった行数
この Excel をダウンロード12KB
Claude Code での作り方
このツールは、AI のコーディング支援ツール Claude Code に、仕様をまとめた指示を1通渡して作らせました。進めた順番は次のとおりです。
- 依頼を書き起こす。
- 依頼文だけでは決まらない点を質問として書き出し、前提を置く。
- Claude Code に守らせること(読ませないファイル、使ってよいコマンド)を設定する。
- おかしな行をわざと混ぜたサンプルCSVを作る。
- 実装より先にテストを書き、失敗することを確かめる。
- 実装し、テストを通す。
- 実際に動かして Excel の中身を読み直し、見つけた問題をテストに足してから直す。
- コードを読み直し、見つけた問題を同じ手順で直す。
- 人が確かめるべきことを書き出す。
そのあと、別の AI(OpenAI Codex)に読み取り専用でコードを読ませてレビューしました。指摘8件のうち7件を、先にテストを足して失敗を確かめてから直しました。店舗名の重複による二重計上、閉じていない引用符で後ろの行が消える問題などです。直さなかった1件は、17桁を超える数を Excel に書くと精度が落ちるという指摘です。Excel の数値が15桁までという Excel 側の限界で、売上の金額・数量ではこの桁を想定しないため、そのままにしました。
お客様の実データを置くフォルダは、Claude Code から読めない設定にしています。動作の確認は架空のサンプルだけで行います。
できないこと
- 1回に処理するのは1か月分です。前年同月比などの比較はありません。
- グラフは作りません。日別推移は表だけです。
- 和暦は令和だけ読めます。
- 区分の列がない店舗では、返品を見分けられません。マイナスの行はすべて要確認に出します。
- CSV を直す機能はありません。要確認に出すだけです。
- 毎月の自動実行やメール送信はしません。
使っている技術
Python 3.10 のコマンドラインツールで、使っているライブラリは openpyxl だけです。テストは116件で、動作は macOS で確かめています。