売上データを取り込んだら金額が合わないときの原因|「成功」と出ても明細が消える一意キーの衝突と、投入後に必ず行う突合
売上データを取り込んだら金額が合わないときの原因|「成功」と出ても明細が消える一意キーの衝突と、投入後に必ず行う突合
POSレジや顧客管理システムから出した月次の売上データを、本部の集計システムやスプレッドシートに取り込む。画面には「528件取り込みました」と出て、エラーは何も無い。ところが合計金額を元の帳票と見比べると、数万円だけ少ない。行数を数えると数行足りない。この症状で「ツールの不具合では」「元ファイルが壊れているのでは」と探し回る人が多いのですが、多くの場合どちらでもありません。
先に結論を書きます。
金額が合わないのに「成功」と出るときの原因の代表は、一意キーの衝突です。 取り込み先のデータベースは「店舗×年月×商品コード」のような組み合わせを「同じ1件」と判定しています。元データにこの組み合わせが2回出てくると、後から来た行が先の行を上書きし、先の行が消えます。取り込みツールは上書きも「1件処理した」と数えるので、件数は元データと同じに見え、成功と表示されます。
正しいやり方は3つです。取り込み先が何を「同じ1件」と判定しているかを把握すること。元データにその組み合わせの重複が無いかを取り込み前に検出し、あれば変換側でキーを分けること。投入後に明細の合計金額と件数を、元帳票の合計行と突合すること。この3つを毎月の手順に固定すれば、完了メッセージに頼らずに済みます。
この記事では、graciauto(名古屋のWEB制作会社)が美容サロンFCの本部向けに運用している集計システムで、20店舗の月次売上を取り込んだ際に5行・97,500円が静かに欠けた実例をもとに、衝突が起きる仕組み、変換側での分け方、投入後の突合手順、取り込みツールを作る・発注するときの判断基準をまとめます。
結論:金額が合わない原因は3つの型に分かれ、「成功」表示は判断材料にならない
売上データの取り込みで金額が合わないとき、原因はおおむね次の3つに分かれます。どの型かで、見るべき場所と直し方が変わります。
| 型 | 症状の出方 | 気づき方 |
|---|---|---|
| 範囲違い | 金額が桁違いに小さい。1店舗だけ極端に少ない | 元ファイルの期間(開始日・終了日)を見る |
| 読み飛ばし | 店舗ごと丸ごと無い。または0円の謎の行が混ざる | 店舗数と行数を数える |
| 一意キーの衝突 | 数行・数万円だけ少ない。件数表示は正常 | 明細の合計と合計行を突合する(本稿の主題) |
1つ目の範囲違いは、例えばPOSレジの期間指定が「当日〜当日」のまま出力され、1日分のファイルを1か月分として取り込んでしまう型です。形式は正常なので、ファイルを開いただけでは気づけません。2つ目の読み飛ばしは、店舗名の表記が登録と1文字違う、見出し行がページごとに繰り返されている、といった理由でツールが行を黙ってスキップする型です。
3つ目の一意キーの衝突は、上の2つより見つけにくい特徴があります。店舗単位で見ても揃っている、件数も合っている、それでも金額だけが少しずれる。この型は合計の突合でしか見つかりません。
なお、「処理は動いたのにデータが反映されない」という別の型については自動処理が「成功」と出ているのに反映されないときで扱っています。本稿はその先の、処理が成功した上でデータの一部が欠ける型です。
一意キーの衝突とは何か:取り込みツールは「上書き」も「成功」と数える
データベースの表には、「この組み合わせが同じなら同じ1件とみなす」という決まりがあります。これを一意キーと呼びます。売上明細なら「店舗×年月×商品コード」が典型です。
取り込みツールの多くは、同じキーの行が既にあれば上書きし、無ければ追加する動き(upsertと呼ばれます)で作られています。これ自体は理にかなった設計です。ある店舗のファイルを取り直して再投入したとき、古い行が残らず新しい値に置き換わるからです。前述の「1日分を1か月分として入れてしまった」場合も、正しいファイルで再投入すれば上書きで直ります。
問題は、同じ月の元データの中に、同じキーの行が2回出てくるときです。
- 1行目が追加される
- 2行目は同じキーなので「追加」ではなく「上書き」になる
- 1行目の金額は2行目の金額に置き換わり、1行目の分は消える
- ツールは1行目も2行目も「1件処理した」と数える
結果、元データが528行なら「528件」と表示されます。表の中に残っているのは523行なのに、です。消えるのは後の行ではなく先の行で、差額は先の行の金額そのものになります。
なぜ同じ商品コードが2回出るのか:メニュー分類の付け替えで起きる
「同じ店舗、同じ月、同じ商品コードの行が2回出る」というのは、一見おかしなデータに見えます。ところがPOSレジ側では、ごく普通の運用で起きます。
美容サロンのPOSレジでは、メニューに「商品コード」と「分類」の両方が付いています。本部が新しいメニュー分類を作り、既存のメニューをその分類にも登録すると、月次の技術売上集計には同じ商品コードが2つの分類の下にそれぞれ出てきます。分類ごとに集計しているので、集計表としては正しい形です。
一方、集計システム側の一意キーには「分類」が含まれていませんでした。商品コードだけで管理していたのは、過去月との連続性を保つためです。同じメニューを商品コードで追いかければ、分類の名前が変わっても推移が切れません。
つまり、POS側の自然な操作と、集計側の合理的な設計が組み合わさった結果として衝突が起きます。どちらかが間違っているわけではなく、「分類が変わりうる」という前提が一意キーの設計に入っていなかった、というのが正確な捉え方です。
実例:20店舗の月次売上を取り込んだときの5行・97,500円
graciautoが運用する本部向け集計システムでは、毎月、各店舗のPOSレジから出力した「技術売上集計」と「顧客区分別売上」を店舗ごとに受け取り、変換スクリプトで取り込み用のブックにまとめてから投入しています。2026年8月分は20店舗・41ファイルでした。
確認した内容
| 確認項目 | 元データ | 投入後 |
|---|---|---|
| 明細の行数 | 528行 | 523行 |
| 明細の合計金額 | 合計行と一致 | 97,500円少ない |
| 取り込みツールの表示 | 「528件インポート」 | 同左(成功扱い) |
差が出たのは投入直後の突合です。変換ブックの明細528行に対して、投入後の表を数えると523行。金額も97,500円少ない。ツールの完了メッセージは「528件」で、これだけ見ていれば成功です。
原因
2店舗で、新しく作られたメニュー分類に既存の商品コードが再掲されていました。片方の店舗で4つ、もう片方で1つ、合計5つの商品コードが同じ月に2回出ており、一意キー(店舗×年月×商品コード)で後の行が先の行を上書きしていました。欠けた5行と97,500円は、先に出ていた分類側の金額です。
直し方
取り込み先の一意キーは変えませんでした。過去1年以上の月次データが同じキーで積まれているので、キーの定義を変えると過去分との照合が崩れます。代わりに変換側で分けました。
- 同じ店舗・同じ月の中で、同じ商品コードが2回目以降に出たら、コードの末尾に分類コードを付けて別のコードにする(例:1012が2回目に出たら「1012_30」)
- 最初に出た行は素のコードのまま残す。過去月と同じコードで追えるので連続性が切れない
- 変換スクリプトがこの重複を自動検出して知らせる。翌月以降に同じ分類の付け替えがあっても、人手で探さなくて済む
検証
再投入後、明細の合計金額と件数が、各店舗の合計行と20店舗すべて一致。技術売上の金額を「技術売上集計」と「顧客区分別売上」の2帳票間でも突合し、こちらも20店舗すべて一致しました。全店合計は前月の15,779,690円に対して16,218,321円(新店2店舗を含む)です。
この件で押さえておきたいのは、欠落そのものより「突合をしていなければ、欠けたまま次の工程に進んでいた」という点です。この集計システムは投入後に各店舗の月次レビューを生成し、店舗オーナー向けの資料として配ります。突合が無ければ、5行少ないデータでレビューが作られ、そのまま配られていました。
投入後に必ず行う突合の手順
取り込みの手順は「取り込み前」「投入直前」「投入後」の3段階に分け、それぞれにチェックを固定します。まず元データを検査し、次にバックアップを取り、最後にデータ側で突合する順番です。
取り込み前(元データの検査)
- 期間が「1日〜月末」になっているか。開始日が1日でないファイルは弾く
- 店舗名が登録済みの名前と一致するか。未登録の名前があれば止める
- 同じ店舗のファイルが2つ以上無いか。内容が同一なら最新を採用し、異なれば人が判断する
- 一意キーの重複が無いか。あれば変換側で分けて、分けた内容を記録する
投入直前
- 取り込み先のバックアップを取る。投入後に差が出ても、戻せる状態を先に作る
投入後(データ側の検査)
| 突合項目 | 何と何を比べるか | 一致しないときに疑うこと |
|---|---|---|
| 明細の合計金額 | 投入後の明細の合計 と 元帳票の合計行 | 一意キーの衝突、読み飛ばし |
| 明細の件数 | 投入後の行数 と 変換ブックの行数 | 一意キーの衝突 |
| 店舗数 | 投入後に存在する店舗 と 受け取ったファイルの店舗 | 店舗名の不一致による丸ごとスキップ |
| 帳票間の一致 | 同じ数字が載る2種類の帳票の該当欄 | 元ファイルの範囲違い、取り違え |
4つ目の「帳票間の一致」は、元データそのものの検査でもあります。技術売上の金額は「技術売上集計」にも「顧客区分別売上」にも載るので、この2つが一致していれば元ファイルの範囲違いや取り違えも同時に潰せます。
ここで大事なのは、突合を人の目でやらないことです。20店舗×数百行を毎月目視で比べるのは続きません。変換スクリプトに組み込み、突合を通らなければ次の工程に進めない順序にします。管理画面での設定変更を件数で確かめる考え方と同じで、詳しくは管理画面の設定変更が保存されていないことがあるにまとめています。
取り込みツールを作る・発注するときの判断基準
自社で集計ツールを作る場合も、制作会社に発注する場合も、次の4点を先に決めておくと、この型の欠落を設計段階で防げます。
1. 一意キーに何を含めるか
業務上「同じ1件」とみなす単位を、データの都合ではなく運用の都合で決めます。メニューの分類が将来変わりうるなら、分類を含めるか、あるいは実例のように変換側で分ける方針を最初から持っておきます。どちらを選ぶにしても、「同じキーが2回出たらどうするか」を決めていない設計は避けます。
2. 上書きを許すかどうか
再投入で直せる利点を取るなら上書き(upsert)は必要です。その代わり、完了メッセージの件数は「処理した数」であって「表に残った数」ではないことを、使う側が理解しておく必要があります。可能なら「新規N件・更新M件・スキップK件」と分けて表示させます。同じ月の初回投入で「更新」が1件でもあれば、それが衝突のサインです。
3. 完了メッセージに合計金額を出す
「528件」だけでなく「528件・合計○○円」と出すようにします。件数は上書きで狂いますが、金額は狂いません。元帳票の合計行と一目で見比べられます。
4. 突合を通らないと次工程が動かない順序にする
取り込み→突合→レポート生成、という順序を固定し、突合で差が出たらレポート生成に進めないようにします。実例のシステムでも、レポートの一括生成は突合が済んでから実行する手順にしています。この一括生成の仕組みは店舗ごとの月次レポート作成を自動化するで扱っています。
商品コードのような識別子の扱いは、EC側でも同じ問題が起きます。複数の販売チャネルの品番を1つに揃える話は楽天・Amazon・Yahoo!・自社ECの受注を1つにまとめる方法にまとめています。
起こりうる失敗と予防
| 起こりうること | 予防 |
|---|---|
| 1日分のファイルを1か月分として取り込む | 取り込み前に期間の開始日が1日か、終了日が月末かを機械で確認する |
| 店舗名の表記揺れ(半角スペースなど)で店舗ごと黙ってスキップされる | 店舗名を登録名と照合し、未登録なら止める。投入後に店舗数を数える |
| ページ跨ぎで繰り返された見出し行が「コード」という0円の行として入る | 商品コードが数値でない行を変換側で除外する |
| 同じ店舗の出力ファイルが2つあり、古い方を採用する | 内容が同一なら最新を採用、異なれば人が確認する規則を先に決める |
| 同じキーの行が2回出て、先の行が上書きで消える | 変換側で2回目以降のキーを分ける。投入後に合計金額と件数を突合する |
| 突合をせずにレポート生成へ進み、欠けたデータで資料が配られる | 突合を通らなければ次工程に進めない順序にする |
| 投入後に差が出たが、戻せない | 投入直前にバックアップを取る |
上の表のうち、範囲違い・表記揺れ・重複ファイルの3つは、実例の集計システムでも変換スクリプトの自動チェックとして組み込んでいる項目です。一意キーの重複検出も同じスクリプトに加えましたが、検出条件に入っていない新しい型は必ず通り抜けてくるので、投入後の突合が最後の砦になります。
よくある質問
Q. 取り込みツールが「成功」と出ているのに疑う必要がありますか。
あります。「成功」はツールがエラーなく最後まで動いたことを示すだけで、表に残ったデータが元データと同じであることは保証しません。特に上書きを許す設計のツールでは、件数が元データと一致していても行が消えている場合があります。判断は完了メッセージではなく、投入後の合計金額と件数で行います。
Q. 数万円の差なら誤差として流してもよいですか。
流さないでください。差の大きさより「差がある理由が分かっているか」が判断基準です。実例の97,500円は全店合計の1%未満ですが、欠けていたのは特定の2店舗の特定のメニュー分類で、その店舗のレビューでは分類ごとの数字が丸ごと変わります。理由が分かるまで次工程に進めないのが正解です。
Q. 外注先に何を確認すればよいですか。
3つです。「一意キーは何か」「同じキーが2回来たらどう動くか(上書きか、エラーか、両方残すか)」「投入後に合計金額と件数を元帳票と突合する手順があるか」。この3つに即答が返ってくれば、この型の欠落は設計に織り込まれています。「成功と出れば大丈夫です」という答えなら、突合の手順を追加してもらってください。
まとめ
- 取り込みが「成功」と出ても金額が合わないときの代表原因は一意キーの衝突。同じキーの行が2回出ると後の行が先の行を上書きし、ツールは上書きも1件と数えるので件数は正常に見える
- 衝突はPOS側の自然な操作(メニュー分類の付け替え)で起きる。設計の穴であって、誰かの操作ミスではない
- 直すときは取り込み先のキーを変えず、変換側で2回目以降のキーを分ける。最初の行は素のコードのまま残して過去月との連続性を守る
- 投入後は明細の合計金額・件数・店舗数・帳票間の一致を突合し、通らなければ次工程に進めない順序にする。完了メッセージは判断材料にしない
- ツールを作る・発注するときは、一意キー・上書きの扱い・完了メッセージの中身・突合の位置を先に決める
多店舗の売上データを本部で集約する仕組み、取り込み後の突合を自動化する設計、店舗のホームページやLINE公式アカウントと連動した本部向け管理ツールについてのご相談はお問い合わせからどうぞ。現在の取り込み手順と、金額が合わなかったときの状況を添えていただくと、原因の型を早く絞れます。