M言語入門 ― GUIの限界を超えるカスタム処理

このページのゴール

Power QueryのM言語を「全部書けるようになる」ことではなく、自動生成されたコードを読める、必要な1行だけ直せる、カスタム列で簡単な式を足せる状態にすることです。実務では、M言語をゼロから手書きするより、GUIで作った手順を少しだけ補正する使い方がもっとも安全です。

M言語はどこで使うか

Power Queryで画面操作をすると、裏側ではM言語のコードが自動で作られます。まずは「どこに出てくるか」を押さえるだけで十分です。

場所何をするところか実務での使い方
数式バー現在選択中のステップのM式を表示・編集するフィルター値、列名、固定文字などを少し直す
カスタム列新しい列をM式で追加する条件判定、文字列結合、日付加工を足す
詳細エディタークエリ全体のMコードをまとめて編集するファイルパスや複数ステップの流れを確認する
高度なエディター操作関数化、パラメータ化、共通処理化を行う同じ処理を複数ファイル・複数部署で再利用する
まずは「読む」だけでよい
Power QueryはGUIだけでもかなりの作業ができます。M言語は、GUIの手順を壊さずに少しだけ融通を利かせるための補助輪として使うのが現実的です。

基本形は let ... in

M言語のクエリは、多くの場合 let で手順を並べ、最後に in で返す結果を指定します。Excelの数式というより、料理のレシピに近い構造です。

let ソース = Excel.CurrentWorkbook(){[Name="売上表"]}[Content], 型の変更 = Table.TransformColumnTypes(ソース, {{"売上", Int64.Type}, {"日付", type date}}), 営業部だけ = Table.SelectRows(型の変更, each [部署] = "営業部") in 営業部だけ
部分意味見るポイント
ソース = ...最初のデータ取得Excel表、CSV、フォルダ、Webなどの入口
型の変更 = ...前の結果に処理を重ねる右辺の先頭に、前ステップ名が入ることが多い
営業部だけ = ...行フィルターなどの変換each [部署] = "営業部" のように行ごとに判定する
in 営業部だけ最終的に返すステップここを途中ステップ名に変えると、その時点の結果を確認できる

ステップ名・列名・行の読み方

ステップ名は変数のように扱う

Power Queryの「適用したステップ」は、M言語では1行ずつ名前付きで保存されています。次のステップは、前のステップ名を材料にして処理します。

削除された列 = Table.RemoveColumns(ソース, {"不要列"}), 並べ替えられた行 = Table.Sort(削除された列, {{"日付", Order.Ascending}})

ステップ名に空白や記号が入る場合は、#"変更された型" のように #"" で囲まれます。これはエラーではありません。

列名は角かっこで参照する

each [部署] = "営業部"

[部署] は「今見ている行の部署列」を意味します。ExcelのA列・B列ではなく、列名で参照するのがPower Queryらしいところです。

each は「各行に対して」

each は、表の各行に対して同じ判定や計算を行う合図です。行フィルター、カスタム列、列変換でよく出てきます。

if式とnullを押さえる

カスタム列で最初に覚えるなら、if ... then ... else ... です。M言語では ifthenelse を小文字で書きます。

if [売上] >= 1000000 then "重点" else "通常"

AND / OR 条件も小文字です。

if [売上] >= 1000000 and [部署] = "営業部" then "対象" else "対象外"

空白セルはExcelの空文字とは違い、Power Queryでは null として扱われることがあります。空白判定は次のように書きます。

if [備考] = null then "未入力" else [備考]
大文字のIFは使わない
Excel関数の感覚で IF と書くとエラーになります。M言語のキーワードは基本的に小文字で覚えると安全です。

よく使うM関数

関数名は Text.Table.Date. のようにカテゴリ名から始まるため、名前を見るだけで役割を推測しやすくなっています。

カテゴリ代表例使いどころ
TextText.BeforeDelimiter
Text.AfterDelimiter
Text.Trim
文字列の抽出、区切り文字の前後取得、余分な空白削除
NumberNumber.Round
Number.FromText
丸め、文字列から数値への変換
DateDate.Year
Date.Month
Date.EndOfMonth
年・月の取り出し、月末日の取得
TableTable.SelectRows
Table.AddColumn
Table.TransformColumnTypes
行フィルター、列追加、型変換
ListList.Sum
List.Max
List.Contains
リスト集計、最大値取得、含まれるかの判定

カスタム列で使う実務例

区切り文字より前を取り出す

商品コード ABC-001 から、ハイフンより前の ABC を取り出す例です。

Text.BeforeDelimiter([商品コード], "-")

複数条件で区分を作る

if [売上] >= 1000000 and [粗利率] >= 0.3 then "優先" else if [売上] >= 500000 then "確認" else "通常"

M言語の else if は横に続けてもよいですが、長くなる場合は改行した方が読みやすくなります。

年月ラベルを作る

Text.From(Date.Year([日付])) & "年" & Text.From(Date.Month([日付])) & "月"

文字列と数値を連結するときは、年や月を Text.From で文字列に変換してから & でつなぎます。

詳細エディターで安全に直す手順

操作手順

1. Power Queryエディターで 表示 タブ → 詳細エディター を開きます。
2. いきなり大きく書き換えず、まずはソース、型変更、フィルター、列追加の流れを確認します。
3. 変更したい箇所だけを1か所直します。たとえばファイルパス、列名、固定値などです。
4. 「完了」を押し、プレビューでエラーが出ないか確認します。
5. エラーが出たら、直前の状態に戻せるように、変更前のコードをメモしておくと安全です。

おすすめは「GUIで作ってから少し直す」
最初から詳細エディターで全部書く必要はありません。Power Queryに8割作らせて、人間は最後の2割だけ整える。この使い方が一番壊れにくいです。

よくあるエラーと直し方

エラー・症状よくある原因確認する場所
トークンが必要ですカンマ、かっこ、引用符の不足。全角記号を混ぜた。直前の行末、"),
列が見つかりません元データの列名変更、余分な空白、全角半角違い。[列名] と実データの見出し
型を変換できません数値列に文字、日付列に不正な文字列が混ざっている。型変更ステップ、エラー行の確認
循環参照のようなエラークエリ名とステップ名、またはパラメータ名が衝突している。クエリ名、ステップ名、参照先名

学ぶ順番

M言語は一気に覚えようとすると重いので、次の順に慣れると実務に乗せやすくなります。

  1. GUI操作後に、数式バーで自動生成されたM式を見る。
  2. フィルター値や固定文字だけを書き換える。
  3. カスタム列で if、文字列結合、日付加工を使う。
  4. 詳細エディターでクエリ全体の流れを読む。
  5. 必要になったら、複数クエリで共通利用する関数化に進む。

固定長データやバイト単位の切り出しまで踏み込む場合は、M言語でMIDB相当の自作関数を作るも参考になります。

まとめ

M言語は、Power Queryを「画面操作だけの便利機能」から「再利用できるデータ処理」に変えるための道具です。最初に覚えるべきことは多くありません。let...inの流れ、ステップ名の参照、列名の角かっこ、if式、よく使うText・Table・Date関数を押さえれば、GUIで作ったクエリを実務向けに少しずつ改良できるようになります。