実務で使えるPower Query小技・テクニック | 無名関数を使う

Excel VBA Power Query M Formula Language
スポンサーリンク
スポンサーリンク

無名関数とは何か

Power Query(M言語)で「無名関数を使う」とは、関数に名前を付けず、その場で“使い捨ての関数”を書くことを指します。 通常の関数は MyFunc = (x) => ... のように名前を付けますが、無名関数は単に (x) => ... と書いて、その場で Table.AddColumn などに渡して使います。

実務では、

  • その場だけで使う簡単な処理
  • 列ごとの変換ロジック
  • フィルタ条件やフラグ判定 などに無名関数が頻繁に登場します。

「関数を作る」より一歩進んだテクニックですが、仕組みはシンプルですので、ステップバイステップでかみ砕いて見ていきます。

M言語の無名関数の基本構文

(引数) => 式 をそのまま書く

無名関数の基本形は、次のようになります。

(x as number) as number => x * 2
Power Query

これだけだと「ただの関数の形」ですが、 これを 名前を付けずに、その場で別の関数に渡して使うのが無名関数です。

例えば、Table.AddColumn の中で使うとこうなります。

let
    SalesTable = Excel.CurrentWorkbook(){[Name="売上"]}[Content],

    AddedDoubleAmount =
        Table.AddColumn(
            SalesTable,
            "金額2倍",
            each (x as number) as number => x * 2 ([金額]),
            type number
        )
in
    AddedDoubleAmount
Power Query

ただ、M言語ではもっとよく使われる書き方があります。

無名関数と each の関係

each は「無名関数の省略記法」です

Power Query でよく見る each は、実は 無名関数の短縮形です。

each [金額] * 2
Power Query

これは、次の無名関数とほぼ同じ意味です。

(row as record) as any => row[金額] * 2
Power Query

つまり、

  • each:その場で「行(row)」を受け取る無名関数を書くためのキーワード
  • [金額]:その行の「金額」列
  • * 2:その値を2倍にする処理

という構造になっています。

初心者の方は、「each は“行を受け取る無名関数”の省略記法」と覚えると理解しやすくなります。

無名関数をステップバイステップで理解する

ステップ1:通常の関数と無名関数の違いを押さえる

通常の関数:

let
    Double =
        (x as number) as number =>
            x * 2
in
    Double
Power Query

無名関数(名前なし):

(x as number) as number => x * 2
Power Query

違いは「名前があるかないか」だけです。 無名関数は、その場でしか使わない処理を簡潔に書くためのものです。

ステップ2:Table.AddColumn で無名関数を使う

最もよく使うパターンは、列追加のときです。

let
    SalesTable = Excel.CurrentWorkbook(){[Name="売上"]}[Content],

    AddedTaxAmount =
        Table.AddColumn(
            SalesTable,
            "消費税額",
            each [金額] * 0.1,
            type number
        )
in
    AddedTaxAmount
Power Query

ここでの each [金額] * 0.1 が、無名関数です。

「各行を受け取って、その行の金額に 0.1 を掛ける」という処理を、 名前を付けずにその場で書いています。

ステップ3:Table.SelectRows で無名関数を使う

フィルタ条件にも無名関数が使われます。

let
    SalesTable = Excel.CurrentWorkbook(){[Name="売上"]}[Content],

    HighAmountThreshold = 1000,

    FilteredHighAmount =
        Table.SelectRows(
            SalesTable,
            each [金額] > HighAmountThreshold
        )
in
    FilteredHighAmount
Power Query

ここでの each [金額] > HighAmountThreshold が無名関数です。

「各行を受け取って、その行の金額が閾値より大きいかどうかを判定する」という処理を、 その場で書いています。

無名関数をもう少し“素の形”で見る

each を使わずに書くとどうなるか

each [金額] * 2 は、実は次のような形に展開できます。

(row as record) as any => row[金額] * 2
Power Query

Table.AddColumn に渡すときは、こういうイメージです。

let
    SalesTable = Excel.CurrentWorkbook(){[Name="売上"]}[Content],

    AddedDoubleAmount =
        Table.AddColumn(
            SalesTable,
            "金額2倍",
            (row as record) as number => row[金額] * 2,
            type number
        )
in
    AddedDoubleAmount
Power Query

each を使うと短く書けるので、 実務ではほとんど each で書きますが、 「裏側では無名関数が動いている」と理解しておくと、M言語の仕組みがぐっと分かりやすくなります。

