この​記事で​分かる​こと

  • Power Queryの「記録して再生」の裏側にあるMコード(let式)の読み方と、UI操作との対応関係
  • クエリをパラメータ化し、対象月やフォルダパスを外部化して使い回すための具体的な書き方
  • カスタム関数の作り方と、try…otherwiseによるエラー処理を「見える化」する設計
  • 本番運用でクエリが壊れる典型パターンと、その防ぎ方

結論:Power Queryは​「記録して再生」の​先に、​Mコードと​いう​本体が​ある

Power Queryのユーザーインターフェースで「型の変更」「列の追加」「フィルター」といった操作をクリックしていくと、その裏側では毎回Mコード(Power Query M言語)が自動生成されています。ステップを積み重ねる操作は、実際にはlet式という1つの式の中に変数を1行ずつ足していく作業にほかなりません。多くの入門解説はここで止まりますが、月次更新テンプレートを事故なく運用するには、この生成されたMコードを読み、必要な箇所を自分で編集できることが実務上の分岐点になります。

以下では、Mコードの基本構文、ファイルパスや対象期間を外部化するパラメータ化クエリ、繰り返し処理を関数化するカスタム関数、そしてエラーを黙って落とさずに扱うtry…otherwiseによるエラー処理という4点に絞って、Microsoft公式のPower Query Mリファレンスに基づき実務目線で解説します。Power Queryの基本操作(CSV取込・型設定・フォルダ結合・更新ボタン)については、Power Query​入門​(財務実務)で扱っていますので、本記事はその続きとして読んでいただくことを想定しています。

UI操作と​Mコード​(let式)は​どう​対応しているか

Power Queryのエディター画面右側にある「適用されたステップ」は、そのままMコードのlet式の中の1行ずつの変数に対応しています。この対応関係を意識できると、「どのステップで何が起きているか」をコードレベルで確認でき、後から特定の1行だけを修正するといった精密な編集が可能になります。

Mコードを直接見るには、リボンの「表示」タブから「詳細エディター」を開きます。ここに表示されるのは、次のような構造を持つ1つの式です。

Power Query​(M)
let
    ステップ1の変数名 = 何らかの式,
    ステップ2の変数名 = ステップ1の変数名を使った式,
    ステップ3の変数名 = ステップ2の変数名を使った式
in
    ステップ3の変数名

ポイントは2つです。1つ目は、各行がコンマ区切りの変数定義であり、後の行は前の行の結果を参照して積み上がっていくという点。2つ目は、inの後ろに書かれた変数名が、そのクエリ全体の出力になるという点です。UIで最後に作られたステップが、常にin以降の変数として指定されます。

ステップ名に日本語や空白・記号を使うと、Mコード上では#"変更された型"のようにシャープと二重引用符で囲む記法(エスケープされた識別子)になります。これはPower Queryが自動的に行う表記であり、崩さずにそのまま使えば問題ありません。

図1:UI操作のステップとMコード(let式)の対応 Power Queryエディター「適用されたステップ」 詳細エディターに表示されるMコード ① ステップ「ソース」 経費入力テーブルを取得 Source = Excel.CurrentWorkbook() {[Name=”経費入力”]}[Content] ② ステップ「変更された型」 3列をすべてテキスト型に統一 #”変更された型” = Table. TransformColumnTypes(Source, {…}) ③ ステップ「金額を数値化」 try…otherwiseで安全に数値変換 #”金額を数値化” = Table.AddColumn( …, each try Number.FromText(…)) ④ 最後のステップが出力になる in #”エラー行フラグ”
図:UIの​各ステップは、​Mコードの​let式の​中の​1変数に​1対1で​対応する。

パラメータ​化クエリの​実務設計:ファイルパス・​対象月を​外に​出す

入門段階のクエリは、ファイルパスやシート名がコードの中に直接書き込まれています。これは1回限りの分析であれば問題ありませんが、毎月同じ構造のファイルを取り込むテンプレートにする場合、ファイル名や対象期間が変わるたびにMコードを書き換える必要が生じ、運用の負担と入力ミスの温床になります。これを解消するのがパラメータです。

