Power Query(M言語)入門
M言語入門:Power Queryのコードを読むための基礎知識

Power Query(パワークエリ)とM言語を練習問題を通して学んでいきます
公開日:2026-09-09 最終更新日:2026-09-09

M言語入門:Power Queryのコードを読むための基礎知識


Excel Power Query M言語

Power Query(パワークエリ)で使われ、Power BIでのデータ取得・変換にも使われているのが「M言語(Power Query M Formula Language)」です。


M言語を活用するにあたって、細かな関数を1つずつ暗記する必要はありません。
生成AIが普及した現在において重要なのは、コードをゼロから書くことではなく、AIが生成したコードや既存クエリの「構造」を正しく読み解き、データの流れを把握することです。

本稿では、文法暗記を最小限に抑え、M言語のコードを解読・デバッグするための構造的知識をコンパクトに解説します。

※本記事の数式および解説文章の多くは、生成AI(ChatGPT、Gemini、Claude)を活用して作成しました。数式動作や解説文の最終的な内容は人間による確認・編集を経て掲載しています。

ページ内目次

導入:M言語を学ぶ前に知っておくべきこと

Power Queryを使いこなす上で、切っても切り離せないのがM言語です。
従来は、こうした専門言語を活用するには、M言語の構文や関数を体系的に学ぶ必要がありました。
しかし、生成AIが普及した現在、学習のアプローチは大きく変わっています。

現代におけるM言語学習のゴールは、「コードをゼロから暗記して書けるようになること」ではありません。
AIは基本的なコードから複雑な変換処理まで生成できます。
しかし、出力されたコードをPower Queryの「詳細エディター」に貼り付けたとき、エラーが出たらどう対処すべきでしょうか。
あるいは、既存のクエリが「何をどう処理しているのか」を理解できなければ、手直しやデバッグを行うことはできません。

ここでまず身につけるべきなのは、以下の2点です。
  1. AIが出力したコードや既存クエリの「構造」を読み解くこと

  2. ステップ間で「どの値を参照しているか」を把握すること
本稿では、網羅的な構文暗記や細かな関数の列挙は行いません。「コードの読み解きとデータの流れの把握」に特化し、M言語を読み解くための最小限の土台を整理します。


第1章:M言語の正体と基本構造

1. M言語の正体:「式を評価して値を得る」言語

M言語は、VBAのような手続き型の考え方とは異なります。
VBAなどでよく見られる「セルを書き換える」「ループ処理で順番に状態を変更する」といった発想ではなく、M言語は「式を評価すると必ず何らかの値になる」という仕組みを基本にしています。

1. 式を評価して「値」を得る
2. 得られた値に「名前(識別子)」をつける
3. 別の式がその「名前」を参照して、次の新しい値を評価する

このプロセスの連続によってクエリ全体が構成されます。
このシンプルな一本の原則を理解しておくと、テーブルの操作だけでなく、レコード、リスト、カスタム関数の読み解きにもスムーズにつながります。

2. 注意すべきルール:大文字・小文字の厳密性とコメント

M言語のコードを読む際、押さえておくべき重要なルールがあります。
それは「大文字と小文字を厳密に区別する(ケースセンシティブ)」ということです。

これは関数名や識別子だけでなく、文字列の値そのものの比較においても同様です。
  • 関数名: Table.SelectRows(正しい)と table.selectrows(小文字:エラーの原因)
  • 文字列比較: "Apple" と "apple" は別の値として扱われる(抽出や結合で一致しない原因になります)

また、コード内の解説や処理の一時的な無効化にはコメント記法が使われます。
  • // 1行コメント: 行末までをコメントとして無視
  • /* 複数行コメント */: 囲まれた範囲全体をコメントとして無視

3. Power Queryのクエリで頻出する基本構造:let ... in ...

Power Queryで作成されるクエリの多くは、以下のような let ... in の構造になっています。
let
    // 名前付きの式を定義する領域
    Step1 = ...,
    Step2 = ...
in
    // 最終的に評価して返す式
    Step2
