Power Queryの関数を値として理解する

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 や _ は使っているが、関数として説明するのが難しい方

  • 高階関数、関数ファクトリー、クロージャーの関係を整理したい方

本記事で得られること

  1. 関数式、関数値、関数呼び出しを区別できます。

  2. 関数を名前に対応付け、引数として渡し、戻り値として返せます。

  3. 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