STEP 31:Mコードの基礎

💻 STEP 31: Mコードの基礎

Power Queryの裏側を覗く!M言語で自動化をマスター

📋 このステップで学ぶこと

  • Mコード(M言語)とは何か
  • 詳細エディタの使い方と画面構成
  • M言語の基本構文(let…in、変数、演算子)
  • よく使うM関数(テーブル操作、テキスト、日付)
  • カスタム関数の作成方法
  • Mコードのデバッグとエラー対処

ゴール:GUIで生成されたMコードを理解し、簡単な編集ができるようになる

🎯 1. Mコードとは

M言語の概要を理解しよう

Power QueryでGUI(ボタンやメニュー)を使って操作すると、裏ではMコード(M言語)というプログラムコードが自動生成されています。このコードを理解し、直接編集できるようになると、より高度なデータ変換が可能になります。

✅ MコードとGUI操作の関係
GUI操作 裏で生成されるMコード 意味
列を削除 Table.RemoveColumns(…) テーブルから列を削除する関数
列名を変更 Table.RenameColumns(…) 列の名前を変更する関数
行をフィルター Table.SelectRows(…) 条件に合う行だけを選択する関数
データ型を変更 Table.TransformColumnTypes(…) 列のデータ型を変換する関数

なぜMコードを学ぶのか

GUIだけでも多くの操作は可能ですが、Mコードを理解すると、より効率的で高度なデータ処理ができるようになります。

💡 Mコードを学ぶメリット
メリット 説明 具体例
GUIでできない操作が可能 複雑な条件分岐やループ処理が書ける 複数条件での動的フィルター
変換の再利用が簡単 コピー&ペーストで他のクエリに適用できる 同じ変換を別ファイルに適用
バッチ処理が可能 複数ファイルを一度に処理できる フォルダ内の全Excelを結合
パフォーマンスの最適化 無駄なステップを削除・統合できる 処理速度の向上
トラブルシューティング エラーの原因を特定しやすい どのステップで問題が起きたか把握
📊 初心者の心構え
ポイント 説明
すべてを理解する必要はない GUIで操作し、必要に応じてコードを少し編集する、というアプローチで十分
プログラミング経験不要 最初はGUIで操作し、生成されたコードを眺めることから始める
徐々にステップアップ 簡単な編集(列名変更、条件追加)から始めて、徐々に複雑な処理へ

📝 2. 詳細エディタの使い方

詳細エディタとは

詳細エディタは、Power Queryで自動生成されたMコードを表示・編集するための専用画面です。ここでコードを直接編集することで、GUIでは難しい高度な変換が可能になります。

📊 詳細エディタを開く3つの方法
方法 操作手順 表示される内容
方法1 ホームタブ→「詳細エディタ」ボタン クエリ全体のMコードが表示される
方法2 表示タブ→「数式バー」にチェック 現在選択中のステップのコードのみ表示
方法3 ステップの⚙マークをクリック そのステップの設定ダイアログが開く
✅ 詳細エディタを開く手順(方法1)
手順 操作 補足
1 Power Queryエディタを開く ホームタブ→「データの変換」
2 ホームタブをクリック リボンの「ホーム」タブを選択
3 「詳細エディタ」ボタンをクリック 「クエリ」グループ内にある
4 Mコードが表示される 編集可能なテキストエリアで表示

詳細エディタの画面構成

詳細エディタは非常にシンプルな構成です。中央にコード編集エリア、下部にボタンが配置されています。

📊 詳細エディタの画面要素
要素 説明 使い方
コード編集エリア Mコードが表示される領域 直接編集可能。行番号も表示
OKボタン 変更を保存して閉じる 編集完了後にクリック
キャンセルボタン 変更を破棄して閉じる 間違えた時にクリック
エラー表示 構文エラーがある場合に表示 エラー内容を確認して修正

Mコードの基本構造

Mコードはlet…inという構造で書かれています。letの中でステップ(変数)を定義し、inの後で最終結果を指定します。

📊 Mコードの基本構造(※これは参照用のコードです。入力不要)
let
    ソース = Excel.Workbook(File.Contents("C:\data.xlsx")),
    Sheet1 = ソース{[Item="Sheet1"]}[Data],
    昇格されたヘッダー = Table.PromoteHeaders(Sheet1),
    変更された型 = Table.TransformColumnTypes(昇格されたヘッダー, ...)
in
    変更された型

