Claude Media
Claude CodeでJANコードのチェックデジットを検算し重複と欠落を洗う

Claude CodeでJANコードのチェックデジットを検算し重複と欠落を洗う

商品マスタCSVのJAN列を、チェックデジット・桁数・重複・欠落の4観点で機械的に検算するスクリプトをClaude Codeに書かせる手順です。Excel由来の崩れ方と、同一JANの扱い方も示します。

商品マスタのJAN列は、チェックデジットの計算式、桁数、数字以外の混入、同じコードの二重登録、空欄で、機械的に見つけられます。どれも「CSVを1行ずつ読んで判定する」だけの作業です。ここでは、その検算スクリプトをClaude Codeに書かせ、実際のCSVに当てて結果を読む手順を示します。

値札やPOPの文言を作る前段として、マスタそのものの正しさを確かめる位置づけです。文言の生成は商品マスタCSVからPOP文言を量産する手順に任せ、ここではJAN列の検証に絞ります。例に出すコードは手順確認用の仮のもので、実在の商品とは関係ありません。

JANコードの構成と、検算できる範囲

GTIN(JANコード)は「どの事業者の、どの商品か」を表す商品識別コードです。主に単品を識別する13桁の標準タイプと、8桁の短縮タイプがあります。標準タイプは、GS1事業者コード(9桁、10桁または7桁)、商品アイテムコード(3桁、2桁または5桁)、チェックデジット(1桁)で構成されます。

検算で確かめられるのは、コードが「形式として成り立っているか」までです。そのコードが実在する商品を指すか、取引先の登録と一致するかは、マスタの外側の情報がないと判定できません。スクリプトが拾えるものを先に整理しておくと、人の確認に回す範囲も決まります。

検算の範囲

スクリプトで機械的に判定できる4項目

  • チェックデジット

    末尾1桁が計算式と合うかを確かめます。1桁だけの打ち間違いは、必ず不一致になります。

  • 桁数・文字種

    13桁か8桁の数字だけかを確かめます。Excelで指数表記に化けた値や、空白の混入もここで拾えます。

  • 重複

    同じJANが複数の行に登録されていないかを確かめます。

  • 欠落

    JAN列が空の行を洗い出します。

チェックデジットが合っていても、別の桁の誤りが重なれば検算を通ってしまう場合があります。通過はマスタの正しさの証明にはなりません。

チェックデジットの計算式を確認する

チェックデジットは、末尾の1桁から左へ「桁番号」を振って求めます。GS1 Japanの解説に沿うと、手順は次の5段階です。

手順

標準タイプ(13桁)のチェックデジットの求め方

  1. 1

    偶数桁を足す

    チェックデジットを1桁目とし、右端から左へ桁番号を振ります。偶数桁の数字をすべて加算します。

  2. 2

    3倍する

    ①の結果を3倍します。

  3. 3

    奇数桁を足す

    チェックデジットを除いた奇数桁の数字をすべて加算します。

  4. 4

    合算する

    ②と③の結果を加算します。

  5. 5

    10から引く

    ④の結果の下1桁を10から引いた数がチェックデジットです。下1桁が0なら、チェックデジットも0です。

GS1 Japanの例では、GS1事業者コード「456995111」に商品アイテムコード「617」を足した12桁から、チェックデジットは9と求まります。偶数桁の合計は33で、3倍して99、奇数桁の合計は22なので、99と22の和は121です。10から下1桁の1を引くと9になり、完成したコードは4569951116179です。

8桁の短縮タイプも同じ式です。同じページの例では、GS1事業者コード「499687」に商品アイテムコード「1」を足した「4996871」から、チェックデジットは2と求まり、コードは49968712になります。

実装では、右端のデータ桁(チェックデジットの一つ左)の重みが3、その左が1と交互に続く形に書き直せます。桁数が13桁でも8桁でも、末尾を除いた部分に同じ関数を適用できるので、スクリプトは1本で済みます。

GS1 Japanのサイトには、チェックデジットの自動計算フォームがあります。計算結果は各事業者の責任のもとで利用するよう、同ページに書かれています。数千行を検算するなら、フォームに1件ずつ入れるよりスクリプトのほうが現実的です。

Claude Codeに検算スクリプトを書かせる

Claude Codeは、コードベースを読み、ファイルを編集し、コマンドを実行する、ターミナル向けのコーディングツールです。CSVのあるフォルダで起動して、検算の仕様を文章で渡します。

仕様は「何を検出し、何は検出しないか」まで書くのがポイントです。検出の対象は前節の4項目で、マスタの書き換えは含めません。修正は人が判断するので、スクリプトは読み取り専用にします。

master.csv の jan 列を検算する Python スクリプト check_jan.py を作ってください。
- 標準13桁と短縮8桁が対象。計算式は、右端のデータ桁の重みを3、
  その左を1として交互に掛けて合計し、10から下1桁を引く。
  下1桁が0ならチェックデジットは0
