食品リコールの規模は
仕入先請求書のバッチ番号で決まる
2026年6月、FDAは6つのサプライチェーンにまたがる15社と実施したトレーサビリティ演習の結果を公表しました。この演習では、各社が24時間以内に記録を提示できるかを検証し、対応時間はおおむね迅速でした。しかし、ほとんどの企業ができなかったのは、それらの記録を通じてロットコードを一貫して引き継ぐことでした。適切に割り当てられたトレーサビリティ・ロットコードをすべての段階で記録していたのは、わずか40%でした。
そのコードの出所を完全に記録していたのは、わずか27%でした。欠落していたのは、記録同士をつなぐ部分であり、多くの食品事業者にとって、その記録の起点は仕入先請求書です。

主なポイント
- FDAのトレーサビリティ演習で、すべての段階でロットコードを記録していたのはわずか40%で、そのコードの出所を記録していたのはわずか27%でした。
- 欠落しているのは記録同士をつなぐ部分であり、その結合された行の責任者という役職は誰にもありません。
- 請求書は支払いを証明するもので、パレットに何が届いたかは証明しないため、バッチコードは記載どおりに取得し、受入記録や生産記録と結合する必要があります。
リコールの範囲は、多くの請求書が任意扱いする1つの項目で決まる

どのパレットが返品されるかはバッチ番号で決まりますが、サプライヤーの請求書では、支払い用に設計された製品行の横に小さな文字で一度だけ印字されていることがよくあります。請求書はサプライヤー、数量、価格を記載する必要があり、その役割は十分に果たしています。バッチ番号は、サプライヤーの請求システムがたまたま含めていれば一緒に載り、含まれていなければ消えてしまいます。
欧州委員会のRegulation (EC) No 178/2002に関するガイダンスは、この違いを明確に示しています。請求書の保管は製品の商流を追跡するものであり、それだけでは「製品の物理的な流れを追うには不十分」でした。規則自体が求めているのはワンステップ・バックとワンステップ・フォワード、つまり直接のサプライヤーと直接の顧客を特定できることです。すべての請求書にバッチ番号を求めてはいませんが、同じガイダンスはバッチの詳細を「非常に有用」と述べています。請求書は法的に有用で、商業的に不可欠でありながら、バッチ記録としては不完全なのです。
FDA Food Traceability Ruleでは、トレーサビリティ・ロットコードは各重要追跡イベントで求められる主要データ要素の1つです。すべての要素はロットに紐づける必要があり、FDAは請求書を明示的に認めています。これらの要素を記載する参照文書として請求書を用いることができます。したがって、サプライヤーの請求書は適合記録の一部になり得ます。ただし、コードが適切なレベルで取得され、印字どおりに保持され、その後の食品の扱いを説明する受入記録や生産記録と結合されて初めて、そうなります。適合期限は2028年7月20日であり、対象事業者にはこの結合を構築する時間があります。
請求書が証明するのは商取引です。バッチ記録が証明するのは実際に何が到着したかであり、この2つの主張は同じではありません。
バッチ記録がリコールの問いに答えるために必要なもの
リコール対応では、使えるバッチ記録は1つのロットに関する4つの事実を結び付ける必要があります。誰が供給したか、いつ・どの数量を受領したか、どの製造ロットが使用したか、どの顧客が完成品を受け取ったかです。リコール通知は通常、サプライヤー名とコードとともに届き、残り3つの調査はそこから時間との勝負になります。
FDAの受入要件は、前半部分の形を示しています。対象食品のトレーサビリティ・ロットごとに、受領者はロットコード、数量と単位、製品説明、直前の供給元の所在地、受領場所、受領日、ロットコードの出所、参照文書の種類と番号を保持しなければなりません。これら9つのフィールドが、テーブルの1行を定義します。この規則はまた、FDAが要求した際に、電子的で並べ替え可能な形式で記録を24時間以内に提出することを定めています。PDFのアーカイブではこの基準を満たしませんが、1ロット1行のスプレッドシートなら満たします。
HACCPシステムの基盤となる衛生原則を定めたCodex Alimentariusも同じ見解をとっています。ロット識別は製品リコールと在庫ローテーションに不可欠であり、各容器は生産者とロットを識別すべきです。食品事業者の内部では、その記録の断片は異なる担当者に分散しており、「結合された行のオーナー」という役職名の人はいません。
| 役割 | 保持しているもの | その記録が答えられること | 単独では答えられないこと |
|---|---|---|---|
| 受入担当者 | 納品書、パレットラベル、ゲートログ | どのバッチが物理的に到着したか、そしていつか | どの請求書がいくらで請求したか |
| 財務/AP | 請求書PDFまたは電子請求書 | サプライヤー、請求数量、価格、支払条件 | どのバッチがパレットに載っていたか |
| QAリード | バッチ台帳、製造・衛生ログ | どの製造ロットがそのバッチを使用したか | 誰が供給したか、どの顧客が受け取ったか |
| 調達 | 発注書、サプライヤー連絡先 | コードが欠落または誤っている場合に誰へ問い合わせるか | 実際にドックに何が到着したか |