リボンの「ホーム」タブから「パラメーターの管理」を開き、「新しいパラメーター」で名前・型・現在の値を設定します。例えば「対象月」という日付型のパラメータと、「フォルダパス」というテキスト型のパラメータを作成すると、これらはクエリの中で通常の変数と同じように参照できます。既存のクエリの数式バーで、日付や数値、文字列などの単純な値になっている箇所を右クリックし「パラメーターに変換」を選ぶことでも作成できます。

パラメータを使うと、対象月に応じてファイル名を組み立てる、といった処理が1行で書けます。

Power Query​(M)
let
    ファイル名 = "経費_" & Date.ToText(対象月, [Format="yyyyMM"]) & ".csv",
    Source = Csv.Document(
        File.Contents(フォルダパス & ファイル名),
        [Delimiter=",", Encoding=65001]
    ),
    #"ヘッダーを昇格" = Table.PromoteHeaders(Source)
in
    #"ヘッダーを昇格"

「対象月」パラメータの現在の値を書き換えるだけで、参照するファイルが自動的に切り替わります。EOMONTH・​EDATE​関数で期末日を扱うのと同じ発想で、MコードでもDate.EndOfMonthのような日付関数を使って月末フラグや期間ラベルを付与できます。

カスタム​関数で​クエリを​テンプレート​化する

パラメータ化した1本のクエリを、複数のファイルやシートに繰り返し適用したい場面は多くあります。この場合は、クエリをカスタム関数に変換します。変換ロジックを作ったサンプルクエリを右クリックし「関数の作成」を選ぶと、そのクエリで参照しているパラメータが、そのまま関数の引数になります。

手書きで関数を定義する場合のMコードは、次のような形になります。

Power Query​(M)
(対象月 as date, フォルダパス as text) as table =>
let
    ファイル名 = "経費_" & Date.ToText(対象月, [Format="yyyyMM"]) & ".csv",
    Source = Csv.Document(File.Contents(フォルダパス & ファイル名)),
    #"ヘッダーを昇格" = Table.PromoteHeaders(Source)
in
    #"ヘッダーを昇格"

引数の後ろのas dateやas textは型の指定です。省略も可能ですが、指定しておくと引数に想定外の型の値が渡された際にエラーとして検知でき、原因調査が速くなります。作成した関数は「フォルダから取得」で得たファイル一覧に対し「カスタム関数の呼び出し」で1件ずつ適用し、その結果を展開すれば、フォルダ内の全ファイルを1つの統合テーブルにまとめられます。この一連の流れは、Power Query​入門で扱った「フォルダから複数ファイルを結合する」機能を、自分で制御可能な形に分解したものと理解すると位置づけがつかみやすくなります。

1点注意が必要です。関数のもとになったサンプルクエリを更新すると関数側にも自動反映されますが、生成された関数のMコードを直接書き換えてしまうと、その時点でサンプルクエリとの連動が止まります。修正はサンプルクエリ側で行うのが基本です。

図2:パラメータ化クエリの本番運用アーキテクチャ ①パラメータ 対象月(Date) フォルダパス(Text) ②サンプルクエリ 1件分の変換ロジックを 作成・テスト ③カスタム関数化 「関数の作成」 パラメータが引数になる ④一括適用 フォルダ内の全ファイルへ カスタム関数を呼び出し → 統合テーブルへ展開 対象月・フォルダパスの値を書き換えるだけで、①〜④のロジックは変更せずに更新できる。
図:パラメータを​起点に、​サンプルクエリ→カスタム​関数→一括適用と​いう​順で​組み立てる。

エラー処理を​「見える化」する:try…otherwiseの​使い方

Power Queryは、型変換や数値化に失敗した値を自動的にエラー値として記録します。何も対処しなければ、更新時にエラーが発生した行があるという警告が出るだけで、どの値が原因かを1件ずつ確認する作業が発生します。この確認作業を仕組み化するのが、M言語のtry…otherwiseです。