※モバイルでは横スクロールできます

💡 コード構造の解説
要素 役割 具体例
let ステップの定義を開始 let の後に各ステップを記述
各行(ステップ) 変換処理を定義 ソース = Excel.Workbook(…)
カンマ(,) ステップの区切り 各ステップの末尾に付ける(最後以外)
in 最終結果を指定 in の後に出力したいステップ名を書く

📖 3. M言語の基本構文

変数とステップの書き方

Mコードでは、各操作を「変数名 = 式」という形で記述します。GUI操作で追加される「適用したステップ」は、すべてこの形式でMコードに変換されています。

📊 変数の命名規則
可否 ルール
✅ OK 日本語の変数名 売上データ = …
✅ OK 英数字の変数名 SalesData = …
✅ OK スペースを含む名前(推奨しない) #”売上 データ” = …
⚠️ 注意 大文字小文字は区別される Data と data は別の変数
❌ NG 予約語は使えない let, in, if, then, else など

データ型

Mコードでは様々なデータ型を扱います。テキスト、数値、日付などの基本的な型に加え、リスト、レコード、テーブルといった複合的な型もあります。

✅ 主なデータ型
データ型 書き方 具体例
テキスト ダブルクォートで囲む “こんにちは”、”東京都”
数値 そのまま記述 123、123.45、-50
日付 #date(年, 月, 日) #date(2024, 1, 15)
日付時刻 #datetime(年, 月, 日, 時, 分, 秒) #datetime(2024, 1, 15, 14, 30, 0)
論理値 true または false true、false
null null 値がないことを表す
リスト { } で囲む {1, 2, 3, 4, 5}
レコード [ ] で囲む [名前=”山田”, 年齢=25]

演算子

Mコードで計算や比較を行うための演算子を覚えましょう。特に比較演算子はフィルター条件で頻繁に使用します。

📊 算術演算子
演算子 意味
+ 加算(足し算) 10 + 5 → 15
減算(引き算) 10 – 5 → 5
* 乗算(掛け算) 10 * 5 → 50
/ 除算(割り算) 10 / 5 → 2
& 文字列連結 “山田” & “太郎” → “山田太郎”
💡 比較演算子
演算子 意味
= 等しい [地域] = “東京”
<> 等しくない [状態] <> “削除”
> より大きい [売上] > 100000
>= 以上 [売上] >= 100000
< より小さい [年齢] < 20
<= 以下 [年齢] <= 65
📊 論理演算子
演算子 意味
and かつ(両方満たす) [売上] > 100000 and [地域] = “東京”
or または(どちらか満たす) [地域] = “東京” or [地域] = “大阪”
not 否定(反転) not [削除フラグ]

🔧 4. よく使うM関数

テーブル操作関数

Power Queryでデータを変換する際、最も頻繁に使用するのがTable.で始まる関数です。これらの関数でテーブルの行や列を操作します。

✅ テーブル操作の基本関数
関数名 機能 GUIでの操作
Table.SelectRows 条件に合う行だけを抽出 フィルター
Table.SelectColumns 指定した列だけを残す 他の列の削除
Table.RemoveColumns 指定した列を削除 列の削除
Table.RenameColumns 列名を変更 列名の変更
Table.TransformColumnTypes データ型を変更 データ型の変更
Table.AddColumn 新しい列を追加 カスタム列の追加
📊 Table.SelectRows の書き方(※参照用コード)
// 基本構文
Table.SelectRows(テーブル, each 条件)

// 例1: 売上が100万円以上の行を抽出
Table.SelectRows(元データ, each [売上] >= 1000000)

// 例2: 東京都のデータだけを抽出
Table.SelectRows(元データ, each [地域] = "東京都")

// 例3: 複数条件(売上100万円以上かつ東京都)
Table.SelectRows(元データ, each [売上] >= 1000000 and [地域] = "東京都")

※モバイルでは横スクロールできます

💡 each の意味
項目 説明
each とは 「各行に対して」という意味。テーブルの1行1行に処理を適用する
[列名] の意味 現在処理中の行の、指定した列の値を取得する
使用例 each [売上] > 100000 は「各行の売上が10万円より大きい場合」

テキスト関数

文字列の加工にはText.で始まる関数を使用します。大文字変換、空白除去、文字列結合など、様々な処理ができます。