無名関数を使うときの重要な注意点

1. ロジックが複雑になりすぎないようにする

無名関数は「その場で書ける」のが便利ですが、 あまり複雑な処理を詰め込みすぎると、読みづらくなります。

悪い例:

each
    if [顧客コード] <> null and [金額] <> null and [金額] > 0 and Text.Length([顧客コード]) > 3 then
        [金額] * 1.1
    else
        null
Power Query

良い例:関数に切り出す

let
    CalcAdjustedAmount =
        (row as record) as nullable number =>
            let
                hasCustomer =
                    (row[顧客コード] <> null and Text.Length(row[顧客コード]) > 3),
                hasPositiveAmount =
                    (row[金額] <> null and row[金額] > 0)
            in
                if hasCustomer and hasPositiveAmount then
                    row[金額] * 1.1
                else
                    null,

    SalesTable = Excel.CurrentWorkbook(){[Name="売上"]}[Content],

    AddedAdjustedAmount =
        Table.AddColumn(
            SalesTable,
            "調整後金額",
            each CalcAdjustedAmount(_),
            type nullable number
        )
in
    AddedAdjustedAmount
Power Query

無名関数は「簡単な処理」に向いていて、複雑なロジックは名前付き関数に切り出した方が安全で読みやすいです。

2. null や型の扱いを意識する

無名関数の中でも、null や型の扱いは重要です。

each
    if [金額] = null then
        null
    else
        [金額] * 0.1
Power Query

このように、

  • null の場合の挙動
  • 計算対象の型(数値かどうか)

を意識して書くことで、 予期せぬエラーや不正な結果を防げます。

3. セキュリティ・品質に関わる処理は無名関数に詰め込みすぎない

例えば、権限チェックや品質チェックを無名関数の中に直接書くと、 後から見直しづらくなります。

悪い例:

Table.SelectRows(
    UserTable,
    each [Role] = "Admin" and [IsActive] = true
)
Power Query

良い例:関数に切り出す

let
    IsActiveAdmin =
        (row as record) as logical =>
            (row[Role] = "Admin" and row[IsActive] = true),

    FilteredAdmins =
        Table.SelectRows(
            UserTable,
            each IsActiveAdmin(_)
        )
in
    FilteredAdmins
Power Query

セキュリティに関わるロジックは、 関数として名前を付けておき、レビューしやすく・変更しやすい形にしておくことが大切です。

実務で使える「無名関数」テンプレート

テンプレ1:列追加での簡単な計算

let
    SalesTable = Excel.CurrentWorkbook(){[Name="売上"]}[Content],

    TaxRate = 0.1,

    AddedTaxAmount =
        Table.AddColumn(
            SalesTable,
            "消費税額",
            each [金額] * TaxRate,
            type number
        )
in
    AddedTaxAmount
Power Query

テンプレ2:フィルタ条件としての無名関数

let
    SalesTable = Excel.CurrentWorkbook(){[Name="売上"]}[Content],

    HighAmountThreshold = 1000,

    FilteredHighAmount =
        Table.SelectRows(
            SalesTable,
            each [金額] > HighAmountThreshold
        )
in
    FilteredHighAmount
Power Query

テンプレ3:フラグ列の追加

let
    SalesTable = Excel.CurrentWorkbook(){[Name="売上"]}[Content],

    AddedValidFlag =
        Table.AddColumn(
            SalesTable,
            "有効行",
            each ([顧客コード] <> null and [顧客コード] <> "" and [金額] <> null and [金額] > 0),
            type logical
        )
in
    AddedValidFlag
Power Query

まとめ:無名関数を使うことは「その場で小さなロジックを書くこと」

M言語で無名関数を使うというのは、 「その場で小さな処理を関数として書き、Table系関数に渡して柔軟な変換や判定を行うこと」です。

これによって、

  • 列追加・フィルタ・フラグ判定をコンパクトに書ける
  • each を使った“行ごとの処理”を直感的に表現できる
  • コードの再利用とその場の記述をバランスよく使い分けられる

というメリットが得られます。

無名関数は、Power Queryの「現場感のある書き方」の中心にあるテクニックですので、 ぜひ「each は無名関数の省略形」「簡単な処理は無名関数、複雑な処理は名前付き関数」という感覚を身につけて、 実務のクエリをより読みやすく・安全に育てていっていただきたいです。

タイトルとURLをコピーしました