- 検出: 空欄 / 数字以外の混入 / 13桁・8桁以外 / チェックデジット不一致 /
  同じJANが複数行にあるもの
- 出力は「行番号 SKU 商品名: 内容」。不一致は正しい値も示す
- CSV は書き換えない。標準ライブラリだけで書く
- 先に、4569951116179 が正しい、4996871 の次が 2 になる、という2つの例を
  テストにして通してから本体を仕上げる

最後の指示が検算の核心です。公式の例をテストとして先に固定すると、計算式の取り違え(偶数桁と奇数桁の逆転など)を、実データに当てる前に検出できます。テストの書き方と進め方は、テストが無いコードを安全に直す手順と同じ考え方です。

出来上がったスクリプトの中心部は、次のような形になります(Claude Codeの実際の出力ではなく、仕様に沿って筆者が書いた例です)。

def check_digit(body: str) -> int:
    """チェックデジットを除いた桁列から検査桁を返す。"""
    total = 0
    for i, ch in enumerate(reversed(body)):
        total += int(ch) * (3 if i % 2 == 0 else 1)
    return (10 - total % 10) % 10

(10 - total % 10) % 10 の外側の % 10 が、合計の下1桁が0のときにチェックデジットを0にする処理です。ここを書き忘れると、10になって1桁に収まりません。

仮のマスタに当てて結果を読む

次のような10行の仮マスタを用意し、スクリプトを実行します。意図的に、よくある崩れ方を詰め込んだ例です。

sku,name,jan
A001,サンプル緑茶 500ml,4569951116179
A002,サンプル緑茶 350ml,4569951116186
A003,サンプル麦茶 500ml,4569951116194
A004,サンプル麦茶 350ml,4569951116193
A005,サンプルほうじ茶 500ml,
A006,サンプル紅茶 500ml,4.56995E+12
A007,サンプル玄米茶 500ml,456995111620
A008,サンプル烏龍茶 500ml,4569951116179
A009,サンプルミニ缶,49968712
A010,サンプル詰合せ,4569951116 25

Python 3.12.2で実行すると、次の出力が得られました。終了コードは検出があるため1です。

python3 check_jan.py master.csv
L4 A003 サンプル麦茶 500ml: チェックデジット不一致(正しくは3)
L6 A005 サンプルほうじ茶 500ml: 欠落(空欄)
L7 A006 サンプル紅茶 500ml: 数字以外を含む: '4.56995E+12'
L8 A007 サンプル玄米茶 500ml: 桁数が12桁(標準13桁か短縮8桁が対象)
L11 A010 サンプル詰合せ: 数字以外を含む: '4569951116 25'
重複 4569951116179: L2 A001 サンプル緑茶 500ml / L9 A008 サンプル烏龍茶 500ml
検出 6 件

10行のうち5行から6件の検出が出ました。行ごとの読み方は次のとおりです。

  • A003:1桁の打ち間違いです。末尾が4で、正しい値は3。1桁だけの打ち間違いは、どの位置でもチェックデジットが不一致になります。別の有効なコードに化けるのは、2桁以上の誤りが重なった場合や、誤った値に合わせてチェックデジットを計算し直した場合です
  • A005:空欄です。新商品の登録待ちなのか、入力漏れなのかは、スクリプトでは判別できません
  • A006:Excelで数値として扱われ、指数表記に化けた例です。元の桁は失われているため、復元せず取引先の資料から入れ直します
  • A007:12桁です。先頭の数字が落ちたのか、末尾が欠けたのかで、直し方が変わります
  • A010:桁の途中に空白が入っています。見た目では気づきにくい種類の誤りです
  • A001とA008:同じコードが別商品に付いています

A001とA002は、容量違いで別のコードです。GS1 Japanは、商品名・色・容量・素材・包装サイズ・香り・味・販売単位が異なる場合は、それぞれ別のGTIN(JANコード)を設定するよう案内しています。A004とA009は、検算を通過しています。

重複の読み方 — 同じJANが別商品に付いているとき

重複の検出結果は、必ずしも「どちらかが誤り」とは限りません。同じ商品を複数の売り場・規格で二重登録しただけの場合もあれば、別の商品に同じコードを誤って割り当てている場合もあります。

GS1 Japanの手順では、商品アイテムコードは自社で重複のないように設定し、正確に管理するよう案内されています。仕様が変わった商品には異なるコードを付け、同じコードの商品は在庫管理や売上管理で同じ商品として扱われます。また、ある商品に設定したJANコードを、終売(廃番)後に別の商品へ転用することはできません。

この規則を踏まえると、重複の読み方は次の表のとおりです。

重複の様子疑うこと確認先
商品名・規格が同じ疑うこと二重登録確認先行を統合するか、片方を廃止
商品名が異なる疑うことコードの誤割当、または転用確認先取引先の商品情報・納品書
終売品と現行品で同じ疑うこと廃番コードの再利用確認先終売日と現行品の設定時期