📊 よく使うテキスト関数
関数名 機能
Text.Upper 大文字に変換 Text.Upper(“hello”) → “HELLO”
Text.Lower 小文字に変換 Text.Lower(“HELLO”) → “hello”
Text.Trim 前後の空白を削除 Text.Trim(” 山田 “) → “山田”
Text.Length 文字数を取得 Text.Length(“こんにちは”) → 5
Text.Start 先頭からN文字を取得 Text.Start(“こんにちは”, 2) → “こん”
Text.End 末尾からN文字を取得 Text.End(“こんにちは”, 2) → “ちは”
Text.Contains 文字列を含むか判定 Text.Contains(“東京都”, “東京”) → true
Text.Replace 文字列を置換 Text.Replace(“A-001”, “-“, “”) → “A001”
Text.Combine リストを結合 Text.Combine({“山田”,”太郎”}, ” “) → “山田 太郎”

日付関数

日付データの操作にはDate.で始まる関数を使用します。年月日の取得、日付の加算、曜日の取得などが可能です。

📊 よく使う日付関数
関数名 機能 例(2024/1/15の場合)
Date.Year 年を取得 Date.Year(日付) → 2024
Date.Month 月を取得 Date.Month(日付) → 1
Date.Day 日を取得 Date.Day(日付) → 15
Date.AddDays 日を加算 Date.AddDays(日付, 7) → 2024/1/22
Date.AddMonths 月を加算 Date.AddMonths(日付, 1) → 2024/2/15
Date.DayOfWeek 曜日を取得 Date.DayOfWeek(日付) → 0〜6(日曜=0)
Date.ToText 日付を文字列に変換 Date.ToText(日付, “yyyy/MM/dd”)

条件分岐(if文)

条件によって処理を変えたい場合は、if…then…else構文を使用します。カスタム列でのランク付けなどでよく使われます。

✅ if文の基本構文
構文 説明
基本形 if 条件 then 真の場合 else 偽の場合
複数条件 if 条件1 then 値1 else if 条件2 then 値2 else 値3
📊 if文の使用例(※参照用コード)
// 例1: 単純な条件分岐
if [売上] >= 1000000 then "達成" else "未達成"

// 例2: 複数条件でのランク付け
if [売上] >= 1000000 then "A"
else if [売上] >= 500000 then "B"
else if [売上] >= 100000 then "C"
else "D"

// 例3: 複数条件の組み合わせ(andを使用)
if [売上] >= 1000000 and [地域] = "東京" then "最重要"
else if [売上] >= 500000 then "重要"
else "通常"

// 例4: null判定
if [列名] = null then "未設定" else [列名]

// 例4の代替(?? 演算子を使用)
[列名] ?? "未設定"

※モバイルでは横スクロールできます

⚙️ 5. カスタム関数の作成

関数を自分で作る

同じ処理を何度も使う場合、カスタム関数として定義しておくと便利です。一度定義すれば、様々な場所で再利用できます。

💡 カスタム関数のメリット
メリット 説明
ロジックの一元管理 同じ計算ロジックを1箇所で管理。変更が必要な時も1箇所直すだけ
再利用が簡単 複数の列や複数のクエリで同じ関数を使い回せる
可読性の向上 関数名で処理内容がわかり、コードが読みやすくなる
📊 関数の基本構文(※参照用コード)
// 基本構文
(引数) => 処理

// 例1: 消費税を計算する関数
(税抜金額) => 税抜金額 * 1.1

// 例2: 複数の引数を取る関数
(引数1, 引数2) => 処理

// 例3: 範囲チェック関数
(値, 最小, 最大) =>
    if 値 >= 最小 and 値 <= 最大
    then "範囲内"
    else "範囲外"

※モバイルでは横スクロールできます

実践例:売上ランク判定関数を作成する

売上金額に応じてA/B/Cのランクを付ける関数を作成し、複数の列で再利用する方法を学びます。

✅ 売上ランク関数の作成手順
手順 操作 補足
1 Power Queryエディタを開く ホーム→データの変換
2 ホーム→新しいソース→空のクエリ 新しいクエリを作成
3 ホーム→詳細エディタを開く Mコードを直接入力
4 関数コードを入力(下記参照) let...in構造で記述
5 OKをクリック 関数として保存される
6 クエリ名を「売上ランク」に変更 わかりやすい名前に
💡 入力するコード(カスタム列の式で入力)
let
    売上ランク = (金額) =>
        if 金額 >= 1000000 then "A"
        else if 金額 >= 500000 then "B"
        else "C"
