Power Query ExcelでExpression.Error: The key didn't match any rows in the tableを修正する

intermediate📊 Microsoft Excel2026-05-16| Microsoft Excel 2016/2019/2021/365、Power Query エディター、Windows 10/11

Error Message

Expression.Error: The key didn't match any rows in the table.
#power-query#excel#expression-error#merge#lookup

TL;DR

Power Queryがキーを検索したが何も見つからず、nullを返す代わりにエラーをスローしました。十中八九、原因はデータ型の不一致です。一方の列がtext型で、もう一方がnumber型やdate型になっています。マージまたはルックアップの手順の前に、両側を同じ型にキャストすればエラーは解消されます。

このエラーが発生する箇所

エラーは一か所だけでなく、複数の場所で表面化することがあります:

  • Mコード内でTable.SelectRowsまたはRecord.Fieldを使った手動ルックアップ
  • クエリのマージステップ後にネストされたテーブル列をドリルダウンする場合
  • 行インデックスのルックアップパターン:lookupTable{[ID = someValue]}
  • 特定の行をキーで参照するカスタムM関数

根本原因

Mの構文tableName{[ColumnName = value]}は、一致する行がちょうど1行あることを期待します。0行の場合はエラー、2行以上の場合もエラーになります。組み込みのフォールバック処理は存在しません。

厄介な点は、ルックアップが型に敏感であることです。文字列"123"と数値123はセル上では同じに見えますが、Power Queryにとっては全く異なるものです。この型の不一致は静かにマッチを失敗させます。その他のよくある原因:

  • ソースデータが更新され、以前は有効だったキーが削除またはリネームされた
  • 一方の列に先頭または末尾の空白が含まれている(CSVインポートでよく見られる)
  • テキストとして保存された日付("2024-01-15")と実際のdate型の値
  • Mコード内の列名のタイポ — 列名は大文字・小文字を区別する

修正1:両側のデータ型を一致させる

詳細エディターを開いてルックアップの行を見つけます。比較の前に両側を同じ型に強制変換します:

// 修正前 — 一方のテーブルでIDが数値、もう一方でテキストの場合に失敗する
let
    result = lookupTable{[ID = sourceID]}[Value]
in
    result

// 修正後 — すべてをまずテキストにキャストする
let
    safeID = Text.From(sourceID),
    safeTable = Table.TransformColumnTypes(lookupTable, {{"ID", type text}}),
    result = safeTable{[ID = safeID]}[Value]
in
    result

キーが常に数値(注文IDや従業員番号など)の場合は、代わりに数値にキャストします:

let
    numID = Number.From(sourceID),
    numTable = Table.TransformColumnTypes(lookupTable, {{"ID", type number}}),
    result = numTable{[ID = numID]}[Value]
in
    result

修正2:try…otherwise を使って存在しないキーを適切に処理する

すべてのソース行が一致するとは限りません — 実際のデータでは普通のことです。クエリをクラッシュさせる代わりに、ルックアップをtryでラップします:

let
    safeLookup = try lookupTable{[ID = sourceID]}[Value] otherwise null
in
    safeLookup

キーが存在しない場合はエラーではなくnullが返されます。ExcelのIFERROR関数でラップするのと同じ考え方です。データを読み込んだ後、nullの行をフィルタリングして、どのキーが一致しなかったかを確認できます。

修正3:比較前に空白をトリムする

CSVのエクスポートやコピー&ペーストしたデータには、目に見えないスペースが含まれていることで有名です。"ABC ""ABC"は同じキーではありません。両側をトリムします:

let
    cleanSource = Table.TransformColumns(sourceTable, {{"ID", Text.Trim}}),
    cleanLookup = Table.TransformColumns(lookupTable, {{"ID", Text.Trim}}),
    merged = Table.NestedJoin(
        cleanSource, "ID",
        cleanLookup, "ID",
        "LookupResult", JoinKind.LeftOuter
    )
in
    merged

修正4:ルックアップの前にキーの存在を検証する

キーパラメーターを受け取るカスタム関数内では、前提とするのではなく先に存在確認を行います:

(inputID as text) =>
let
    matches = Table.SelectRows(lookupTable, each [ID] = inputID),
    result = if Table.RowCount(matches) > 0
             then matches{0}[Value]
             else "KEY NOT FOUND"
in
    result

Table.SelectRowsは何も一致しない場合に空のテーブルを返します — エラーはスローされません。行インデックス構文{[ID = ...]}にはこの安全策がないため、ユーザー向けのクエリにはこのパターンの方が堅牢です。

修正5:UIでマージの結合タイプを確認する

クエリのマージダイアログを使用していて、マージされた列を展開したときにのみエラーが表示される場合、結合タイプが間違っている可能性があります:

  • 適用したステップでマージステップをクリックする
  • 結合の種類の設定を確認する — *内部結合(Inner Join)*は一致しない行を静かに削除するため、すべての行が存在することを前提とした後続のステップが壊れる
  • **左外部結合(Left Outer Join)**に切り替えて、すべてのソース行を保持する(一致しない行のルックアップ列はnullになる)
  • 必要に応じて、除外するためにnullを後でフィルタリングする

確認手順

修正を適用した後、以下を実行してください:

  • Power Query エディターでプレビューの更新をクリックする — 赤いエラーバナーが消えているはず
  • キー列の横にある型アイコンを確認する — 両方ともABC(テキスト)または123(数値)と表示されており、混在していないこと
  • クイック診断ステップを追加する:= Table.RowCount(lookupTable)でテーブルに行が読み込まれているか確認する(ゼロ行は多くある落とし穴)
  • 閉じて読み込み、出力行数が期待値と一致するか比較する
  • try...otherwise nullを使用した場合、結果列にフィルターを追加してnull行を抽出する — それらが調査すべき不一致キー

クイック診断チェックリスト

  • [ ] キー比較の両側で同じデータ型になっているか?
  • [ ] キー値に先頭または末尾のスペースが潜んでいないか?
  • [ ] クエリが最初に作成された後にソースデータが変更されたか?
  • [ ] ルックアップテーブルがゼロ行を読み込んでいないか?
  • [ ] 本当は左外部結合が必要なのに内部結合を使用していないか?
  • [ ] Mコードでキー列名のスペルと大文字・小文字が正しいか?

Related Error Notes