Excelの検索条件をPower QueryのM関数として注入する
~検索画面とPower Queryを名前定義セルでつなぐ、構造化条件注入の設計~
Copyright © 2026 LWP 山中 一弘
本資料は、出典を明記いただければ、商用・非商用を問わず、ご自由に複製・改変・再配布していただけます。なお、著作権表示は改変せず、そのまま記載してご利用くださいますようお願いいたします。
記事要約
Power Queryの検索条件を利用者ごと、実行ごとに変えたい場合、Mコードを毎回編集させる運用は現実的ではありません。Excelの検索画面で項目名、演算子、値、and / or を選び、その結果をM言語の行判定関数としてPower Queryへ渡せれば、利用者はワークシートだけで検索条件を変更できます。
この記事では、Excelの構造化された条件をM関数リテラルへ変換し、名前定義セルから Excel.CurrentWorkbook、Expression.Evaluate、Table.SelectRows へ渡す方式を説明します。この方式を「Excel条件UI-M述語関数注入方式」と呼びます。
結論は、任意のMコードを利用者に書かせるのではなく、許可した項目、演算子、データ型から行判定関数だけを生成することです。これにより、Power Queryの処理本体と検索条件を分離しながら、型違い、文字列の引用、過大な評価権限といった問題も管理できます。
本記事の対象とゴール
想定読者
ExcelとPower Queryを組み合わせた業務ブックを作っている人
VBAからPower Queryの更新を制御している人
検索画面の条件をMコードへ反映したい人
Expression.Evaluate を使うべき範囲と注意点を知りたい人
本記事で得られること
Excelの条件入力から Table.SelectRows までの受け渡し構造を説明できるようになります。
Mの真偽式ではなく、行を受け取るfunctionを渡す理由が分かります。
項目名、値、演算子、評価環境を安全に扱う設計判断が分かります。
1セルの名前定義を使った最小例を自分のブックで再現できます。
1. Excel画面からMコードを変えるという考え方
Power Queryでは、通常は詳細エディターにMコードを書きます。しかし、検索条件が毎回変わる業務では、固定したMコードだけでは対応しにくくなります。
例えば、利用者がExcel画面で次の条件を指定するとします。
売上年月が202401以上
売上年月が202412以下
金額が100000以上
すべての条件を and で結ぶ
この条件は、M言語では次の行判定関数として表現できます。この文字列は、後で名前定義セルへ書き込む値です。
(_)=>([売上年月] >= 202401 and [売上年月] <= 202412) and ([金額] >= 100000)このコードを使う目的は、テーブルの各行について、条件に一致するかをtrueまたはfalseで返すことです。成功時には、該当する期間かつ10万円以上の行だけが残ります。
2. 方式を4つの役割に分ける
この方式は、Excel、条件生成処理、受け渡し場所、Power Queryの4つに分けて考えると理解しやすくなります。
2.1 Excelは条件入力画面になる
利用者は、項目名、演算子、値、論理演算子をワークシートへ入力します。項目名と演算子は入力規則のリストから選ばせます。値だけを自由入力にする場合でも、項目ごとに数値、文字列、日付などの型を決めておきます。
2.2 VBAまたはMが条件をコンパイルする
入力された条件を、そのまま文字列連結するのではなく、許可された規則に従ってMの関数リテラルへ変換します。この変換処理は、画面入力をM言語へ翻訳する小さなコンパイラーです。
2.3 名前定義セルが受け渡し場所になる
生成したM関数リテラルを、例えば 検索条件_M関数 という名前を付けた1セルへ書き込みます。Power Queryは、セル番地ではなく名前を使って値を取得します。
2.4 Power Queryが評価して実行する
Power Queryは名前定義セルから文字列を取得し、Expression.Evaluate でfunction値へ変換します。最後に、そのfunctionを Table.SelectRows へ渡します。
3. 最小構成を作る
ここでは、同じブック内にあるExcelテーブルを検索する最小構成を作ります。対象環境は、Power Queryを利用できるWindows版Excelです。
3.1 Excel側に2つの名前を用意する
最初に、検索対象データをExcelテーブルにし、テーブル名を 検索対象 とします。例では 売上年月、金額、商品名 の列があるものとします。
次に、空いているセルを1つ選び、名前ボックスまたは名前の管理から 検索条件_M関数 という名前を付けます。そのセルへ、先ほどの (_)=> で始まる文字列を入力します。
3.2 Power Queryで名前定義セルを読む
次のコードを新しい空のクエリの詳細エディターへ入力します。クエリ名は 検索結果 とします。このコードは、名前定義セルの文字列をfunctionへ変換し、Excelテーブル 検索対象 を絞り込みます。
let 条件セル = Excel.CurrentWorkbook(){[Name = "検索条件_M関数"]}[Content], 条件文字列 = Text.From(条件セル{0}[Column1]), 評価環境 = Record.SelectFields( #shared, {"Text.Contains"}, MissingField.Ignore ), 条件関数 = Expression.Evaluate(条件文字列, 評価環境), 確認済み条件関数 = if 条件関数 is function then 条件関数 else error "検索条件が行判定関数ではありません。", 検索対象 = Excel.CurrentWorkbook(){[Name = "検索対象"]}[Content], 検索結果 = Table.SelectRows(検索対象, 確認済み条件関数)in 検索結果クエリを更新し、指定期間かつ指定金額以上の行だけが残れば成功です。エラーになった場合は、名前定義の名称、列名、値の型、条件文字列の括弧を確認します。
3.3 VBAから条件を書き込む
次のVBAは、最小例の条件関数を名前定義セルへ書き込み、検索結果クエリの接続を更新します。接続名はブックによって異なるため、実際の接続名に合わせてください。
Option ExplicitPublic Sub 検索条件を注入して更新する() Const XM_PREDICATE As String = _ "(_)=>([売上年月] >= 202401 and [売上年月] <= 202412)" & _ " and ([金額] >= 100000)" ThisWorkbook.Names("検索条件_M関数").RefersToRange.Value = _ XM_PREDICATE ThisWorkbook.Connections("クエリ - 検索結果").RefreshEnd Subこのマクロの目的は、注入経路の動作確認です。実務版では、定数で条件を書くのではなく、検索画面から読み取った条件を専用の生成関数で組み立てます。マクロ実行後、名前定義セルの文字列と検索結果の両方を確認します。
4. なぜ真偽式ではなくfunctionを渡すのか
Table.SelectRows の第2引数は、テーブル全体に対する1つのtrueまたはfalseではありません。各行を受け取り、その行を残すかどうかを返すfunctionです。
そのため、次の条件本体だけでは不足します。
[金額] >= 100000行を受け取る関数にすると、Table.SelectRows が各行へ繰り返し適用できます。
(_)=>[金額] >= 100000Mでよく使う each [金額] >= 100000 も同じ役割です。動的に文字列として受け渡す場合は、(_)=> の形にすると関数であることが明示されます。
5. 検索画面を構造化する


実務用の検索画面では、条件を単なる自由記述欄にしません。1条件を「項目名、演算子、値」の組として扱います。
同じグループ内の条件は and で結びます。複数グループを作る場合は、グループ間の and または or を別の入力欄で指定します。例えば、1行目に期間の下限と上限、2行目に金額条件を置けば、画面のまとまりと生成される括弧のまとまりを対応させられます。
演算子は、少なくとも次のような許可リストから選択させます。
=
<>
>
<
>=
<=
含む。Mでは Text.Contains に変換する
VBAの関数名も、実際の役割に合わせます。グループ間が or 固定でないなら、「Or条件生成」ではなく「条件グループ結合」のような名前にしたほうが誤解を防げます。
6. 方式として確立するための安全規則
6.1 項目マスタにデータ型を持たせる
Excelセルが数値に見えるかどうかだけで、Mの数値リテラルか文字列リテラルかを決めてはいけません。社員番号、商品コード、年月のように、見た目は数字でも文字列として管理する列があります。
項目マスタには、表示名、M列名、Mデータ型、使用可能な演算子を持たせます。Mデータ型は number、text、date、datetime、logical などです。
6.2 識別子と値を単純連結しない
列名に空白、演算子、引用符などが含まれる場合は、Mの引用識別子が必要です。文字列値の中に引用符や改行がある場合も、Mの文字列リテラルとして正しく表現しなければなりません。
条件式をM側で生成できる場合は、Expression.Identifier と Expression.Constant を使うと、識別子と値をMソースとして表現できます。次のコードは、空白を含む列名と引用符を含む文字列から、安全な条件関数文字列を作ります。
let 項目名 = "商品 名", 検索値 = "A ""ランク""", 項目式 = "[" & Expression.Identifier(項目名) & "]", 値式 = Expression.Constant(検索値), 条件文字列 = "(_)=>" & 項目式 & " = " & 値式in 条件文字列VBAでM文字列を生成する場合も、同じ引用規則を実装した専用関数とテストが必要です。画面値を直接 "[" & 項目名 & "]" のように連結するだけでは、汎用方式としては不十分です。
6.3 演算子を対応表から変換する
利用者が入力した文字列を演算子としてそのまま埋め込まず、許可済みの対応表を使います。特に 含む は二項演算子ではないため、Text.Contains([列], 値) という関数呼出しへ変換します。
6.4 評価環境を限定する
Expression.Evaluate(条件文字列, #shared) とすると、共有環境にある多くの関数を条件式から参照できます。管理された社内ブックでは動作しますが、方式として公開・再利用するなら、必要な関数だけを含むenvironmentへ限定します。
この記事の最小例では、文字列の部分一致に必要な Text.Contains だけを選択しています。比較演算子、数値リテラル、文字列リテラル、行フィールド参照はMの構文なので、environmentへ個別登録する必要はありません。
6.5 条件関数は一度だけ評価する
複数の月次テーブルへ同じ条件を適用する場合、テーブルごとに Expression.Evaluate を呼ぶ必要はありません。最初に一度だけfunctionを生成し、同じfunctionを各 Table.SelectRows へ渡します。
各テーブルを絞り込んでから Table.Combine すれば、結合後に全件を絞り込むより中間行数を抑えられます。ただし、すべてのテーブルで列名とデータ型が一致していることが前提です。
6.6 エラーを利用者へ返す
条件が空、項目名が存在しない、値の型が合わない、条件文字列がfunctionではない、更新中に再実行した、といった状態を区別します。Power Queryのエラーをそのまま見せるだけでなく、どの条件を直せばよいかをExcel画面へ返す設計が必要です。
7. この方式が向く範囲
この方式は、項目、演算子、値、論理演算子で表せる検索に向きます。複数ファイルや複数テーブルに対して、同じ条件を適用する業務検索画面では特に有効です。
一方で、結合方法、集計方法、追加列、外部データソースまで利用者が自由に変更する用途には向きません。その場合は、用途別のクエリを分ける、条件定義テーブルをM関数が直接解釈する、または専用アプリケーションにするほうが管理しやすくなります。
判断基準は、動的にする対象を「行を残すかどうか」に限定できるかです。限定できるなら、述語関数だけを注入するこの方式は、Power Query本体を固定したまま検索条件を外出しできます。
8. まとめ
ExcelからPower Queryへ検索条件を渡すときは、値を1つ渡すだけでなく、行を判定するMのfunctionを渡すことができます。Excel画面を入力層、条件生成処理をコンパイル層、名前定義セルを受け渡し層、Power Queryを実行層として分けると、方式の責任が明確になります。
ただし、成立の中心は Expression.Evaluate そのものではありません。利用者の入力を構造化し、項目型と演算子を制限し、識別子と値を正しく表現し、評価できる範囲を限定することが中心です。
この境界を守れば、Power Queryエディターを利用者に触らせず、Excelの検索画面から再利用可能なM条件関数を供給できます。
出典メモ
ほえほえ作成の業務用Excelマクロブックを2026-08-01に確認した。顧客名、ブック名、固有の業務項目、実データは掲載していない。
Microsoft Learn: Expression.Evaluate - https://learn.microsoft.com/en-us/powerquery-m/expression-evaluate
Microsoft Learn: Table.SelectRows - https://learn.microsoft.com/en-us/powerquery-m/table-selectrows
Microsoft Learn: Excel.CurrentWorkbook - https://learn.microsoft.com/en-us/powerquery-m/excel-currentworkbook
Microsoft Learn: Expression.Identifier - https://learn.microsoft.com/en-us/powerquery-m/expression-identifier
Microsoft Learn: Expression.Constant - https://learn.microsoft.com/en-us/powerquery-m/expression-constant
Microsoft Learn: Power Query M language specification - https://learn.microsoft.com/en-us/powerquery-m/power-query-m-language-specification
確認範囲: 元ブックは静的に読み戻した。検索ボタンの実行と外部データの再評価は行っていない。記事のコードは、方式説明のために匿名化して作り直した独自例である。