let ... in は、M言語を読むうえで押さえておきたい基本的な構文構造です。
  • let:各式に名前(識別子)をつけて定義する部分
  • in:let で定義した値など、最終的に評価して返す式を指定する部分

M言語のコードでは、let 内で定義された名前付きの式が、Power QueryのGUI上では「適用したステップ」として画面に表示されます。

手続き型言語のように「上から順に文を実行する」のではなく、「let で名前付きの式を定義し、in でその中から返す式を指定する」という構造を理解することが、M言語解読の第一歩となります。


第2章:M言語の核心「参照の連鎖でデータを渡す」

1. ステップと識別子の関係:参照の連鎖を追う

M言語のクエリは、直感的には「バケツリレー」のように順々にデータが渡されているように見えます。
しかし内部的には、定義した名前付きの式を、別の式が参照するという依存関係によって成り立っています。

[Source]
↓ (参照)
[Filtered]
↓ (参照)
[Result]


Power Queryの画面上でステップが順番に並んで見えるのは、通常、後続のステップが前のステップを参照する形でクエリが構成されているためです。
なお、
M言語には部分的な遅延評価(Lazy Evaluation)の性質があり、let 内で定義した式は、単純に上から順番に実行されるとは限りません。
最終的に in で指定された結果を出力するために必要な式だけを逆算して評価するため、途中でどの式からも参照されていないステップが存在する場合、そのステップは評価されずにスキップされます。

2. コードで見るデータの流れ

以下は、データ取得部分を省略し、ステップ間の参照関係だけを示した簡略化したコード例です。
let
    Source = ..., // データ取得・定義を行うステップ(簡略表記)
    Filtered = Table.SelectRows(Source, each [金額] > 1000),
    Result = Table.Sort(Filtered, {{"日付", Order.Descending}})
in
    Result
このコードにおける参照関係は以下の通りです。
  1. Source:データを表す値を定義します。
  2. Filtered:Table.SelectRows の対象として Source を参照し、条件を適用します。
  3. Result:Table.Sort の対象として Filtered を参照し、ソートを適用します。
  4. in Result:最終的に Result の評価結果を返します。
多くのテーブル変換関数では、対象となるテーブルが第1引数に指定されるため、そこにどの名前付きの式が渡されているかを追うと、データの変換関係を把握しやすくなります。

3. #"..."(引用符付き識別子)の正体

Power Queryの詳細エディターでコードを開いた際、次のような記述を見かけることがあります。
let
    ソース = ..., // データ取得ステップ(簡略表記)
    #"昇格されたヘッダー数" = Table.PromoteHeaders(ソース, [PromoteAllScalars=true]),
    #"変更された型" = Table.TransformColumnTypes(#"昇格されたヘッダー数", {{"金額", Int64.Type}})
in
    #"変更された型"
この #"..." という表記は、M言語における引用符付き識別子(quoted identifier)です。
#" " と " で囲むことで、スペースやキーワード、演算子など、通常の識別子としてそのまま記述できない文字を含む名前を識別子として扱えるようになります。

なお、日本語そのものは通常の識別子としても使用可能です。
Power QueryがGUI操作時に自動生成する「昇格されたヘッダー数」や「変更された型」のようなステップ名では、間にスペースが含まれるなどの理由から、この引用符付き識別子の形式が使われます。


第3章:値の構造をたどる([ ] と { } の役割)

1. M言語における代表的なデータの「構造」

M言語では、数値・文字列・テーブル・レコード・リスト・関数など、さまざまなものが「値」として扱われます。
コードを解読するうえで特に頻出する基本的なデータ構造は、以下の3つです。

データ構造 囲み記号 特徴・定義 基本アクセス記法
レコード [ ] 名前と値を組み合わせた構造(1行分のデータや設定情報) [フィールド名] で参照
リスト { } 順序を持つ値の並び(列データや引数のグループ) {インデックス} で参照(0始まり)
テーブル 該当なし 行(レコード)と列からなる表構造 [列名] で列リスト、{行番号} で行レコード

ここで重要なのは、記号 `[ ]` と `{ }` は、操作対象がレコードかテーブルかによって役割が変わるという点です。
それぞれの構造を具体的に確認します。

