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

Power Query(パワークエリ)で使われ、Power BIでのデータ取得・変換にも使われているのが「M言語(Power Query M Formula Language)」です。
生成AIが普及した現在において重要なのは、コードをゼロから書くことではなく、AIが生成したコードや既存クエリの「構造」を正しく読み解き、データの流れを把握することです。
第1章:M言語の正体と基本構造
第2章:M言語の核心「参照の連鎖でデータを渡す」
第3章:値の構造をたどる([ ] と { } の役割)
第4章:特殊構文とエラー処理(each / try...otherwise)
第5章:未知の関数に出会ったときの読み方(名前からの推測)
第6章:AIが生成したコードを解読・検証する実践手順
【補足:M言語や関数について困ったときの調べ方】
おわりに:M言語とAIの正しい付き合い方
導入:M言語を学ぶ前に知っておくべきこと
従来は、こうした専門言語を活用するには、M言語の構文や関数を体系的に学ぶ必要がありました。
しかし、生成AIが普及した現在、学習のアプローチは大きく変わっています。
AIは基本的なコードから複雑な変換処理まで生成できます。
しかし、出力されたコードをPower Queryの「詳細エディター」に貼り付けたとき、エラーが出たらどう対処すべきでしょうか。
あるいは、既存のクエリが「何をどう処理しているのか」を理解できなければ、手直しやデバッグを行うことはできません。
- AIが出力したコードや既存クエリの「構造」を読み解くこと
- ステップ間で「どの値を参照しているか」を把握すること
第1章:M言語の正体と基本構造
1. M言語の正体:「式を評価して値を得る」言語
VBAなどでよく見られる「セルを書き換える」「ループ処理で順番に状態を変更する」といった発想ではなく、M言語は「式を評価すると必ず何らかの値になる」という仕組みを基本にしています。
2. 得られた値に「名前(識別子)」をつける
3. 別の式がその「名前」を参照して、次の新しい値を評価する
このシンプルな一本の原則を理解しておくと、テーブルの操作だけでなく、レコード、リスト、カスタム関数の読み解きにもスムーズにつながります。
2. 注意すべきルール:大文字・小文字の厳密性とコメント
それは「大文字と小文字を厳密に区別する(ケースセンシティブ)」ということです。
- 関数名: Table.SelectRows(正しい)と table.selectrows(小文字:エラーの原因)
- 文字列比較: "Apple" と "apple" は別の値として扱われる(抽出や結合で一致しない原因になります)
また、コード内の解説や処理の一時的な無効化にはコメント記法が使われます。
- // 1行コメント: 行末までをコメントとして無視
- /* 複数行コメント */: 囲まれた範囲全体をコメントとして無視
3. Power Queryのクエリで頻出する基本構造:let ... in ...
let
// 名前付きの式を定義する領域
Step1 = ...,
Step2 = ...
in
// 最終的に評価して返す式
Step2- let:各式に名前(識別子)をつけて定義する部分
- in:let で定義した値など、最終的に評価して返す式を指定する部分
M言語のコードでは、let 内で定義された名前付きの式が、Power QueryのGUI上では「適用したステップ」として画面に表示されます。
第2章:M言語の核心「参照の連鎖でデータを渡す」
1. ステップと識別子の関係:参照の連鎖を追う
しかし内部的には、定義した名前付きの式を、別の式が参照するという依存関係によって成り立っています。
↓ (参照)
[Filtered]
↓ (参照)
[Result]
なお、
M言語には部分的な遅延評価(Lazy Evaluation)の性質があり、let 内で定義した式は、単純に上から順番に実行されるとは限りません。
最終的に in で指定された結果を出力するために必要な式だけを逆算して評価するため、途中でどの式からも参照されていないステップが存在する場合、そのステップは評価されずにスキップされます。
2. コードで見るデータの流れ
let
Source = ..., // データ取得・定義を行うステップ(簡略表記)
Filtered = Table.SelectRows(Source, each [金額] > 1000),
Result = Table.Sort(Filtered, {{"日付", Order.Descending}})
in
Result- Source:データを表す値を定義します。
- Filtered:Table.SelectRows の対象として Source を参照し、条件を適用します。
- Result:Table.Sort の対象として Filtered を参照し、ソートを適用します。
- in Result:最終的に Result の評価結果を返します。
3. #"..."(引用符付き識別子)の正体
let
ソース = ..., // データ取得ステップ(簡略表記)
#"昇格されたヘッダー数" = Table.PromoteHeaders(ソース, [PromoteAllScalars=true]),
#"変更された型" = Table.TransformColumnTypes(#"昇格されたヘッダー数", {{"金額", Int64.Type}})
in
#"変更された型"#" " と " で囲むことで、スペースやキーワード、演算子など、通常の識別子としてそのまま記述できない文字を含む名前を識別子として扱えるようになります。
Power QueryがGUI操作時に自動生成する「昇格されたヘッダー数」や「変更された型」のようなステップ名では、間にスペースが含まれるなどの理由から、この引用符付き識別子の形式が使われます。
第3章:値の構造をたどる([ ] と { } の役割)
1. M言語における代表的なデータの「構造」
コードを解読するうえで特に頻出する基本的なデータ構造は、以下の3つです。
| データ構造 | 囲み記号 | 特徴・定義 | 基本アクセス記法 |
| レコード | [ ] | 名前と値を組み合わせた構造(1行分のデータや設定情報) | [フィールド名] で参照 |
| リスト | { } | 順序を持つ値の並び(列データや引数のグループ) | {インデックス} で参照(0始まり) |
| テーブル | 該当なし | 行(レコード)と列からなる表構造 | [列名] で列リスト、{行番号} で行レコード |
ここで重要なのは、記号 `[ ]` と `{ }` は、操作対象がレコードかテーブルかによって役割が変わるという点です。
それぞれの構造を具体的に確認します。
2. レコード [ ]:定義とフィールドアクセス
「フィールド名 = 値」というペアをカンマ区切りで保持します。
[ ID = 1, 商品名 = "りんご", 価格 = 150 ]
レコードに対して [フィールド名] を指定すると、そのフィールドの値を取得できます。
例えば上記レコードに対して [価格] を指定すると、値 150 が得られます。
3. リスト { }:定義とインデックスアクセス
同じ種類、あるいは異なる種類の値を並べることができます。
{ "りんご", "みかん", "バナナ" }
{ 100, 200, 300 }リストに対して {位置番号} を指定すると、該当する要素を取り出せます。M言語のインデックスは0始まり(0ベース)です。
例えば上記リストに対して {0} を指定すると "りんご"、{1} を指定すると "みかん" が得られます。
4. テーブルに対するデータ取り出し(構造の組み合わせ)
テーブルに対する要素の取り出しは、アクセス対象が「列」か「行」かによって記号を使い分けます。
- Source[金額] → 列を「リスト」として取り出す
テーブルに対して [列名] を指定すると、その列の値が並んだリストが得られます(※レコードに対する [ ] が単一フィールドを参照するのとは対照的です)。
Source[金額] // 実行結果:{ 1500, 800, 2300, ... } (金額列のリスト)
- Source{0} → 行を「レコード」として取り出す
テーブルに対して {インデックス} を指定すると、該当行がレコードとして取得できます。
Source{0} // 実行結果:[ ID = 1, 商品名 = "りんご", 価格 = 150 ] (先頭行のレコード)
- Source{0}[商品名] → 構造をたどって単一の値を取り出す
行指定 { } で取り出したレコードに対し、さらに [列名] を指定することで特定の値を取得できます。
Source{0}[商品名] // 実行結果:"りんご"
| 記述 | 対象 | 使う記法 | 得られるデータ構造 | コードの動作 |
| Source[列名] | テーブル | [ ] (名前指定) | リスト { } | テーブルから指定した列をリストとして取得 |
| Source{0} | テーブル | { } (位置指定) | レコード [ ] | テーブルから先頭行をレコードとして取得 |
| Source{0}[列名] | レコード | [ ] (名前指定) | 単一の値 | レコードから指定したフィールドの値を取得 |
このように、対象がレコードなのかテーブルなのかによって `[ ]` の意味が変わる点を意識すると、M言語のデータ抽出コードを正しく読み解けるようになります。
5. 補足:キーが存在しないときのエラーを防ぐ ?(オプショナル参照)
これは「もし指定した列やフィールドが存在しなければ、エラーを出さずに null を返す」という安全な参照方法(オプショナルアクセス)です。
データに特定の列が含まれているか不確定な場合によく使われます。
第4章:特殊構文とエラー処理(each / try...otherwise)
1. 関数の基本(アロー記法)と each の正体
M言語では、関数も数値や文字列などと同じく「値」の一つとして扱われます。
(x) => x + 1
例えば、この関数に 10 を渡すと、結果は 11 になります。
((x) => x + 1)(10)
(_) => _[金額] > 1000
ここで _ は、この関数が受け取る1つの引数を表しています。
(_) => _[金額] > 1000
each [金額] > 1000
each は、1つの値を受け取る関数を簡潔に記述するための構文です。
通常の関数の形で書くと、
Table.SelectRows(Source, (_) => _[金額] > 1000)
Table.SelectRows(Source, each [金額] > 1000)
コードを読むときは、
- each を見たら、「1つの値を受け取る関数を簡潔に書いている」と考える
2. エラーに対処する try ... otherwise 構文
これは「処理中にエラーが発生した場合に、安全に代替の値を返す」ための記述です。
try [金額] otherwise 0
データ変換時の不備に対処する安全策としてコード内で使われます。
第5章:未知の関数に出会ったときの読み方(名前からの推測)
これらを1つずつ暗記しようとする必要はありません。
詳細エディターで知らない関数に出会ったときは、関数名から「何を対象にしている処理なのか」を推測できるようになることが重要です。
| 接頭辞(カテゴリ) | 対象・領域 | 代表的な関数例と推測のポイント |
| 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が生成したコードを解読・検証する実践手順
1. 接続先となる「ステップ名」と「列名」を確認する
- 接続先となるステップ名(例: #"変更された型")
- 対象となる正確な列名(例: 売上金額)
【AIへの提示プロンプト例】
Power Queryの既存クエリにステップを追加したいです。- 接続先のステップ名:#"変更された型"
- 対象の列名:売上金額
- 処理内容:売上金額 列が 1000 以上の行に絞り込むステップを作成してください。
2. 組み込み時のチェックポイント(デバッグ手順)
既存クエリの末尾にAIが作成した新しいステップを追加する場合、以下の2点を調整します。
- 直前ステップの末尾にカンマ , を付与する
- in の直後の参照ステップ名を新しいステップ名に書き換える
let
ソース = ...,
変更された型 = ..., // ← 末尾にカンマを追加
抽出された行 = Table.SelectRows(変更された型, each [金額] > 1000) // ← 新ステップを挿入(末尾カンマなし)
in
抽出された行 // ← in の参照先を新しいステップ名に変更【2】エラーの段階を切り分けて確認する
トラブルが発生した場合は、エラーの性質を切り分けて対応します。
- ① 構文エラー(Syntax Error):
カンマの欠落やカッコ・引用符の閉じ忘れ等によって生じます。詳細エディターの下部に赤文字メッセージが表示され、コードを保存して閉じることができません。
※エラーメッセージ(「Token Comma expected」や「Token In expected」など)が表示された位置はパーサーが解釈に失敗した場所を示すため、必ずしもエラーメッセージ通りの位置や内容そのものを指しているとは限りません。メッセージ行だけでなく、直前行のカンマ有無やカッコの閉じ忘れ、`let ... in` の構造全体を確認することが解決のポイントです。 - ② 評価時・実行時エラー:
型の不一致(テキスト列に対する数値計算など)や存在しない列名の参照等によって生じます。構文上正しく記述できていても、実際のデータを評価する段階でエラーが発生することがあり、Power Query画面の「適用したステップ」やプレビュー画面に Error(警告)が表示されます。
【3】構造とデータの検証チェックリスト
- 参照関係の整合性: 追加した式が意図した接続先ステップを参照し、in が最終ステップを指しているか
- データ型の整合性: 条件式や計算で扱う列の型が合っているか(数値として比較したい列がテキスト型になっていないか)
- アクセスの記法: レコードの [フィールド名] と テーブルの [列名] の使い分け、インデックス { } の記述に間違いがないか
- try ... otherwise の評価: エラーを安易に埋もれさせて重要なデータ不備を見落としていないか
「AIにすべてを任せる」のではなく、「人間が構造と型を検証する」アプローチを取ることで、予期せぬトラブルを防ぎやすくなります。
【補足:M言語や関数について困ったときの調べ方】
疑問が生じた際や特定の処理方法を知りたい場合は、以下の方法で調べるのが効率的です。
- AI(ChatGPT / Gemini / Claude 等)に直接質問する(手軽でおすすめ)
コードの意味が分からない場合やエラーが出た際は、詳細エディターのコードやエラーメッセージをそのままAIに貼り付けて尋ねるのが手軽です。
- コード解説の依頼例:「以下のM言語コードの各ステップが何をしているか、データの流れを分かりやすく解説してください。[コードを貼り付け]」
- エラーの質問例:「Power Queryで構文エラーが出ました。以下のコードのどこに不備があるか指摘してください。[コードを貼り付け]」
- やりたいことから探す例:「M言語でテーブルをグループ化して集計したいです。使うべき関数とコード例を教えてください。」
- Microsoft 公式ドキュメントを参照する
関数の正確な仕様や引数の詳細を確認したい場合は、Microsoft公式の「Power Query M 数式言語リファレンス」を参照します。
M言語の文法や仕組みを詳しく確認したい場合は、Microsoft公式の「Power Query M 言語仕様」を参照できます。 - Web検索で調べる
関数名やエラーメッセージを検索することで、公式ドキュメントや解説記事などから関連情報を探せます。 - Power Query の画面上で直接確認する
数式バーに = Table.SelectRows のように関数名だけを入力してEnterを押すと、関数の説明やパラメーター、関数シグネチャ、使用例などを画面上で確認できます。
「この関数は何をするのか」を確認したい場合には、非常に便利な方法です。
おわりに:M言語とAIの正しい付き合い方
最後に、本稿の重要ポイントを振り返ります。
- M言語は「式を評価して値を得る」言語:式を定義し、その値を別の式が参照して処理を構成する
- 基本構造は let ... in:let で名前付きの式を定義し、in で最終的に評価して返す式を指定する
- 式の参照でデータがつながる:別の式が参照先の名前付きの式を参照することで依存関係ができる
- #"..." は引用符付き識別子:スペースや演算子などを含む名前を識別子として扱うための記法
- アクセス記法:[ ] は名前指定(レコードのフィールド・テーブルの列)、{ } は位置指定(リストの要素・テーブルの行)
- each:1つの値(レコード等)を受け取る無名関数を簡潔に記述するための記法
- try ... otherwise:エラー発生時に代替値を返す安全策の構文
「何をしているか」を漠然と追うのではなく、「どの値を参照し、どの式から次の結果が作られているか」という構造を追えるようになっていれば、AIが出力したコードの評価やデバッグもしやすくなります。
同じテーマ「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入門
- ホーム
- その他
- PowerQuery(M言語)入門
- M言語入門:Power Queryのコードを読むための基礎知識
このサイトがお役に立ちましたら「シェア」「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.