スクリプトは「同じコードが並んでいる」ことしか言えません。表の右列の確認は、取引先の資料と突き合わせる人の作業として残ります。Claude Codeに任せられるのは、検出した行を一覧にして、確認先ごとに分類するところまでです。

逆に、商品名が同じで別のJANが付いている行は、容量違いや販売単位違いで正当な場合が多く、検出対象に入れていません。入れると誤検出が増えて、本当の誤りが埋もれます。

検算を毎回の習慣にする仕組み

一度スクリプトを書いても、マスタが更新されるたびに手で実行するのでは、いずれ忘れます。Claude Codeの設定ファイルに運用ルールを書いておくと、次回以降の作業に同じ前提を引き継げます。

プロジェクトのルートに置くCLAUDE.mdは、Claude Codeがセッションの開始時に読む指示ファイルです。マスタを扱うフォルダなら、次のような断片が使えます。

# 商品マスタの取り扱い
- master.csv の jan 列を変更したら、必ず `python3 check_jan.py master.csv` を実行する
- 検出が1件でもあれば、その内容を一覧にして報告する。勝手に値を直さない
- jan 列は文字列として扱う。数値に変換しない(指数表記と先頭桁の欠落を防ぐため)
- 重複は商品名・規格が同じか異なるかで分けて報告する

マスタを更新する作業そのものも、Claude Codeに任せられます。ただし、更新した行にチェックデジットの誤りがあるかどうかは、Claude自身ではなくスクリプトの出力で判断させるのが確実です。Claude Codeはコマンドを実行して出力を読めるので、「直す→検算する→出力が空になるまで繰り返す」という反復を指示できます。

ターミナルから呼び出すだけなら、Claude Codeの-pオプションでパイプ入力にもできます。公式ドキュメントには、ログを渡して分析させる形や、変更ファイルの一覧を渡してレビューさせる形がUnix流の組み合わせ方として載っています。検算の結果をそのまま渡して、確認の優先順位を付けさせる使い方も同じ発想です。

python3 check_jan.py master.csv | claude -p "検出内容を修正方法ごとに分類してください"

この方法で渡すのは検算結果の文字列だけで、マスタ全体ではありません。商品名や仕入れ値などの列を含むCSVを丸ごと外に出したくない場合でも、JAN・SKU・商品名の検出行だけで分類は進められます。

検算を通っても残る誤り

検算を通過したJANが、正しいJANとは限りません。次の3点は、スクリプトの外で確かめます。

  1. 別の実在コードへの化け:複数桁の誤りが重なると、結果がたまたま別の商品の有効なコードになる場合があります。商品名とJANの対応は、取引先の商品情報との突き合わせでしか確認できません
  2. 事業者コードの誤り:先頭の事業者コード部分の誤りは、チェックデジットを計算し直した人が「正しい形式」にしてしまうことがあります。国内の貸与は「45」または「49」で始まる番号なので、警告として拾う手はありますが、輸入品の海外コードもあるため、誤りと断定はできません
  3. 終売品の再利用:前節の転用です。スクリプトは廃番の履歴を持たないので、検出できません

こうした限界を知っておくと、「検算が通ったから正しい」という過信を避けられます。検算は、明らかな誤りを機械的に除く第一段階で、最終的な正しさは取引先データとの照合で確定します。

よくあるつまずき

Excelで開き直して保存したら、桁が化けた

CSVをExcelで開いて保存すると、長い数字列が数値として解釈され、指数表記や下位桁の丸めが起きる場合があります。上の例のA006はこの型です。保存済みのファイルから元の値は復元できないため、CSVはテキストエディタか、列を文字列として読み込む設定で扱います。

先頭の0が落ちて桁数が足りない

先頭が0で始まるコードを数値として保存すると、0が消えて桁数が減り、桁数検査に引っかかります。落ちた桁は、元データがなければ補えません。先頭が0で始まる海外由来のコードで起きやすい型です。

検出が多すぎて、どこから直すか迷う

検出内容を種類別に分けると、直す順番が決まります。文字種・桁数の崩れは入力形式の問題なので先に直し、チェックデジット不一致は取引先の資料で照合し、重複は最後に商品名の突き合わせへ回します。この分類は、前節のパイプでClaude Codeに任せられます。

スクリプトが正しいか不安

公式の例(4569951116179、49968712)を通すテストを先に置いたうえで、手元の数件を計算フォームで照合すれば、実装の取り違えはほぼ防げます。これ以上の検証は、実際のマスタで検出が出るかを見ながら進めます。

まとめ

JAN列の検算は、計算式・桁数・重複・欠落の4項目で、数千行でも短時間で終わります。Claude Codeには、公式の例をテストに固定してからスクリプトを書かせ、検出の出力を読んで分類させるところまでを任せられます。直す判断と取引先との照合は人が担う、という分担にすると、誤検出も見落としも抑えられます。

値札やPOPの文言を作る作業へ進む前に、この検算をマスタの受け入れ条件にしておくと、後続の文言生成の手戻りを減らせます。

この記事を共有:XはてブLinkedIn