【図で分かる!】Power Query 入門 M関数の使い方

実は Power Query のデータ処理は全て M関数 というプログラム言語で記述されています。Power Query を普通に使うだけであればこの M関数 を意識することなく使うことができます。

しかし、M関数 について知っておけば、Power Query をより高度に活用 できるようになります。

M関数 は Excel関数 と似ている部分もあるので、初心者の人でも理解しやすいと思います。

ステップアップには必須の M関数、皆さんも是非挑戦してみてください。

では、早速いってみましょう!

スポンサーリンク

M関数とは?

従来の Excel関数 を使う場合、使い方を自分で覚えるか、ネット記事を参考にして使うしかありませんでした。

しかし、Power Query の場合、Power Query エディタの メニューのボタンにほぼ全ての機能が揃っています。ボタンを見れば機能かも分かるように出来ていて、直感的に使えるようになっています。

しかし、Power Query の素晴らしさはこれで留まりません。使いやすさを向上させつつも、プログラミングによる柔軟性も兼ね備えている のです。

このプログラミング言語 が M関数 です。

実は、Power Query のデータ操作は全て M関数 で記述でき、ユーザーの操作手順も Power Query エディタの中で M関数のプログラムとして記録 されています。

M関数 のプログラムを覗いてみる

では一度その中身を覗いてみましょう。導入編 で作成したクエリなど、作成済みのクエリを Power Query エディター で開いてみましょう。(メニューから データ>クエリと接続>(サイドウィンドウからクエリ名をダブルクリック)

続いて、 Power Query エディターのメニューから、 ホーム>詳細エディタ をクリックして下さい。すると図のような 詳細エディター の ウィンドウ が開くと思います。

ここに記述されているプログラムが Power Query の データ処理の核心 の M関数 のプログラムです。

詳細エディター

M関数 プログラムの構成

プログラミングに慣れている人でも初めて M言語 のプログラムを見たら戸惑うかもしれません。それもそのはずで、M言語 のプログラムはその他のプログラムと構成がかなり異なっているのです。

しかし、M言語 のプログラムは非常に単純な構成なのですぐに理解できると思います。下の図をご覧ください。

プログラムは “let” で始まり、続く行をシンプルに順番に実行、最後に “in” の後に指定された変数をアウトプットとして出力します。とても単純な構成です。

通常のプログラミング言語では、For 文 や Do Loop 文 などの繰り返しなどがありますが、M関数 のプログラムではこの 繰り返し制御がありません。だからとてもシンプルな構成になっているのです。

M関数で記録された操作手順 を確認する

Power Query エディター でデータ操作したものを 詳細エディター で確認すると図のように 1つ前の処理結果を受け取って次の処理をする ように書かれているのが分かります

しかし、自分で M関数 のプログラムを編集する場合は、この順番を気にすることなく、自由に記述することができます。最後に出力する変数を指定することが大切なルールですが、それ以前のプログラムは上から順に実行されるというだけだからです。

このことを知っておくと、M関数のプログラムを編集することへの抵抗がぐっと減ると思いますので、是非覚えておいてください。

M関数 プログラム の例と解説

続いて、M関数 プログラム の例を挙げて解説をします。

例: テーブルからデータを取得

let
    ソース = Excel.CurrentWorkbook(){[Name="テーブル1"]}[Content],
    変更された型 = Table.TransformColumnTypes(ソース,{{"日付", type datetime}, {"売上", Int64.Type}})
in
    変更された型

このプログラムの2行目のM関数式を読み解くと以下のようになります。

M関数 の名前は [処理対象のデータ型].[処理名]() と ピリオド “.” で繋いだ形になっています。処理名は 英語で処理内容が想像できる ようになっています。。

1つ注意 が必要なのは M関数 の名前は 大文字と小文字を区別する ということです。単語の1文字目が大文字になって単語の区切りが分かるようになっています。

M関数 の Microsoft リファレンスを参照

M関数式はExcel関数と同様に様々なものが用意されています。関数を探したり、その使い方を知るには Microsoft のリファレンスが便利です。以下のリンクからアクセスしてみてください。

Power Query M 関数参照 - PowerQuery M
詳細については、以下をご覧ください。Power Query M 関数参照

リファレンスは主に以下のような データ型ごとに 分けて整理されています。

  • 日付型(Date)
  • 日時型(DateTime)
  • リスト型(List)
  • 数値型(Number)
  • テーブル型(Table)
  • テキスト型(Text)
  • ・・・etc

上の例で解説した内容を念頭に参照すると、このリファレンスも読み解きやすいと思いますので、ご自分でもアクセスして確認してみて下さい。


ここまでで M関数 の基本的な知識をご紹介しました。続いては Power Query エディターのボタン操作では実現できない M関数 を使ったテクニックをご紹介します。

パラメータを使ってクエリ動作を動的に変える

Power Query は決まった処理をキッチリ覚えておいて、毎回その処理を実行してくれます。

しかし、Power Query を使っていると、実行時に動作を変更したいケース が出てきます。例えば、イベント リストのデータから「今日から一週間以内の イベント を表示 したい」というようなケースです。

このために毎回 Power Query エディター でクエリを編集するのでは効率が上がりません。しかし、M関数 のプログラムを編集することで、Power Query エディターでクエリを編集すること無く、クエリの動作を毎日変更することが可能になります。

「本日の日付」でフィルターをかける

具体例として図のように テーブル1 のデータがあり、このイベントリストの情報から本日以降のイベントを Power Query のクエリ出力を得たいとします。

通常のクエリを作成した場合、以下の例のようにフィルターする日付を #date(2025, 9, 10) と直接してします。

let
    ソース = Excel.CurrentWorkbook(){[Name="テーブル1"]}[Content],
    変更された型 = Table.TransformColumnTypes(ソース,{{"日付", type date}, {"イベント", type text}}),
    フィルターされた行 = Table.SelectRows(変更された型, each [日付] > #date(2025, 9, 10))
in
    フィルターされた行

これを動的に変化するようにコードを見直します。

let
    本日 = Date.From(DateTime.LocalNow()),
    ソース = Excel.CurrentWorkbook(){[Name="テーブル1"]}[Content],
    変更された型 = Table.TransformColumnTypes(ソース,{{"日付", type date}, {"イベント", type text}}),
    フィルターされた行 = Table.SelectRows(変更された型, each [日付] >= 本日)    
in
    フィルターされた行

解説

1行目でまず、 DateTime.LocalNow() で現在日時を取得します。それを Date.From() 関数でデータ型を日付型に変換しています。

4行目のフィルターをかけるところで、先ほどの直接日付をしてしていたところを、変数「本日」に置き換えています。

これだけの変更で、次回からは Power Query エディター でクエリの内容を編集しなくても、本日の日付でフィルターをかけることができるようになります。

これはなかなか便利ではないでしょうか?ご自分のニーズに合わせてカスタマイズして活用してみて下さい。

ユーザー入力をクエリに取り込む方法

日付以外にユーザーがセルに入力した値を使ってクエリの動作を変更したい場合も M関数 を使えば実現可能です。

Power Query のM関数では、セルのアドレスを直接指定して値を取得することはできません

その代わり、セルにつけた名前を指定して値を取得 することが可能です。

ですので、まずセルに名前をつける方法から解説します。

セルに名前をつける方法

  1. セルを選択した状態で図のように「名前ボックス」をクリックします。
  2. ボックス内にセルにつける 名前を入力 します。

とても簡単な手順なので、あっという間にできたかと思います。続いて M関数 でセルの値を取得します。

M関数でセルの値を取得する

M関数 で以下のようなプログラムを書くことで 変数1 に セルの値を取得することができます。

変数1 = Excel.CurrentWorkbook () {[Name = "ユーザー入力1"]} [Content] {0} [Column1],

この関数式の意味合いは以下のようになります。

  • Excel の CurrentWorkbook(作業中のファイル)の
  • Name(名前付き範囲の名前)が「ユーザー入力1」の
  • Content(データ内容)の
  • {0} 番目(最初の)データの
  • Column1(1列目:最初の列)のデータ

少々ややこしくて覚えるのは面倒かもしれません、これをそのままコピー&ペーストして使って下さい。

使用例

例えば図のように Power Query で読み込むファイル名を名前をつけたセルに入力しておきます。

M関数 のプログラムは次のように記述します。

let
    filepath = Excel.CurrentWorkbook () {[Name = "ユーザー入力1"]} [Content] {0} [Column1],
    ソース = Excel.Workbook(File.Contents(filepath), null, true),
    テーブル1_Table = ソース{[Item="テーブル1",Kind="Table"]}[Data]
in
    テーブル1_Table
  • 1行目: 先ほどご紹介した関数式で filepath という変数ににセルの値を取得します。
  • 2行目: Excel.Workbook(File.Contents(filepath)... の関数式でファイルを読み込みます。
  • 3行目: 「テーブル1」という名前の Table を読み取る指示をしています。

以上のようにすることで、毎回 Power Query エディター を開いて編集することなく、Power Query が読み込むファイルを変更することが可能になります。

これは Power Query の動作を柔軟に変更することができるので非常に便利です。この方法は他にも様々な場面で応用できますのぜ、是非憶えておきましょう。

M関数でクエリのエラーを回避

Power Query はデータ内に次のような問題があると、エラーで処理中断してしまう という問題があります。

  • データ型 の 不一致
  • Excel のエラー値(#DIV/0! , #NULL! , #REF! など・・・)

この問題も M関数 を使うことで回避が可能です。エラーを安全に扱う基本が M関数 の try … otherwise 構文 です。

try … otherwise 構文の使い方

try … otherwise 構文では、値がエラーの場合、代わりの出力値を指定することができます。

例:通常の処理(文字列を数値に変換)

let
    ソース = Excel.CurrentWorkbook(){[Name="テーブル1"]}[Content],
    変更された型 = Table.TransformColumnTypes(ソース,{{"値", type number}})
in
    変更された型

例:try ... otherwise による処理(文字列を数値に変換)

let
    ソース = Excel.CurrentWorkbook(){[Name="テーブル1"]}[Content],
    変更された型 = Table.TransformColumns(
        ソース,
        {{"値", each try Number.From(_) otherwise null, type number}}
    )
in
    変更された型

解説

2行目の Table.TransformColumns() 関数 の中で 以下の変更を加えています。

  • 変更前: ”値”
  • 変更後: ”値”, each try Number.From(_) otherwise null

変更後の M関数式 は少々複雑ですが、以下のような指示になっています。

  • each で “値” 列の全ての値に対して処理を開始
  • try の後で、Number.From(_) にて各値を 数値に変換。
  • ここで アンダースコア “_” は each で取り出された列の各値を示す変数です。
  • 続いて otherwiseNumber.Form(_) で数値に変換する際にエラーになった場合の代わりの出力をしていします。ここでは “null” を出力としています。例えば別の 10000 などの数値を出力しても構いません。

この例では、文字列 "123""456" などは数値に変換されますが、 "ABC" は変換できないため null に置き換えられます。これでエラーで処理が止まらず、データのクリーニングがスムーズに進みます。

Record.HasFields で条件分岐

JSONやAPIのデータを扱うとき、「あるレコードに特定のフィールドがあったりなかったりする」ことがあります。
そんなときに便利なのが Record.HasFields です。

例:フィールドが存在するかチェック

let
    レコード = [名前="山田", 年齢=30],
    年齢有無 = if Record.HasFields(レコード, "年齢") then レコード[年齢] else null
in
    年齢有無

この場合は 30 が返ります。
もし 年齢 フィールドが存在しなければ null になるので、エラーを防げます。

グループ化でテキストを まとめて結合する

導入編のチュートリアル でグループ集計を紹介しました。グループ集計では数値については合計値を求めることができますが、テキストはどうでしょうか?

グループ化の操作で図のように テキストの「備考」列 を合計しようとしても エラー になってしまいます。

これも M関数 を使って解決することができます。次は テーブル1 にある備考欄をまとめる M関数 プログラムになります。

例:「備考」列のテキストをまとめる

let
    ソース = Excel.CurrentWorkbook(){[Name="テーブル1"]}[Content],
    変更された型 = Table.TransformColumnTypes(ソース,{
        {"地区", type text}, 
        {"売上", Int64.Type}, 
        {"備考", type text}
        }),
    グループ化された行 = Table.Group(変更された型, {"地区"}, {
        {"売上", each List.Sum([売上]), type nullable number}, 
        {"備考", each Text.Combine([備考], "#(lf)"), type text}
        })
in
    グループ化された行

解説

通常のクエリと異なる箇所は下から4行目の {"備考", each Text.Combine([備考], "#(lf)"), type text} の箇所になります。

  • 数値の合計の場合なら List.Sum() 関数を使いますが、テキストでは Text.Combine() 関数を使います。
  • 最初の引数はテキストをまとめる列 [備考] を指定します。
  • 2つ目の引数はテキストを結合する際に間に入れる文字です。“#(lf)” は M関数 における特殊文字で 改行コード を示します。これによりテキストは改行されて結合されます。

まとめ

本記事では Power Query のデータ処理の核心である M関数 について基本的な概念から応用的な使い方までを解説しました。

Power Query エディター の操作だけでは実現できないような様々な処理が M関数 を使うことで実現できることを実感いただけたかと思います。

M関数 はシンプルな関数なので習得のハードルも高くは無いと思います。

簡単な処理からトライして徐々に慣れていくことで M関数 をマスターできると思いますので、皆さんも是非トライしてみて下さい。

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