Power Queryでカスタム関数を作成して再利用する方法

目次

概要

Power Query では、M 言語で カスタム関数 を定義し、複数のクエリや列計算で繰り返し利用できます。本記事では、文字連結と数値スケーリングの関数を例に、作成から呼び出し、テーブル列への適用、例外処理までを丁寧にご説明いたします。変数名・引数名・数値は本記事用に変更しております。


基本:関数の作り方と呼び出し

1) 文字列を連結する関数(接頭辞は任意)

クエリ名: fxAddGreeting

(str as text, optional prefix as nullable text) as text =>
let
    base = if prefix <> null then prefix else "Hello ",
    result = base & str
in
    result
  • 使い方例
    • fxAddGreeting("森")Hello 森
    • fxAddGreeting("森", "こんにちは、")こんにちは、森

2) リストの各要素に係数を掛ける関数(既定は 10)

クエリ名: fxScaleList

(items as list, optional factor as nullable number) as list =>
let
    k = if factor <> null then factor else 10,
    scaled = List.Transform(items, each _ * k)
in
    scaled
  • 使い方例
    • fxScaleList({1, 2, 3}){10, 20, 30}
    • fxScaleList({2, 4, 6}, 0.5){1, 2, 3}

実務での適用例

例A:テーブル列にあいさつ文を追加

let
    Source   = Excel.CurrentWorkbook(){[Name = "Employees"]}[Content],
    Promoted = Table.PromoteHeaders(Source, [PromoteAllScalars = true]),
    Typed    = Table.TransformColumnTypes(Promoted, {{"Name", type text}}),
    // 既に作成済みの fxAddGreeting を列計算で呼び出す
    Added    = Table.AddColumn(
                 Typed,
                 "Greeting",
                 each fxAddGreeting([Name]),
                 type text
               )
in
    Added

例B:数値列を一括スケーリング(係数はパラメータ)

let
    Source   = Excel.CurrentWorkbook(){[Name = "Sales"]}[Content],
    Promoted = Table.PromoteHeaders(Source, [PromoteAllScalars = true]),
    Typed    = Table.TransformColumnTypes(Promoted, {{"Amount", type number}}),
    // 係数 1.08(税率等)で倍率を掛ける
    Scaled   = Table.TransformColumns(
                 Typed,
                 {{"Amount", each List.First(fxScaleList({_}, 1.08)), type number}}
               )
in
    Scaled

応用

応用1:エラーに強いラッパー関数

数値変換で失敗しても null にフォールバックする関数です。
クエリ名: fxToNumberSafe

(x as any) as nullable number =>
let
    v = try Number.From(x) otherwise null
in
    v
  • 列適用例 powerqueryコピーする編集するSafeTyped = Table.TransformColumns( Promoted, {{"Amount", each fxToNumberSafe(_), type number}} )

応用2:関数を Folder 結合で再利用

フォルダ内の複数ブックへ同一処理を適用します。

let
    Files    = Folder.Files("C:\Data\Books"),
    OnlyXlsx = Table.SelectRows(Files, each Text.Lower([Extension]) = ".xlsx"),
    Picked   = Table.SelectColumns(OnlyXlsx, {"Content", "Name"}),
    WithTbl  = Table.AddColumn(
                 Picked,
                 "Data",
                 each
                   let
                     wb  = Excel.Workbook([Content], true, true),
                     sh  = Table.SelectRows(wb, each [Kind] = "Sheet"){0}[Data],
                     hdr = Table.PromoteHeaders(sh, [PromoteAllScalars = true]),
                     out = Table.AddColumn(hdr, "Greeting", each fxAddGreeting([Name]))
                   in
                     out,
                 type table
               ),
    Cols     = Table.ColumnNames(WithTbl{0}[Data]),
    Expand   = Table.ExpandTableColumn(WithTbl, "Data", Cols, Cols)
in
    Expand

応用3:既定値や検証を組み込む

(text as nullable text, optional maxLen as nullable number) as text =>
let
    src   = if text <> null then text else "",
    m     = if maxLen <> null then maxLen else 50,
    cut   = Text.Start(src, m),
    clean = Text.Trim(cut)
in
    clean
  • 長すぎる説明文を切り詰め、前後の空白を除去する用途に適しています。

トラブルシューティング

  • 関数が見つからない
    クエリ名が関数名になります。呼び出し元から fxAddGreeting(...) のように正しい名前で参照してください。
  • 「式が期待される場所に識別子」などのエラー
    let ... in ...カンマの位置括弧の対応識別子の綴り(例:Text.Start など)を確認してください。
  • 型不一致
    引数や列の型を Table.TransformColumnTypes で先に揃え、関数側の引数にも as textas number の注釈を付けると安定します。

まとめ

例外処理(try … otherwise)と型注釈を組み合わせることで、運用時のエラー耐性が向上します。

カスタム関数は 関数クエリ として作成し、他のクエリから呼び出して再利用します。

文字列処理や数値スケーリングのような小粒の関数を用意しておくと、列計算・フォルダ集約での再利用性が高まります。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次