2. レコード [ ]:定義とフィールドアクセス

角括弧 [ ] で囲まれた構造はレコード(Record)と呼ばれます。
「フィールド名 = 値」というペアをカンマ区切りで保持します。
[ ID = 1, 商品名 = "りんご", 価格 = 150 ]
テーブルの中における「1行分のデータ」として表現されるほか、Table.PromoteHeaders(ソース, [PromoteAllScalars=true]) のように関数に渡す設定オプション(設定情報)としてもよく使われます。

【レコードに対する [ ]】
レコードに対して [フィールド名] を指定すると、そのフィールドの値を取得できます。
例えば上記レコードに対して [価格] を指定すると、値 150 が得られます。

3. リスト { }:定義とインデックスアクセス

波括弧 { } で囲まれた構造はリスト(List)と呼ばれます。
同じ種類、あるいは異なる種類の値を並べることができます。
{ "りんご", "みかん", "バナナ" }
{ 100, 200, 300 }
関数の引数として複数の列名や条件を一括指定する場合などにも登場します。

【リストに対する { }】
リストに対して {位置番号} を指定すると、該当する要素を取り出せます。M言語のインデックスは0始まり(0ベース)です。
例えば上記リストに対して {0} を指定すると "りんご"、{1} を指定すると "みかん" が得られます。

4. テーブルに対するデータ取り出し(構造の組み合わせ)

M言語におけるテーブル(Table)は、各行がレコードとして扱われる集合体です。
テーブルに対する要素の取り出しは、アクセス対象が「列」か「行」かによって記号を使い分けます。

  • Source[金額] → 列を「リスト」として取り出す
    テーブルに対して [列名] を指定すると、その列の値が並んだリストが得られます(※レコードに対する [ ] が単一フィールドを参照するのとは対照的です)。
    Source[金額]
    // 実行結果:{ 1500, 800, 2300, ... } (金額列のリスト)

  • Source{0} → 行を「レコード」として取り出す
    テーブルに対して {インデックス} を指定すると、該当行がレコードとして取得できます。
    Source{0}
    // 実行結果:[ ID = 1, 商品名 = "りんご", 価格 = 150 ] (先頭行のレコード)

  • Source{0}[商品名] → 構造をたどって単一の値を取り出す
    行指定 { } で取り出したレコードに対し、さらに [列名] を指定することで特定の値を取得できます。
    Source{0}[商品名]
    // 実行結果:"りんご"

記述 対象 使う記法 得られるデータ構造 コードの動作
Source[列名] テーブル [ ] (名前指定) リスト { } テーブルから指定した列をリストとして取得
Source{0} テーブル { } (位置指定) レコード [ ] テーブルから先頭行をレコードとして取得
Source{0}[列名] レコード [ ] (名前指定) 単一の値 レコードから指定したフィールドの値を取得

このように、対象がレコードなのかテーブルなのかによって `[ ]` の意味が変わる点を意識すると、M言語のデータ抽出コードを正しく読み解けるようになります。

5. 補足:キーが存在しないときのエラーを防ぐ ?(オプショナル参照)

AIが生成したコードや高度なクエリでは、Source{0}[列名]? や Record[Field]? のように、末尾に ? がついていることがあります。
これは「もし指定した列やフィールドが存在しなければ、エラーを出さずに null を返す」という安全な参照方法(オプショナルアクセス)です。
データに特定の列が含まれているか不確定な場合によく使われます。


第4章:特殊構文とエラー処理(each / try...otherwise)

1. 関数の基本(アロー記法)と each の正体

Power Queryのコードを読み解くうえで重要なのが「関数」の記述です。
M言語では、関数も数値や文字列などと同じく「値」の一つとして扱われます。

(1) 関数の基本形:(引数) => 式
M言語では、=> を使って関数を定義します。
(x) => x + 1
これは「x という値を受け取り、1を加えた値を返す関数」です。
例えば、この関数に 10 を渡すと、結果は 11 になります。
((x) => x + 1)(10)
このように、M言語では関数を値として扱い、直接実行したり別の関数に渡したりすることができます。