財務が請求書を保管するのは支払わなければならないからです。受入が納品書を保管するのはドライバーが署名するからです。QAがバッチログを保管するのは監査人が求めるからです。各記録はそれぞれの目的において完全であり、それらの間のリンクは、サプライヤーがリコール通知を発行するたびに手作業で再構築されます。その再構築にFDAの演習が数値を付けたのです。
実際のサプライヤー請求書でバッチ識別情報が崩れる箇所

崩れる原因は通常、請求書の記載内容と倉庫の実際の対応との間にある4つの小さな不一致であり、請求書の金額は合っているため、いずれも手作業のチェックをすり抜けます。
1つの請求書明細行、3つの物理バッチ
サプライヤーがモッツァレラ20ケースを1明細行・1単価で請求します。届いたパレットには3つの製造バッチが載っています。サプライヤーが注文を満たすために3回の製造分から詰め合わせたためです。請求書は支払いとしては正しく、トレーサビリティ記録としては誤っています。3つのロットを1つにまとめてしまっているからです。台帳を請求書明細行だけから作ると、中間バッチのリコールでは、同じ明細行を共有する2つのパレットを見落とすか、20ケースすべてを引き上げて顧客関係まで失うかのどちらかになります。
分割は受入時に行う必要があり、パレットラベルまたは納品書から取得します。台帳にはバッチごとに1行が必要で、各行に請求書番号を繰り返し記載します。これが、製品と数量だけで終わる明細行テーブルでは食品には不十分である理由でもあります。食品卸売業者の請求書明細行を抽出する場合と同じ仕組みが当てはまり、明細行の下にバッチという追加の階層が加わります。
バッチコードが請求書に到達しない
多くのサプライヤーはロットを納品書、ケースラベル、事前出荷通知、または後続のメールに記載し、請求書には記載しません。IFSQN食品安全フォーラムのある実務者は、ロットコードもバッチ番号もまったくない状態で届く原材料をどう追跡するかと質問しました。回答には、受入日と賞味期限による追跡や、発注書番号を代用する方法が含まれていました。これらの回避策は誠実なものですが、請求書から得られる情報の限界も示しています。コードが印刷されていなければ、抽出でそれを生成することはできず、スプレッドシートがでっち上げた番号は空白よりも悪いものです。
実用的な答えは、請求書と納品書を同じテーブルに着地する2つの受入キューとして扱うことです。APが請求書を転送し、受入担当者がドックで納品書を撮影します。どちらも同じ列に対して処理され、発注書番号または納品書番号が結合キーとなり、請求書番号は商業参照として保持されます。請求書にバッチがなく納品書にある場合は、納品書の行がその空白を埋めます。どちらにもない場合は、台帳にその旨を記載し、調達担当がサプライヤーに書面で確認します。これは、コードをでっち上げるのではなく、FDAが受入担当者に期待する対応でもあります。
日付コードは3つの異なる意味を持ち、5つの形式で存在する
製造日、賞味期限、消費期限は互換ではなく、Julian code は誰かがデコードするまで日付ですらない。それでもほとんどのスプレッドシートでは、この3つがすべて「Expiry」という見出しの列に入ってしまう。あるサプライヤーは BBE 03/2027 と印字し、別のサプライヤーは 27.03.2027、また別は 26087 のような Julian code、さらに別は年月のみを印字する。Excel はこれらの一部を問題なく日付として読み取り、他のものは黙って誤読する。そしてテキストと日付が混在した列は並べ替えができず、まさに先入れ先出し(FEFO)チェックが必要とする機能が働かない。
ほとんどの損害は2つのルールで防げる。元の文字列を1つの列に保持し、正規化した日付はドキュメントが完全な日付をサポートする場合にのみ別の列に配置する。月のみの賞味期限は、その月の1日にするのではなく月のみのままにしておくべきだ。次に日付タイプ用の列を追加し、賞味期限が消費期限として扱われないようにする。この違いは法的にも商業的にも重要である。期限切れの賞味期限は品質の問題であり、期限切れの消費期限は安全の問題である。
コードは1文字ずつ手作業で転記される
バッチ番号は一意になるよう設計された英数字の文字列であり、入力されるようには設計されていない。L26-0412/A はスラッシュが落ちて L26-0412A になり、0 は O になり、1 は I になり、末尾のサフィックスは消える。台帳は完全に見える。しかしリコール検索は何も返さない。バッチ番号の照合は完全一致だからだ。これは4つの失敗の中で最も静かなものであり、通常業務中よりも監査中に表面化する可能性が最も高い。内部監査について r/QAProfessionals で説明した QA 担当者によると、手作業のログと ERP の入力が同期していないため、一部のロットを原材料の起源まで追跡できないことが判明した。
リコール検索は完全一致であるため、1文字でも間違っている台帳は、その問いに答えられない台帳である。
対策は目視検証である。抽出されたすべてのバッチ番号は、それが由来するピクセルと照合して確認できなければならない。これが本記事の後半で説明するレビューステップの目的である。
請求書の明細行をトレーサビリティ行に変える列
列を一度定義すれば、同じセットがすべてのサプライヤーで機能します。出力はサプライヤーのレイアウトではなく、指定したフィールドによって決まるためです。以下は、請求書をまたいだバッチ番号抽出と賞味期限の追跡を1つの台帳に集約するフィールドと、それぞれのルールです。
| 列 | 入れる内容 | 記録を使用可能に保つルール |
|---|---|---|
| サプライヤー | 印刷されている正式名称 | 印刷された名称を保持し、サプライヤーIDへのマッピングは抽出時ではなく後で行う |
| 請求書番号 | 接頭辞・接尾辞を含め、印刷どおり | すべての行に繰り返し記載し、各バッチ行を請求書まで追跡できるようにする |
| 請求書日付 | 請求書に記載された日付 | 納品日や受入日と混同しない |
| 製品説明 | サプライヤーの表記 | 印刷どおりに保持し、内部品目コードは別の列にする |
| サプライヤー品目コード | サプライヤーのSKUまたは品番 | 説明が判別不能なほど省略されている場合に有用 |
| バッチ番号 / ロットコード | スラッシュや区切り文字を含め、印刷どおり正確に | 識別子を「整理」したり再フォーマットしたりしない。コードはリコールの鍵である |
| 製造日または包装日 | サプライヤーが印刷した箇所 | 賞味期限のみが印刷されている場合は空欄にする |
| 賞味期限 | 印刷された日付または月 | ドキュメントが対応する精度にのみ正規化する |
| 消費期限 | 印刷された日付 | 賞味期限とは分けて保持する。リスクが異なるため |
| 数量と単位 | 納品数量と計量単位 | バッチごとに1行とし、コードごとの数量を明確にする |
| 受入日 | 納品書またはゲートログから | FDAの受入記録が求める日付であり、請求書日付ではない |
| 日付タイプ | 賞味期限、消費期限、製造日、または不明 | 推論列。AIがページ上のラベル表記から分類する |
12列あれば、リコールに関する問い合わせの請求書側の半分に答え、次のシステムにクリーンな結合キーを渡すのに十分です。これは意図的に完全なトレーサビリティスキーマではありません。顧客列や製造ロット列はありません。それらの事実は出荷記録や製造記録にあり、サプライヤーの請求書にはないためです。それら用の空列を追加しても、表が完全に見えるだけで何も変わりません。
バッチコードは、決して整理してはならない唯一のフィールドです。日付は正規化し、識別子は保持します。
1つの列セットで40社に対応
40社あれば請求書のレイアウトも40通り、日付の表記も40通りあり、通常の月では1,000行を超える明細を1つの台帳にまとめて整合させなければなりません。この規模になると、手入力は一度に破綻するのではなく、少しずつ劣化していきます。まず崩れるのは、支払いが左右されないために誰も確認しない項目です。
ここに適した抽出モデルは、ImageToTable.aiがカスタム列抽出と呼ぶものです。欲しい列名を入力すると、AIが固定位置の照合ではなく意味を理解して、ページ上のどこからでも各値を探し出します。入力した名前がそのまま出力テーブルのヘッダーになります。サプライヤーごとのテンプレートを作成しないため、サプライヤーが請求書のレイアウトを変更しても翌月の処理が止まることはありません。
データを分割する前に受入口を分ける
請求書はAPから抽出キューへ、納品書は荷卸し場から送ります。コレクションリンクを使えば、受入担当者はアカウントなしでリンクを開き、短い確認コードを入力して納品書のスマホ写真を処理キューにアップロードできます。請求書がメールで届く場合は、アカウントのEmail Inboxアドレスがサプライヤーのホワイトリストからのメールを受け取り、自動的に処理を開始できます。
台帳の言葉で列を定義する
上の表のフィールド名を使います。「Batch / Lot Code」や「Best Before」は「Product Code 2」や「Date 3」よりもモデルにとって明確で、1年後に出力ヘッダーで目にする名前でもあります。「Date Type」を推論列として追加すると、AIがラベルの文言から各日付を分類します。
1か月分を1バッチで処理する
すべてのサプライヤーの請求書をまとめてアップロードします。バッチ処理は結果を1つのスプレッドシートにマージするため、1回の実行で40個のファイルをつなぎ合わせるのではなく1つの台帳が得られます。40件の請求書(各30行)のバッチは、1つのテーブルで約1,200行になり、サプライヤー列から各行がどのレイアウト由来かを判別できます。
精度を捏造せずに日付を正規化する
フォーマットルールを使えば日付を一貫した形式で出力でき、列を並べ替え可能にできます。ドキュメントが月単位の精度しか示していない値がないか結果を確認します。03/2027と印刷された賞味期限は月のままとし、Julian codeは誰かがサプライヤーに意味を確認するまで印刷どおりに保ちます。
合計ではなくコードを確認する
bboxハイライト付きのReview Modeは、抽出された各セルを元の画像上の位置にリンクします。バッチ番号をクリックすると、その由来箇所が元の画像上でハイライトされ、請求書全体を入力し直さずにOと0を見分けられます。バッチ列と日付列を確認し、数量を抜き取り検査し、計算はAPに任せます。
POまたは納品書で台帳を生産につなげる
テーブルをExcelまたはCSVとしてエクスポートし、POまたは納品書番号を使って各バッチ行を受入記録にリンクし、AP側のために請求書番号を保持します。請求書の抽出結果がサプライヤー側を提供します。生産システムが「使用先」側を提供します。この結合がトレーサビリティ記録となります。
ファイルは安全に処理され、保存されません。
目の前の問題がトレーサビリティではなく量である場合、同じ設定がバッチ請求書のExcel変換ワークフローとしても機能し、その週次食品コスト版は食品卸の明細行を週次シートにバッチ処理する方法で解説しています。トレーサビリティ表は、集約せずにバッチ単位を保持した同じデータです。
請求書抽出が食品安全のためにできないこと
抽出はより優れた台帳を生み出します。しかしコンプライアンスを生み出すわけではなく、そうであると仮定して作成されたリコールファイルは、完成しているように見えるため、遅い手作業のものより危険です。
- トレーサビリティやコンプライアンスのシステムではありません。トレーサビリティ計画、リコールワークフロー、監査者ポータル、規制当局への申請はありません。FDAからの24時間以内の要求には、台帳を証拠として、事業者が対応しなければなりません。
- バーコードをデコードしません。AIはページ上の印刷された文字と手書き文字を読み取ります。バッチコードがGS1-128バーコードやDataMatrixラベルの中にしか存在しない場合、このワークフローでは認識できず、そのロットにはスキャナーまたはラベルシステムが必要です。
- 賞味期限を計算したりFEFOを実行したりしません。30日で期限切れになるものや、どのパレットを先に出荷すべきかを判断する日付計算機能は組み込まれていません。正規化された日付は、下流でそれらの判断を可能にしますが、判断自体は行いません。
- フォワードトレースはしません。完成品を誰が受け取ったかは出荷の事実であり、請求書の事実ではありません。請求書はチェーンのワンステップバック部分を提供し、フォワード部分には同じバッチコードに紐づく生産・出荷記録が必要です。
- 欠落を埋めません。サプライヤーがコードを省略した場合、行は空白のままで例外は可視化されたままです。これが正しい動作です。生成されたコードは、まさに必要な瞬間にサプライヤーの記録へのリンクを断ち切ります。
- サプライヤーマスタに対してコードを検証しません。チェックディジット、GS1検証、製品カタログへの照合はありません。正しく印刷されていても別の製品に属するコードは、正しく抽出され、誤ったまま残ります。
役割分担が要点です。ソフトウェアは、なじみのないレイアウトを読み取り、文字列を保持することが得意です。コードの意味、ロットが安全かどうか、誰に連絡すべきかを判断するのは、人と専門システムの役割です。それらの判断を容易にする台帳は有用です。判断しているふりをする台帳は負債です。
次のサプライヤー回収通知の前に、5分でできるテスト
5分でできるテストで、サプライヤーから聞かれる前に、自社の記録が回収に関する質問に答えられるかどうかがわかります。先月の入庫からバッチ番号を1つランダムに選び、タイマーを開始し、現在の記録だけを使って次の4つの質問に答えてください。
- このバッチはどのサプライヤー請求書で入庫し、受入日はいつですか?
- そのバッチはどれだけ入庫し、現在どれだけ在庫に残っていますか?
- どの製造ロットで使用され、どの完成ロットができましたか?
- それらの完成ロットを受け取った顧客はどこですか?
質問1と2が数秒で終わり、3と4に半日かかるなら、請求書側は機能しており、製造への紐付けが欠けています。4つすべてに半日かかるなら、問題は上流にあります。バッチ番号がそもそも記録されておらず、記録されなかったコードはいくら探しても見つかりません。どちらの結果も有用であり、どちらもサプライヤーの回収通知中に発覚するより、今発見するほうが安く済みます。回収通知時には、サプライヤーが同じ日に全顧客へ電話をかけています。
このテストは四半期ごとに、毎回異なるバッチで実施してください。失敗するコードは話し合う価値のあるサプライヤーであり、空のままの列は受入プロセスが収集していない項目です。
FAQ
すべての食品サプライヤー請求書にバッチ番号は記載されていますか?
いいえ。乳製品、食肉、生鮮青果などの腐敗しやすく規制対象のカテゴリでは通常記載されていますが、乾物では記載されないことがよくあります。ロットコードを納品書やケースラベルにのみ印字するサプライヤーもいます。請求書はすべての購入で発行される唯一の書類であるため、台帳の出発点としては適していますが、すべてのバッチ番号の信頼できる情報源ではありません。
請求書にバッチ番号がない場合はどうすればよいですか?
バッチ番号なしで受入を記録し、自社で番号を生成してサプライヤーの番号として提示するのではなく、サプライヤーに書面でコードを求めてください。自社の内部受入番号は別の列に置くことはできますが、サプライヤーの記録に存在しないため、サプライヤーのコードの代わりにはなりません。納品書やパレットラベルにコードがある場合はそれを使用し、PO番号または納品書番号を通じて請求書に紐付けてください。
バーコードからバッチ番号を読み取れますか?
バーコードの横に印刷されたコードを含め、ドキュメント上に印刷または手書きされた文字を読み取ります。バーコード自体をデコードするものではありません。コードがGS1-128やDataMatrixシンボルにのみエンコードされている場合は、バーコードスキャナーまたは倉庫システムから供給する必要があります。
3つのバッチにまたがる請求書の1行はどう処理すればよいですか?
受入時にパレットラベルまたは納品書を使って3行に分割し、各行に請求書番号と単価を繰り返し、数量を3つのコードに振り分けます。抽出はドキュメントに表示されているものしか生成できません。分割は受入側の判断であり、後からのクリーンアップではなく、テーブルを構築する前に行う必要があります。
これでFSMA 204やEU 178/2002に準拠できますか?
いいえ。これらの規則が求める記録保持を支える、構造化された並べ替え可能な記録を生成し、24時間の記録請求にも1つのテーブルから対応できるようにします。準拠にはさらに、トレーサビリティ計画、各重要追跡イベントでの記録、生産および出荷からの前方記録、EUの場合は顧客へのワンステップフォワードのリンクが必要です。抽出された台帳は構成要素の1つとして扱い、システムそのものとは考えないでください。
同じテーブルをサプライヤーの価格比較に使えますか?
はい、行レベルの詳細を保持していれば可能です。数量と単価がサプライヤーをまたいで1つのテーブルに入れば、支払った金額の比較は並べ替え1回で済みます。これは請求書から食品サプライヤーの価格を比較するで説明されているワークフローです。バッチ列はその分析を妨げず、保持しておけば同じ抽出結果が財務とQAの両方に役立ちます。
まとめ
食品のトレーサビリティは、検査室で失敗するよりもずっと前に、記録間の結合で失敗します。サプライヤー請求書はすべての購買が生み出すドキュメントであり、バッチ台帳を始めるのに適した場所ですが、そこで止めるべき場所ではありません。バッチコードは印刷されたまま取得し、物理的なバッチごとに1行を保ち、賞味期限と消費期限を分け、その結果を発注書または納品書番号で受入および生産と結合します。そうすれば、リコール通知は1週間の電話対応ではなく、スプレッドシート上のフィルターになります。
ご自身のサプライヤー請求書がバッチ台帳としてどう見えるか確認してみてください。請求書を1枚アップロードし、必要な列に名前を付け、バッチコードと日付コードがその過程を生き残るかどうかを確認しましょう。