以下は説明用の仮設例です。ある月の経費入力データに、1件だけ数値化できない値(”N/A”)が混入しているケースを考えます。

支店科目金額(入力値)金額_数値要確認
東京交通費12,50012500
東京消耗品費4,8004800
大阪交通費9,8009800
大阪消耗品費N/Anull要確認
名古屋交通費11,00011000

集計の考え方
「金額_数値」列のうち数値化に成功した4行(12,500/4,800/9,800/11,000)を合計すると、12,500+4,800+9,800+11,000=38,100円です。「要確認」が付いた1行は合計に含めず、別途目視確認の対象として残す、という設計にしています。エラーを合計から静かに消してしまわず、必ず「要確認」件数として可視化するのがポイントです。

このテーブルを作るMコードは次の通りです。try 式 otherwise 既定値は、式の評価がエラーになった場合にだけ既定値へフォールバックする構文です。

Power Query​(M)
let
    Source = Excel.CurrentWorkbook(){[Name="経費入力"]}[Content],
    #"変更された型" = Table.TransformColumnTypes(
        Source,
        {{"支店", type text}, {"科目", type text}, {"金額", type text}}
    ),
    #"金額を数値化" = Table.AddColumn(
        #"変更された型",
        "金額_数値",
        each try Number.FromText([金額]) otherwise null
    ),
    #"エラー行フラグ" = Table.AddColumn(
        #"金額を数値化",
        "要確認",
        each if [金額_数値] = null then "要確認" else ""
    )
in
    #"エラー行フラグ"

主なエラー処理の構文・関数を整理すると次の通りです。

構文・関数用途例
try 式 otherwise 既定値エラー時に既定値へ置き換える、最も基本的な形try Number.FromText([金額]) otherwise null
try 式 catch (e) => 式エラーの内容(レコード)を使って処理を分岐したい場合try Number.FromText([金額]) catch (e) => null
Table.ReplaceErrorValues列単位でエラー値をまとめて置換するTable.ReplaceErrorValues(t, {{"金額_数値", 0}})
error [Reason=..., Message=...]自分で意図的にエラーを発生させ、原因を記録するerror [Reason="ValidationError", Message="金額が負の値です"]

実務で​よく​使う​Mコードパターン

詳細エディターを自分で編集できるようになると、UI操作だけでは組みにくい処理を短いコードで実現できます。財務実務で頻出するパターンを3つ紹介します。

条件分岐(if…then…else)。UIの「条件列」機能でも近いことはできますが、条件が複雑になるとMコードで直接書いたほうが見通しが良くなります。例えば金額の正負で科目区分を振り分ける場合、each if [金額_数値] < 0 then "マイナス" else "プラス"のように書けます。

日付処理。Date.EndOfMonthで対象日が属する月の月末日を取得できます。月次データに「当月分か、翌月にずれ込んだ計上か」を判定するフラグを付ける際などに使えます。日付関数の実務的な使い分けそのものは、Excelワークシート関数側のEOMONTH・​EDATE​関数とあわせて理解しておくと、どちらの層で処理すべきかを判断しやすくなります。

動的なソース切替。パラメータで受け取ったフォルダパスやファイル名の一部を文字列結合し、参照先を切り替える書き方は、s3・s4で紹介した通りです。同じロジックを「今月分」「先月分」「四半期集計用」など複数の呼び出し方で使い回せるのが、パラメータ化・関数化の実務上の価値です。

本番運用で​壊れやすい​ポイントと​防ぎ方

Mコードを直接編集できるようになると自由度が上がる一方、壊れ方も一段階複雑になります。運用前に押さえておきたい点を整理します。

構文エラーの典型。詳細エディターは末尾のコンマ忘れ、波括弧・角括弧の対応崩れ、大文字小文字の違い(Mコードは大文字小文字を区別します)でエラーになります。エディターは構文エラーの有無を表示してくれるので、保存前に必ず確認します。

カスタム関数を直接編集しない。s4で触れた通り、サンプルクエリから生成した関数のコードを直接書き換えると、その時点でサンプルクエリとの自動連動が止まります。修正は必ずサンプルクエリ側で行い、変更を関数に反映させる運用にします。