ここで、次のような関数を考えてみます。
(_) => _[金額] > 1000
これは、1つの値(1行分のレコード)を受け取り、その値の [金額] フィールドが1000より大きいかどうかを調べ、true または false を返す関数です。
ここで _ は、この関数が受け取る1つの引数を表しています。

(2) each は関数を簡潔に書くための構文
M言語には、このような1つの引数を受け取る関数を簡潔に記述するための each という構文があります。
(_) => _[金額] > 1000
という関数は、each を使うと、
each [金額] > 1000
と簡潔に記述できます。

ここで重要なのは、each 自体が「各行を処理する命令」ではないということです。
each は、1つの値を受け取る関数を簡潔に記述するための構文です。

Table.SelectRows は、テーブルの各行について、指定した関数を使って処理を行います。
通常の関数の形で書くと、
Table.SelectRows(Source, (_) => _[金額] > 1000)
となり、each を使って簡潔に書くと、
Table.SelectRows(Source, each [金額] > 1000)
となります。
コードを読むときは、
  • each を見たら、「1つの値を受け取る関数を簡潔に書いている」と考える
ことが重要です。

2. エラーに対処する try ... otherwise 構文

コード読解の際、知っておくと便利なのが try ... otherwise 構文です。
これは「処理中にエラーが発生した場合に、安全に代替の値を返す」ための記述です。
try [金額] otherwise 0
`try` の後に記述した式(上記では `[金額]` の参照)を評価し、もしデータ型の不一致や欠損などでエラーが発生した場合は、`otherwise` の後に指定した代替の値(上記では `0`)を評価して返します。
データ変換時の不備に対処する安全策としてコード内で使われます。


第5章:未知の関数に出会ったときの読み方(名前からの推測)

M言語には非常に多くの組み込み関数が存在します。
これらを1つずつ暗記しようとする必要はありません。
詳細エディターで知らない関数に出会ったときは、関数名から「何を対象にしている処理なのか」を推測できるようになることが重要です。

多くの組み込み関数は、`Table.`、`List.`、`Text.` などの接頭辞によって、対象となるデータの種類や機能領域が推測できる整理ルールになっています。

以下は、コード解読時に頻繁に見かける主要カテゴリの整理表です。

接頭辞(カテゴリ) 対象・領域 代表的な関数例と推測のポイント
Table.~ テーブル(表全体) SelectRows(行抽出)、AddColumn(列追加)、Group(グループ化)など、表全体の構造を変える処理
List.~ リスト(値の並び) Sum(合計)、Average(平均)、Distinct(重複除去)など、値の集まりに対する処理
Record.~ レコード(1行・設定) Field(フィールド取得)、AddField(フィールド追加)など、単一の行や設定に関する処理
Text.~ テキスト(文字列) Middle(切り出し)、Replace(置換)、Split(分割)、Combine(結合)など、文字列操作
Date.~ / DateTime.~ 日付・時刻 Year(年の抽出)、Month(月の抽出)、EndOfMonth(月末日)など、日時計算
Excel.~ / Web.~ など データ接続・取得 Workbook(Excel読み込み)、Contents(Webデータ取得)など、外部データソースからの読込処理

ドットの前の部分を見ることで、「このステップはテーブル全体を操作しているのか、それとも文字列の加工をしているだけなのか」といった大まかな処理の狙いを即座に推測できるようになります。


第6章:AIが生成したコードを解読・検証する実践手順

ここまでの知識を踏まえ、AIが生成したM言語コードや既存のクエリを人間がチェックし、正しく組み込むための実践的な手順を整理します。

1. 接続先となる「ステップ名」と「列名」を確認する

AIに既存クエリへコードを追加・修正させたい場合、人間側の手で「どの式に接続するか」を明確にする必要があります。