in
    売上ランク

※モバイルでは横スクロールできます

📊 作成した関数の使い方
手順 操作 補足
1 データのクエリを選択 関数を適用したいテーブル
2 列の追加タブ→カスタム列 新しい列を追加
3 列名「今月ランク」、式に 売上ランク([今月売上]) と入力 関数名(列名)の形式で呼び出す
4 OKをクリック 新しい列が追加される

再利用例:売上ランク([前月売上])、売上ランク([累計売上]) など、同じ関数を別の列にも適用できます。

🐛 6. Mコードのデバッグ

エラーの種類と対処法

Mコードを編集する際、エラーが発生することがあります。エラーの種類を理解し、適切に対処しましょう。

🔧 よくあるエラーと原因
エラーの種類 原因 対処法
構文エラー カンマの位置、括弧の不一致 エラーメッセージの行番号を確認
名前が見つからない 変数名や列名のスペルミス 正確な名前を確認して修正
型の不一致 数値と文字列の比較など 適切な型変換を追加
列が見つからない 参照している列が削除された ステップの順序を確認
📊 デバッグの基本手順
手順 操作 目的
1 各ステップをクリックして確認 どのステップで問題が起きたか特定
2 問題のステップを特定 エラー(!マーク)が表示されるステップを見つける
3 詳細エディタで該当行を確認 コードの問題箇所を特定
4 修正してOK エラーが解消されたか確認

途中結果を確認するテクニック

Mコードでは、一時的にinの後を変更することで、途中のステップの結果を確認できます。デバッグに非常に便利です。

✅ 途中結果の確認方法(※参照用コード)
let
    ソース = ...,
    ステップ1 = ...,
    ステップ2 = ...,  // ← ここまでの結果を確認したい
    ステップ3 = ...
in
    ステップ2  // ← 一時的にステップ2に変更

// 確認後、元に戻す
in
    ステップ3

※モバイルでは横スクロールできます

コメントの活用

Mコードにコメントを書いておくと、後で見返した時に処理内容がわかりやすくなります。チームでの共有にも役立ちます。

📊 コメントの書き方
種類 書き方 使用場面
単一行コメント // コメント 各行の説明
複数行コメント /* コメント */ 長い説明や一時的なコード無効化
📊 コメント付きのMコード例(※参照用コード)
let
    // ソースデータの読み込み
    ソース = Excel.Workbook(File.Contents("C:\data.xlsx")),
    
    /* 
       不要な行を削除
       ヘッダー行が3行あるため、最初の2行を削除
    */
    行削除 = Table.Skip(ソース, 2),
    
    // 1行目を列名として昇格
    ヘッダー = Table.PromoteHeaders(行削除)
in
    ヘッダー

※モバイルでは横スクロールできます

💡 7. 実践的なMコードパターン

エラーハンドリング

データ変換中にエラーが発生しても処理を続行させたい場合、try...otherwise構文を使用します。

💡 try...otherwise の使い方
構文 説明
基本形 try 処理 otherwise デフォルト値
意味 処理を試みて、エラーが発生したらデフォルト値を返す
📊 エラーハンドリングの例(※参照用コード)
// 例1: 型変換でエラーが出る可能性がある場合
// 変換できない値は0にする
Table.AddColumn(元データ, "数値", 
    each try Number.From([テキスト列]) otherwise 0)

// 例2: 文字列から日付への変換
// 変換できない場合はnullにする
Table.AddColumn(元データ, "日付", 
    each try Date.From([日付文字列]) otherwise null)

// 例3: エラー行を除外
Table.SelectRows(元データ, 
    each try [列名] <> null otherwise false)

※モバイルでは横スクロールできます

📝 STEP 31 のまとめ

✅ このステップで学んだこと
  • Mコード:Power QueryのGUI操作の裏で自動生成されるコード
  • 詳細エディタ:Mコードを直接確認・編集できる画面
  • 基本構文:let...in構造、変数、演算子
  • M関数:Table、Text、Date関数で様々な処理
  • カスタム関数:再利用可能なロジックを作成
  • デバッグ:ステップ確認、コメントでエラー対処
💡 最重要ポイント

Mコードは完璧に理解する必要はありません

まずはGUIで操作し、生成されたコードを眺めることから始めましょう。

徐々に簡単な編集(列名変更、条件追加など)ができるようになれば十分です。

