実務で使えるPower Query小技・テクニック | _ の意味を理解する

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

_(アンダースコア)の正体を一言でいうと何か

Power Query(M言語)で使われる _ は、「無名関数の引数として自動的に渡される“現在の値”を表す特別な変数」です。 もっと噛み砕くと、

_ は “今まさに処理している値そのもの” を指す記号

だと理解すると一気に分かりやすくなります。

ただし、ここでいう「値」は、

  • 行全体(record)
  • 列のセル値
  • リストの要素 など、使う関数によって変わります。

つまり、_ は「その場で処理対象になっているもの」を指す万能の“現在値”変数なのです。

_ は「無名関数の引数」の省略記法

無名関数の“素の形”を先に見てみる

まず、無名関数を普通に書くとこうなります。

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

ここでの x が「引数」です。 この関数をリストに適用すると、各要素が2倍になります。

List.Transform({1,2,3}, (x as number) => x * 2)
Power Query

これを _ を使って書くとこうなります。

List.Transform({1,2,3}, each _ * 2)
Power Query

つまり、

  • _ は「無名関数の引数」
  • each _ * 2 は「(x) => x * 2」の省略形

という関係になります。

ステップバイステップで _ の意味を理解する

ステップ1:_ は「今処理している値」を指す

例:リストの各要素を2倍にする

List.Transform({1,2,3}, each _ * 2)
Power Query

ここでの _ は、

  • 1回目:1
  • 2回目:2
  • 3回目:3

というように、リストの各要素そのものを指します。

ステップ2:テーブルの列変換では「セルの値」を指す

Table.TransformColumns の中で使う _ は、 その列のセル値を指します。

Table.TransformColumns(
    SalesTable,
    {
        {
            "顧客名",
            each Text.Upper(_),
            type text
        }
    }
)
Power Query

ここでの _ は、

  • 「顧客名」列の各セルの値 を指します。

つまり、

行ではなく “列のセル値” を処理する場面では _ が使われる

ということです。

ステップ3:行全体を扱う場合は _ が「行(record)」になる

Table.AddColumnTable.SelectRows の each の中では、 _ は行全体(record)を指します。

例:

Table.AddColumn(
    SalesTable,
    "金額2倍",
    each _[金額] * 2,
    type number
)
Power Query

ここでの _ は、

  • 行全体(record) であり、
  • _ [金額] でその行の金額列を参照しています。

つまり、

_ は「行を表す record」になることもある

ということです。

_ の意味は「使う関数によって変わる」

代表的な関数と _ の意味の対応表

関数_ が指すもの
List.Transformリストの各要素_ * 2
Table.TransformColumns列のセル値Text.Upper(_)
Table.AddColumn行全体(record)_ [金額] * 2
Table.SelectRows行全体(record)_ [金額] > 1000

この表を覚えておくと、 「今この _ は何を指しているのか?」 が迷わなくなります。

_ を使った実務的な例

例1:リストの値を加工する(_ は要素)

let
    Numbers = {1, 2, 3},
    Doubled = List.Transform(Numbers, each _ * 2)
in
    Doubled
Power Query

例2:列の値をクレンジングする(_ はセル値)

Table.TransformColumns(
    SalesTable,
    {
        {
            "顧客コード",
            each Text.Upper(Text.Trim(_)),
            type text
        }
    }
)
Power Query

例3:行全体を使って判定する(_ は record)

Table.SelectRows(
    SalesTable,
    each _[金額] <> null and _[金額] > 1000
)
Power Query

例4:行全体を関数に渡す(_ は record)

Table.AddColumn(
    SalesTable,
    "有効行",
    each IsValidRow(_),
    type logical
)
Power Query

_ を使うときの重要な注意点

1. _ が「行」なのか「セル値」なのかを必ず意識する

間違いやすい例:

Table.AddColumn(
    SalesTable,
    "顧客名大文字",
    each Text.Upper(_)
)
Power Query

これはエラーになります。 なぜなら _ は「行全体」であり、 Text.Upper(record) はできないからです。

正しい書き方:

each Text.Upper(_[顧客名])
Power Query

2. _ を使いすぎると読みづらくなる

複雑な処理は関数に切り出した方が安全です。

悪い例:

each if _[金額] > 1000 and Text.Length(_[顧客コード]) > 3 then true else false
Power Query

良い例:

each IsHighValueCustomer(_)
Power Query

3. セキュリティ・品質に関わる処理を _ の中に直接書かない

権限判定や重要顧客判定などは、 必ず関数に切り出しておくべきです。

理由:

  • ロジックのレビューがしやすい
  • 誤って条件を緩める事故を防げる
  • 意図が明確になる

実務で使える「_」テンプレート

テンプレ1:列の値を加工する

Table.TransformColumns(
    SalesTable,
    {
        {"顧客名", each Text.Upper(_), type text}
    }
)
Power Query

テンプレ2:行全体を使って判定する

Table.SelectRows(
    SalesTable,
    each _[金額] > 1000
)
Power Query

テンプレ3:行全体を関数に渡す

Table.AddColumn(
    SalesTable,
    "有効行",
    each IsValidRow(_),
    type logical
)
Power Query

まとめ:_ を理解することは「無名関数の仕組み」を理解すること

M言語で _ の意味を理解するというのは、 「無名関数が何を引数として受け取っているか」を理解することでもあります。

_ は、

  • リストの要素
  • 列のセル値
  • 行全体(record)

など、使う関数によって姿を変える「現在値」を表す記号です。

ぜひ、

  • 「_ はその場で処理している値」
  • 「行なら [列名]、セルなら _
  • 「複雑な処理は関数に切り出す」

という感覚を身につけて、 実務の Power Query をより読みやすく、安全で、意図の伝わるコードに育てていってください。

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