LWP | Power Queryの関数を値として理解する
LWP TECHNICAL ARTICLE | 181
Power Queryの関数を値として理解する
関数に名前を付け、渡し、返す仕組みから、each・高階関数・クロージャーまでをつなぐ
Copyright © 2026 LWP 山中 一弘
本資料は、出典を明記いただければ、商用・非商用を問わず、ご自由に複製・改変・再配布していただけます。なお、著作権表示は改変せず、そのまま記載してご利用くださいますようお願いいたします。
記事要約
Power QueryのM言語では、関数は「呼び出して計算する命令」であるだけでなく、数値やテキストと同じく一つの値です。関数式 (x) => x * 2 を評価すると関数値が作られ、その関数値を呼び出したときに初めて関数本体が評価されます。
関数が値だからこそ、名前を付けられ、別の関数へ引数として渡せ、関数の戻り値として返せます。List.Transform や Table.SelectRows に渡している each も、実体は簡略記法で書かれた関数値です。さらに、返された関数が作成時の外側の値を参照し続ける仕組みがクロージャーです。
この記事では「入れる・渡す・返す」を別々のテクニックとして暗記せず、すべてを「関数は値である」という一つの原理から理解します。
本記事の対象とゴール
想定読者
Power Query Editorの操作から一歩進み、Mコードを読み始めた方
each や _ は使っているが、関数として説明するのが難しい方
高階関数、関数ファクトリー、クロージャーの関係を整理したい方
本記事で得られること
関数式、関数値、関数呼び出しを区別できます。
関数を名前に対応付け、引数として渡し、戻り値として返せます。
each、高階関数、クロージャーを同じ流れの中で説明できます。
はじめに 関数を実行する前に、関数そのものを見る
Excelでは、SUMやXLOOKUPのように、関数は「呼び出して結果を得るもの」として触れることが多いでしょう。
関数 + 引数 → 結果
M言語でも関数は呼び出せます。しかし、それだけではありません。MicrosoftのM言語仕様では、関数は引数の集合を一つの値へ写す「値」として定義されています。
この一文を理解すると、Power Queryで頻繁に現れる次の機能が一つにつながります。
let で関数に名前を付ける
List.Transform へ関数を渡す
each で無名関数を短く書く
関数から別の関数を返す
外側の値を保持した関数を作る
第1章 式を評価すると値が得られる
1.1 式と値を分ける
Mの中心にあるのは式です。式を評価すると一つの値が得られます。
1 + 2
この式を評価すると、number値の3になります。同様に、次の式もそれぞれ値を作ります。
"Excel"
{1, 2, 3}
[A = 1, B = 2]
上から順にtext、list、recordの値です。
1.2 関数式も値を作る
次の式も、一つの値を作ります。
(x) => x * 2
ここで作られる値の種類がfunctionです。この時点では x * 2 は実行されていません。「xを受け取り、xを2倍する」という関数値が作られただけです。
1.3 関数を作ることと呼び出すこと
作った関数へ10を渡して呼び出すと、初めて本体が評価されます。
((x) => x * 2)(10)
結果は20です。
(x) => x * 2 → function値
((x) => x * 2)(10) → number値の20
この区別が以後の土台です。
第2章 関数に名前を付ける
2.1 letは値へ名前を対応付ける
次の let 式では、number値の100へ x という名前を付けています。
let
x = 100
in
x
Mを理解するときは、値を変更可能な箱へ代入するイメージより、「名前と値を対応付ける」と考える方が自然です。
2.2 function値にも名前を付けられる
関数も値なので、同じように名前を付けられます。
let
Double = (x) => x * 2
in
Double
このクエリの結果は20ではなく、関数値です。呼び出すには引数を渡します。
let
Double = (x) => x * 2,
Result = Double(10)
in
Result
結果は20です。
2.3 名前付き関数は特別扱いではない
次の対応は、すべて同じ 名前 = 式 の仕組みです。
let
Count = 100,
Message = "Hello",
Items = {1, 2, 3},
Double = (x) => x * 2
in
[Count = Count, Message = Message, Items = Items, Double = Double]
名前付き関数だけを特別な宣言として覚える必要はありません。function値へ名前を付けているだけです。
第3章 関数を別の関数へ渡す
3.1 List.Transformの第2引数
List.Transform は、リストの各要素へ変換関数を適用します。
List.Transform(
{1, 2, 3},
(item) => item * 10
)
結果は {10, 20, 30} です。第1引数はlist値、第2引数はfunction値です。
List + Function → 新しいList
このように関数を引数として受け取ったり、関数を返したりする関数を高階関数と呼びます。
3.2 名前付き関数を渡す
関数へ先に名前を付けても、意味は変わりません。
let
Multiply10 = (item) => item * 10,
Result = List.Transform({1, 2, 3}, Multiply10)
in
Result
ここでは Multiply10 と Multiply10(10) を区別します。
Multiply10 → 関数そのもの
Multiply10(10) → 関数を実行した結果100
List.Transform が必要としているのは、各要素へ適用する関数そのものです。
3.3 処理対象と処理方法を分離する
関数を渡せると、次の二つを分けられます。
何を処理するか → {1, 2, 3}
どう処理するか → (item) => item * 10
Power Queryの標準関数には、この形が数多く現れます。関数を値として理解すると、引数の意味を読み取りやすくなります。
第4章 eachは関数を短く書く構文
4.1 eachを通常の関数式へ展開する
次の式は、Power Queryでよく見かけます。
List.Transform({1, 2, 3}, each _ * 10)
Microsoftの説明では、each ... は _ を引数に取る関数式の簡略記法です。
each _ * 10
は、次の式に相当します。
(_) => _ * 10
したがって each は「各要素について実行する命令」そのものではありません。その位置で必要なfunction値を短く作る構文です。
4.2 Table.SelectRowsでも同じ
Table.SelectRows(
Source,
each [売上] >= 10000
)
概念的には、次のように読めます。
Table.SelectRows(
Source,
(row) => row[売上] >= 10000
)
第2引数は、1行を受け取り、その行を残すならtrue、除くならfalseを返す関数です。
Table
+ 行を残すか判定するFunction
→ 絞り込まれたTable
each の意味が分からなくなったら、「この場所では、何を受け取って何を返す関数が必要なのか」と問い直します。
第5章 関数から関数を返す
5.1 戻り値にfunction値を選べる
関数が値なら、関数の戻り値にもできます。
(x) => (y) => x + y
外側の関数はxを受け取り、数値ではなく (y) => x + y という新しい関数を返します。
5.2 加算関数を作る関数
let
MakeAdder = (x) => (y) => x + y,
Add10 = MakeAdder(10),
Result = Add10(5)
in
Result
評価の流れは次のとおりです。
MakeAdder(10)
↓
10を加えるfunction値
↓
Add10
↓
Add10(5) = 15
同じ仕組みで Add100 = MakeAdder(100) も作れます。このように設定の異なる関数を作る関数は、関数ファクトリーとして利用できます。
第6章 クロージャーは外側の環境を保持する
6.1 固定値を閉じ込めた関数
税率や換算率を先に与え、後から値へ適用する例を考えます。
let
MakeMultiplier =
(rate as number) as function =>
(value as number) as number =>
value * rate,
TaxIncluded = MakeMultiplier(1.1),
Result = TaxIncluded(100)
in
Result
MakeMultiplier(1.1) の呼び出しが終わった後でも、返された TaxIncluded は rate = 1.1 を参照できます。
MicrosoftのM言語仕様では、関数本体は、関数が初期化されたときの環境にある変数を参照できます。関数と、その関数が参照する外側の環境を組み合わせたものがクロージャーです。
6.2 「関数を返す」と「クロージャー」は同義ではない
関数を返すだけなら、必ずしも外側の値を利用するとは限りません。クロージャーとして重要なのは、返された関数が作成時の環境にある値を参照し続けることです。
関数を返す → 戻り値の種類がfunction
クロージャー → 関数が作成時の外側の環境を参照する
両者を分けておくと、部分適用や関数生成を過度に難しく考えずに済みます。
第7章 実務コードを読むための判断順序
Mコードで関数らしい式に出会ったら、次の順に確認します。
その式はfunction値を作っているのか、関数を呼び出しているのか。
関数は何を引数として受け取るのか。
関数は何を返すのか。
その関数は名前に対応付けられているのか、別の関数へ渡されているのか。
外側の変数を参照しているなら、何を閉じ込めているのか。
たとえば、次の式を見ます。
(rate) => each _ * rate
each を展開すれば、構造が明確になります。
(rate) => (value) => value * rate
外側はrateを受け取り、valueを受け取る新しい関数を返します。内側の関数は外側のrateを参照します。
まとめ 入れる・渡す・返すは一つの原理
Mでは、式を評価すると一つの値が得られます。
関数式を評価するとfunction値が作られ、呼び出したときに関数本体が評価されます。
関数が値だから、名前を付けられ、引数として渡せ、戻り値として返せます。
each ... は (_) => ... の簡略記法であり、function値を作ります。
関数を受け取る、または返す関数が高階関数です。
作成時の外側の環境を参照し続ける関数がクロージャーです。
ExcelからPower Queryへ進むと、関数を「計算を実行するもの」としてだけ見てしまいがちです。しかしMコードを読み解く鍵は、呼び出す前の関数そのものを値として見ることです。
functionも値
↓
名前を付けられる
↓
引数として渡せる
↓
戻り値として返せる
↓
外側の環境を保持できる
この一本の流れが見えれば、each、高階関数、関数ファクトリー、クロージャーは別々の暗記事項ではなくなります。
参考資料
Microsoft Learn「Power Query M formula language introduction」
Microsoft Learn「Understanding Power Query M functions」
Microsoft Learn「M Language Functions」
Microsoft Learn「M Language values」
出典メモ
元原稿: C:\Users\hoehoe\Downloads\記事ネタmd\Power Queryの関数は値である――関数を変数に入れ、渡し、返す.md
元原稿は末尾が「ExcelからPower Query」で途切れていたため、既存の章と主張だけを根拠に、まとめを補完しました。
関数値、関数式の評価、each の展開、クロージャーの説明は、2026年8月21日にMicrosoft公式仕様で確認しました。
公式資料: https://learn.microsoft.com/en-us/powerquery-m/m-spec-introduction
公式資料: https://learn.microsoft.com/en-us/powerquery-m/understanding-power-query-m-functions
公式資料: https://learn.microsoft.com/en-us/powerquery-m/m-spec-functions
公式資料: https://learn.microsoft.com/en-us/powerquery-m/m-spec-values