個人依存のパスにしない。フォルダパスをパラメータ化しても、値そのものが個人のPC環境に固有のパスであれば、ファイルを引き継いだ担当者の環境では動きません。共有ドライブやOneDrive・SharePointなど、チームで共通してアクセスできる場所を前提にパスを設計します。

M言語がすべての自動化を担うわけではない。Power Query Mはデータの取得・変換(ETL的な処理)に強い一方、ワークシート上のボタン操作やダイアログの自動化、他のOfficeアプリとの連携といった領域はVBAマクロの領域です。「データを整形して読み込む」部分はPower Query、「読み込んだ後にワークブック内で何かを動かす」部分はVBA、という役割分担で考えると設計しやすくなります。

整形後のデータを動的配列関数で加工したい場合は、Power Query側で列構成を安定させてから、ワークシート側でFILTERやUNIQUEなどの関数につなぐと、どちらの層で何が起きているかを追いやすくなります。

よく​ある​質問​(FAQ)

Power Queryの​M言語は、​VBAの​代わりに​なりますか。

用途が​異なります。​M言語は​データの​取得・変換に​特化した​関数型言語で、​ワークシートの​外部​ファイル​読込や​整形を​「更新」ボタン1つで​再実行できる​形に​するのが​得意です。​一方で​ボタンクリックの​自動化や​ダイアログ​操作、​他アプリとの​連携は​VBAの​領域です。​同じ​「自動化」でも​守備範囲が​違う​ため、​扱う​データの​入り口を​Power Query、​その後の​ワークブック​内操作を​VBAと​役割分担して​考えるのが​実務的です。

UI操作で​作った​クエリを、​後から​Mコードで​直接編集しても​壊れませんか。

直接編集は可能ですが、慣れないうちは元のクエリを複製してから編集することをお勧めします。ステップ名に日本語や記号を含む場合は#"ステップ名"という記法になっている点、コンマや括弧の対応が崩れると構文エラーになる点に注意してください。詳細エディターは保存前に構文エラーの有無を表示してくれます。

パラメータに​個人の​PC上の​ファイルパスを​直書きしても​大丈夫ですか。

一時的な​検証であれば​問題ありませんが、​複数人で​共有する​テンプレートに​する​場合は​避けるべきです。​パスが​個人の​環境に​固有だと、​ファイルを​引き​継いだ​担当者の​環境では​参照先が​見つからず​エラーに​なります。​共有​ドライブや​OneDrive・​SharePointなど、​チームで​共通して​アクセスできる​場所を​前提に​パラメータを​設計してください。

try…otherwiseを​使わずに​エラーの​ある​行の​まま​更新すると、​どうなりますか。

更新自体は完了することが多いですが、該当列にエラー値が残ったままになり、後続の集計や別のステップでそのエラーが伝播して別のエラーを引き起こす場合があります。エラーが起きうる変換(型変換や数値化など)には、あらかじめtry…otherwiseやTable.ReplaceErrorValuesで明示的な受け皿を用意しておくと、原因の特定と対処が格段に楽になります。

まとめ

Power QueryのUI操作は、その裏側で常にMコード(let式)を生成しています。この対応関係を理解し、詳細エディターでコードを直接読み書きできるようになると、パラメータ化によるファイルパス・対象月の外部化、カスタム関数によるロジックの再利用、try…otherwiseによるエラー処理の見える化という3つの実務スキルが視野に入ります。いずれも派手な機能ではありませんが、月次更新テンプレートを「作った人にしかメンテナンスできない」状態から「仕組みとして安全に運用できる」状態に引き上げるための、地味だが効果の大きい積み重ねです。まずは既存クエリの詳細エディターを開き、自分が普段クリックしている操作がどのようなMコードになっているかを確認するところから始めてみてください。

出典・参考​(2026年8月確認)

※本記事は教育目的の一般的な解説であり、法務・税務・投資助言ではありません。設例は理解のための仮設例です。