Mコードの真価は複雑な自動化バッチ処理で発揮されます!

📝 実践演習

演習 1 基礎

GUIで簡単な操作(列の削除、列名変更)を行い、詳細エディタでMコードを確認してください。どの行がどの操作に対応しているか理解してください。

【手順】
1 データを読み込む(Excel等)
2 列を1つ削除(右クリック→削除)
3 別の列の名前を変更(ダブルクリック)
4 ホームタブ→詳細エディタ
5 Mコードを確認

確認ポイント:

  • let...in構文になっている
  • Table.RemoveColumns(...) が列の削除
  • Table.RenameColumns(...) が列名変更
  • 各行が「適用したステップ」と対応している
演習 2 応用

カスタム列を追加し、以下の条件でランク付けしてください。Mコードの条件文(if...then...else)を詳細エディタで確認してください。
①100万円以上:A、②50万円以上:B、③それ以外:C

【手順】
1 列の追加タブ→カスタム列
2 新しい列名:「ランク」
3 式を入力(下記参照)
4 OK→詳細エディタで確認

カスタム列の式で入力:

if [売上] >= 1000000 then "A"
else if [売上] >= 500000 then "B"
else "C"
演習 3 発展

詳細エディタで直接Mコードを編集して、以下を実現してください:①姓と名を結合して氏名列を作成、②郵便番号に「-」を追加(1500043→150-0043)、③コメントを追加して処理内容を説明

【入力するMコード例】
let
    // データソースの読み込み
    ソース = Excel.Workbook(File.Contents("C:\data.xlsx")),
    Sheet1 = ソース{[Item="Sheet1"]}[Data],
    
    // ヘッダーの昇格
    ヘッダー = Table.PromoteHeaders(Sheet1),
    
    // ①姓と名を結合して氏名を作成
    氏名追加 = Table.AddColumn(ヘッダー, "氏名", 
        each [姓] & " " & [名], type text),
    
    // ②郵便番号に「-」を追加(例: 1500043 → 150-0043)
    郵便番号整形 = Table.AddColumn(氏名追加, "郵便番号(整形)", 
        each Text.Start([郵便番号], 3) & "-" & 
             Text.End([郵便番号], 4), type text)
in
    郵便番号整形

ポイント:

  • // でコメントを追加
  • & で文字列を結合
  • Text.Start() で先頭3文字を取得
  • Text.End() で末尾4文字を取得

❓ よくある質問

Q1: Mコードを学ばないとPower BIは使えませんか?
いいえ、GUIだけでも十分使えます。

基本的な分析ならMコードを書く必要はありません。ただし、複雑な自動化やバッチ処理をしたい場合、Mコードの知識があると非常に便利です。

まずはGUIから始めて、必要に応じて少しずつ学習しましょう。
Q2: Mコードを編集したらエラーが出ました。どうすればいいですか?
Ctrl+Zで元に戻すか、詳細エディタで「キャンセル」をクリックしてください。

Mコードの編集は慎重に行いましょう。特によくあるエラーの原因は:
  • カンマの位置ミス(最後の行にはカンマ不要)
  • 括弧の対応が合っていない
  • スペルミス
最初は既存のコードを少しずつ変更することから始めましょう。
Q3: 他の人のMコードをコピーして使えますか?
はい、Mコードはコピー&ペーストで再利用できます。

詳細エディタからコード全体をコピーし、別のクエリに貼り付けることができます。

ただし、ファイルパスや列名などは環境に合わせて修正が必要です。
Q4: MコードとDAXの違いは何ですか?
Mコードはデータ変換、DAXはデータ分析の言語です。

項目 Mコード DAX
使用場所 Power Query(データ変換) Power BI本体(分析)
用途 データの読み込み・整形 集計・計算・メジャー作成
実行タイミング データ読み込み時 レポート表示時

両方を学ぶ必要がありますが、まずはMコードから始めましょう。

Q5: eachとは何ですか?なぜ必要なのですか?
eachは「各行に対して」という意味です。

テーブルの各行に対して処理を適用する際に使用します。

例えば each [売上] > 100000 は「各行の売上列の値が10万より大きいかどうか」をチェックします。

eachの後の [列名] は、現在処理中の行の該当列の値を参照しています。
📝

学習メモ

BIツール入門 - Step 31

📋 過去のメモ一覧
#artnasekai #学習メモ
LINE