コードを追加する際は、以下の2点を確認してAIへ提示します。

  • 接続先となるステップ名(例: #"変更された型")
  • 対象となる正確な列名(例: 売上金額)
    【AIへの提示プロンプト例】
    Power Queryの既存クエリにステップを追加したいです。
    • 接続先のステップ名:#"変更された型"
    • 対象の列名:売上金額
    • 処理内容:売上金額 列が 1000 以上の行に絞り込むステップを作成してください。
接続先のステップ名を正しく渡すことで、既存の参照関係を壊さずにコードを生成させやすくなります。

2. 組み込み時のチェックポイント(デバッグ手順)

生成されたコードを詳細エディター(クエリ全体のMコードを確認・編集できる画面)に組み込む際は、次の手順とガイドラインに沿って確認します。

【1】既存コード内への具体的な挿入ルール
既存クエリの末尾にAIが作成した新しいステップを追加する場合、以下の2点を調整します。
  1. 直前ステップの末尾にカンマ , を付与する
  2. in の直後の参照ステップ名を新しいステップ名に書き換える
let
    ソース = ...,
    変更された型 = ...,  // ← 末尾にカンマを追加
    抽出された行 = Table.SelectRows(変更された型, each [金額] > 1000) // ← 新ステップを挿入(末尾カンマなし)
in
    抽出された行 // ← in の参照先を新しいステップ名に変更

【2】エラーの段階を切り分けて確認する
トラブルが発生した場合は、エラーの性質を切り分けて対応します。
  • ① 構文エラー(Syntax Error):
    カンマの欠落やカッコ・引用符の閉じ忘れ等によって生じます。詳細エディターの下部に赤文字メッセージが表示され、コードを保存して閉じることができません。
    ※エラーメッセージ(「Token Comma expected」や「Token In expected」など)が表示された位置はパーサーが解釈に失敗した場所を示すため、必ずしもエラーメッセージ通りの位置や内容そのものを指しているとは限りません。メッセージ行だけでなく、直前行のカンマ有無やカッコの閉じ忘れ、`let ... in` の構造全体を確認することが解決のポイントです。

  • ② 評価時・実行時エラー:
    型の不一致(テキスト列に対する数値計算など)や存在しない列名の参照等によって生じます。構文上正しく記述できていても、実際のデータを評価する段階でエラーが発生することがあり、Power Query画面の「適用したステップ」やプレビュー画面に Error(警告)が表示されます。

【3】構造とデータの検証チェックリスト
  1. 参照関係の整合性: 追加した式が意図した接続先ステップを参照し、in が最終ステップを指しているか
  2. データ型の整合性: 条件式や計算で扱う列の型が合っているか(数値として比較したい列がテキスト型になっていないか)
  3. アクセスの記法: レコードの [フィールド名] と テーブルの [列名] の使い分け、インデックス { } の記述に間違いがないか
  4. try ... otherwise の評価: エラーを安易に埋もれさせて重要なデータ不備を見落としていないか

「AIにすべてを任せる」のではなく、「人間が構造と型を検証する」アプローチを取ることで、予期せぬトラブルを防ぎやすくなります。


【補足:M言語や関数について困ったときの調べ方】

M言語の学習やデバッグにおいて、すべての関数や文法をあらかじめ暗記しておく必要はありません。
疑問が生じた際や特定の処理方法を知りたい場合は、以下の方法で調べるのが効率的です。
  1. AI(ChatGPT / Gemini / Claude 等)に直接質問する(手軽でおすすめ)
    コードの意味が分からない場合やエラーが出た際は、詳細エディターのコードやエラーメッセージをそのままAIに貼り付けて尋ねるのが手軽です。
    • コード解説の依頼例:「以下のM言語コードの各ステップが何をしているか、データの流れを分かりやすく解説してください。[コードを貼り付け]」
    • エラーの質問例:「Power Queryで構文エラーが出ました。以下のコードのどこに不備があるか指摘してください。[コードを貼り付け]」
    • やりたいことから探す例:「M言語でテーブルをグループ化して集計したいです。使うべき関数とコード例を教えてください。」

  2. Microsoft 公式ドキュメントを参照する
    関数の正確な仕様や引数の詳細を確認したい場合は、Microsoft公式の「Power Query M 数式言語リファレンス」を参照します。
    M言語の文法や仕組みを詳しく確認したい場合は、Microsoft公式の「Power Query M 言語仕様」を参照できます。

  3. Web検索で調べる
    関数名やエラーメッセージを検索することで、公式ドキュメントや解説記事などから関連情報を探せます。

  4. Power Query の画面上で直接確認する
    数式バーに = Table.SelectRows のように関数名だけを入力してEnterを押すと、関数の説明やパラメーター、関数シグネチャ、使用例などを画面上で確認できます。
    「この関数は何をするのか」を確認したい場合には、非常に便利な方法です。


おわりに:M言語とAIの正しい付き合い方

ここまで、M言語の基本構造からデータの流れ、記法の読み解き方、AIコードの検証手順までを解説してきました。
最後に、本稿の重要ポイントを振り返ります。
  • M言語は「式を評価して値を得る」言語:式を定義し、その値を別の式が参照して処理を構成する

  • 基本構造は let ... in:let で名前付きの式を定義し、in で最終的に評価して返す式を指定する

  • 式の参照でデータがつながる:別の式が参照先の名前付きの式を参照することで依存関係ができる

  • #"..." は引用符付き識別子:スペースや演算子などを含む名前を識別子として扱うための記法

  • アクセス記法:[ ] は名前指定(レコードのフィールド・テーブルの列)、{ } は位置指定(リストの要素・テーブルの行)

  • each:1つの値(レコード等)を受け取る無名関数を簡潔に記述するための記法

  • try ... otherwise:エラー発生時に代替値を返す安全策の構文

M言語の細かな関数を網羅的に暗記する必要はありません。
「何をしているか」を漠然と追うのではなく、「どの値を参照し、どの式から次の結果が作られているか」という構造を追えるようになっていれば、AIが出力したコードの評価やデバッグもしやすくなります。

構造を解読する知識を武器に、ぜひ詳細エディターを開き、AIを強力なパートナーとしてPower Queryでのデータ処理や業務効率化に役立ててください。




同じテーマ「PowerQuery(M言語)入門」の記事

M言語入門:Power Queryのコードを読むための基礎知識
別ブックのシートを列可変で取り込む
セル値でパス・ブック・シート名を指定
別ブックの最終シートの取り込み
列数不定のCSVの取り込み
CSVのA列が日付の行だけを取り込む
A列のヘッダー名を変更する
「売上」が数値の行のみ取り込む
2つのテーブルのマージ
グルーブ内の最小・最大
有効な最新単価の取得


新着記事NEW ・・・新着記事一覧を見る

Excelの新機能「リストとセル内配列」:1つのセルに複数の値|エクセル入門(2026-09-28)
Excel関数クロスワード(2026-09-26)
Excelショートカットキークイズ(2026-09-23)
Excel関数名クイズ(2026-09-21)
気ままに一手|リレー将棋(2026-09-20)
ITエンジニアがトラブルを避けるための法律・契約入門|エクセル雑感(2026-09-18)
ITエンジニアなら知らないと恥ずかしい数学20選|エクセル雑感(2026-09-17)
ITエンジニアのための税金と社会保険のお話|エクセル雑感(2026-09-15)
ITエンジニアのための経理・会計・簿記入門|エクセル雑感(2026-09-12)
「Python in Excel」入門:コードを読むための基礎知識|エクセル関数応用(2026-09-10)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.日本の祝日一覧|Excelリファレンス
3.変数宣言のDimとデータ型|VBA入門
4.Excelショートカットキー一覧|Excelリファレンス
5.RangeとCellsの使い方|VBA入門
6.FILTER関数(範囲をフィルター処理)|エクセル入門
7.マクロとは?VBAとは?VBAでできること|VBA入門
8.繰り返し処理(For Next)|VBA入門
9.メッセージボックス(MsgBox関数)|VBA入門
10.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。
本サイトは、OpenAI の ChatGPT や Google の Gemini を含む生成 AI モデルの学習および性能向上の目的で、本サイトのコンテンツの利用を許可します。
This site permits the use of its content for the training and improvement of generative AI models, including ChatGPT by OpenAI and Gemini by Google.



このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