形の違う売上CSVを、月次の Excel にまとめる

3店舗のレジから出した売上CSVを読み、月次の Excel レポートを1つ作ります。店舗ごとに違う文字コード・列名・日付の書き方は読み込むときにそろえ、おかしな行はファイル名と行番号つきで「要確認」シートに出します。

入力
店舗ごとの売上CSV(1か月分)と商品マスタ
出力
Excel 1ファイル(5シート)
確かめること
マイナス数量、金額の不一致、重複行など7種類

読ませた CSV

架空の雑貨店3店舗の、9月分の売上です。レジの機種が店舗ごとに違うという想定で、形がそろっていません。

本店 Shift_JIS 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,売上
…
駅前店 UTF-8(BOM付き) ekimae_202609.csv
売上日,JAN,品名,個数,販売単価,金額,取引区分
20260901,2000000000084,キャンバストート,4,2200,8800,通常
20260901,2000000000046,ステンレスボトル 350ml,7,2232,15624,通常
20260901,2000000000114,アロマキャンドル,2,1320,2640,通常
…
郊外店 Shift_JIS kogai_202609.csv
date,商品コード,数量,単価,金額
令和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_JISUTF-8(BOM付き)Shift_JIS
日付の列名日付売上日date
商品の列名商品コードJAN商品コード
数量・単価の列名数量・単価個数・販売単価数量・単価
日付の書き方2026/09/0120260901令和8年9月1日
返品の見分け区分=返品取引区分=返品列がない

できあがった Excel

上の3ファイルから作りました。売上は 2,753,347円(返品を差し引いた額)、要確認は 11件でした。

店舗×月シート

年月店舗売上金額うち返品販売数量明細行数要確認件数
2026-09本店1,170,986-1,2808501724
2026-09駅前店854,537-2,4806611783
2026-09郊外店727,82405321594
2026-09合計2,753,347-3,7602,04350911

郊外店の「うち返品」が0なのは、郊外店のCSVに区分の列がなく、返品を見分けられないためです。郊外店のマイナスの行は要確認に出しています。

要確認シート

No種別ファイル行数量単価金額内容集計
1対象月外の日付honten_202609.csv225501,100対象月(2026-09)以外の日付です。集計には含めていません。除外
2マイナス数量honten_202609.csv63-21,650-3,300数量がマイナスですが、区分が「売上」で返品ではありません。含む
3金額不一致honten_202609.csv9139802,490数量×単価 = 2,940 ですが、金額は 2,490 です(差 -450)。含む
4重複行honten_202609.csv12761,6509,900126行目と同じ内容です。含む
5単価の乖離ekimae_202609.csv872198396標準単価 1,980円 に対して 198円(-90%)。±50% を超えています。含む
6未登録の商品コードekimae_202609.csv1091300300商品マスタにない商品コードです。含む
7対象月外の日付ekimae_202609.csv18047603,040対象月(2026-09)以外の日付です。集計には含めていません。除外
8マイナス数量kogai_202609.csv22-1880-880数量がマイナスです。このファイルには区分の列がないため、返品かどうか判定できません。含む
9重複行kogai_202609.csv7451,2806,40073行目と同じ内容です。含む
10金額不一致kogai_202609.csv11221,48029,600数量×単価 = 2,960 ですが、金額は 29,600 です(差 +26,640)。含む
11読み取り不可kogai_202609.csv1611690690日付「令和8年9月31日」を読めません。除外

店舗・日付・商品コードの列は省いています。サンプルCSVにはこの11行をわざと混ぜ、あわせて出してはいけない行(区分が返品の行、ちょうど半額の行)も入れてあります。11件を過不足なく出すことをテストで確かめています。

そのほかのシート

商品ランキング
売上金額の順。構成比と、店舗ごとの内訳
日別推移
毎日の、店舗ごとの売上と合計
読込ファイル
読んだファイル、判定した文字コード、行数、読めなかった行数

この Excel をダウンロード12KB

Claude Code での作り方

このツールは、AI のコーディング支援ツール Claude Code に、仕様をまとめた指示を1通渡して作らせました。進めた順番は次のとおりです。

  1. 依頼を書き起こす。
  2. 依頼文だけでは決まらない点を質問として書き出し、前提を置く。
  3. Claude Code に守らせること(読ませないファイル、使ってよいコマンド)を設定する。
  4. おかしな行をわざと混ぜたサンプルCSVを作る。
  5. 実装より先にテストを書き、失敗することを確かめる。
  6. 実装し、テストを通す。
  7. 実際に動かして Excel の中身を読み直し、見つけた問題をテストに足してから直す。
  8. コードを読み直し、見つけた問題を同じ手順で直す。
  9. 人が確かめるべきことを書き出す。

そのあと、別の AI(OpenAI Codex)に読み取り専用でコードを読ませてレビューしました。指摘8件のうち7件を、先にテストを足して失敗を確かめてから直しました。店舗名の重複による二重計上、閉じていない引用符で後ろの行が消える問題などです。直さなかった1件は、17桁を超える数を Excel に書くと精度が落ちるという指摘です。Excel の数値が15桁までという Excel 側の限界で、売上の金額・数量ではこの桁を想定しないため、そのままにしました。

お客様の実データを置くフォルダは、Claude Code から読めない設定にしています。動作の確認は架空のサンプルだけで行います。

できないこと

使っている技術

Python 3.10 のコマンドラインツールで、使っているライブラリは openpyxl だけです。テストは116件で、動作は macOS で確かめています。