実務で使えるPower Query小技・テクニック | 関数に引数を渡す

Excel VBA Power Query M Formula Language
スポンサーリンク
スポンサーリンク

関数に引数を渡すとは何か

Power Query(M言語)で「関数に引数を渡す」とは、関数に対して“具体的な値”や“対象データ”を渡し、その値に応じた処理をさせることです。 同じ関数でも、渡す引数が違えば結果が変わります。これが「再利用できるロジック」としての関数の本質です。

実務では、

  • 税率や閾値などの設定値
  • テーブルやレコード
  • 文字列や数値、論理値、null などを引数として渡しながら、柔軟なクエリを組み立てていきます。

ここでは、初心者向けに「引数の渡し方・考え方」をステップバイステップで解説していきます。

M言語の関数と引数の基本構文

関数定義と呼び出しの関係

関数の基本形は次のようになります。

let
    Double =
        (x as number) as number =>
            x * 2
in
    Double
Power Query

ここでのポイントは、

  • (x as number):引数の定義(名前:x、型:number)
  • Double(10):呼び出し時に「10」を引数として渡す

という関係です。

呼び出し例:

let
    Double =
        (x as number) as number =>
            x * 2,

    Result1 = Double(10),   // 20
    Result2 = Double(3),    // 6
    Result3 = Double(-5)    // -10
in
    [R1 = Result1, R2 = Result2, R3 = Result3]
Power Query

同じ関数でも、渡す引数が違えば結果が変わる、これが「関数に引数を渡す」ということです。

ステップバイステップで「引数を渡す」を理解する

ステップ1:関数側で「何を受け取るか」を決める

まず、関数を作るときに「どんな値を受け取るか」を決めます。

例:税込金額を計算する関数

let
    CalcTaxIncluded =
        (price as number, taxRate as number) as number =>
            price * (1 + taxRate)
in
    CalcTaxIncluded
Power Query

ここでは、

  • price:元の金額
  • taxRate:税率

という2つの引数を受け取る関数になっています。

ステップ2:呼び出し側で「具体的な値」を渡す

関数を呼び出すときは、引数に具体的な値を渡します。

let
    CalcTaxIncluded =
        (price as number, taxRate as number) as number =>
            price * (1 + taxRate),

    TaxRate = 0.1,

    Amount1 = CalcTaxIncluded(1000, TaxRate),
    Amount2 = CalcTaxIncluded(500, TaxRate)
in
    [A1 = Amount1, A2 = Amount2]
Power Query

ここでは、

  • CalcTaxIncluded(1000, TaxRate):price=1000, taxRate=0.1
  • CalcTaxIncluded(500, TaxRate):price=500, taxRate=0.1

という形で、同じ関数に違う金額を渡して計算しています。

ステップ3:テーブル処理の中で引数を渡す

テーブルに対して関数を適用するときも、引数を渡します。

let
    CalcTaxIncluded =
        (price as number, taxRate as number) as number =>
            price * (1 + taxRate),

    TaxRate = 0.1,

    SalesTable = Excel.CurrentWorkbook(){[Name="売上"]}[Content],

    AddedFinalAmount =
        Table.AddColumn(
            SalesTable,
            "税込金額",
            each CalcTaxIncluded([金額], TaxRate),
            type number
        )
in
    AddedFinalAmount
Power Query

ここでは、

  • 各行の [金額]price 引数として渡し
  • 共通の TaxRatetaxRate 引数として渡しています。

「行ごとの値」と「共通設定値」を組み合わせて関数に渡す」というのが、実務で非常によく使うパターンです。

引数の型を意識する

引数に型を付けるメリット

M言語では、引数に型を付けることができます。

(price as number, taxRate as number) as number =>
    ...
Power Query

型を付けることで、

  • 間違った型の値が渡されたときに早期にエラーになる
  • 関数の意図が読みやすくなる
  • セキュリティ・品質の観点からも安全になる

というメリットがあります。

例:文字列クレンジング関数

let
    CleanCustomerCode =
        (code as nullable text) as nullable text =>
            if code = null then
                null
            else
                Text.Upper(Text.Trim(code))
in
    CleanCustomerCode
Power Query

ここでは、

  • code as nullable text:null を許容するテキスト
  • as nullable text:戻り値も null を許容するテキスト

と明示しています。

「この関数はテキスト(またはnull)を受け取る」ということが、型によってはっきり示されているのが重要です。

null を引数として渡すときの注意

null を許容するかどうかを関数側で決める

引数に null が渡される可能性がある場合、 関数側で「null をどう扱うか」を決めておく必要があります。

例:安全な割り算関数

let
    SafeDivide =
        (x as nullable number, y as nullable number) as nullable number =>
            if x = null or y = null or y = 0 then
                null
            else
                x / y
in
    SafeDivide
Power Query

ここでは、

  • x または y が null の場合
  • y が 0 の場合

null を返すようにしています。

呼び出し例:

let
    Result1 = SafeDivide(10, 2),    // 5
    Result2 = SafeDivide(10, 0),    // null
    Result3 = SafeDivide(null, 2)   // null
in
    [R1 = Result1, R2 = Result2, R3 = Result3]
Power Query

「null が来たときにどうするか」を関数側で決めておくことが、品質・セキュリティの両面で非常に重要です。

テーブルやレコードを引数として渡す

テーブルを引数にする関数

関数は、テーブルを引数として受け取ることもできます。

let
    GetSalesSummary =
        (SalesTable as table) as record =>
            let
                AmountList = List.RemoveNulls(SalesTable[金額]),
                TotalAmount = List.Sum(AmountList),
                RowCount = List.Count(AmountList),
                AverageAmount =
                    if RowCount = 0 then
                        null
                    else
                        TotalAmount / RowCount
            in
                [
                    合計金額 = TotalAmount,
                    件数 = RowCount,
                    平均金額 = AverageAmount
                ]
in
    GetSalesSummary
Power Query

呼び出し側:

let
    SalesTable = Excel.CurrentWorkbook(){[Name="売上"]}[Content],

    Summary = GetSalesSummary(SalesTable),

    Total = Summary[合計金額],
    Avg = Summary[平均金額]
in
    [Total = Total, Avg = Avg]
Power Query

ここでは、

  • SalesTable というテーブルを丸ごと引数として渡し
  • 集計結果をレコードとして受け取っています。

「テーブルを引数にして、集計や変換を関数化する」のは、実務で非常に強力なパターンです。

レコードを引数にする関数

1行分のレコードを引数にすることもできます。

let
    IsValidSalesRow =
        (row as record) as logical =>
            let
                hasCustomer =
                    (row[顧客コード] <> null and row[顧客コード] <> ""),
                hasPositiveAmount =
                    (row[金額] <> null and row[金額] > 0)
            in
                hasCustomer and hasPositiveAmount
in
    IsValidSalesRow
Power Query

テーブルに適用する例:

let
    IsValidSalesRow =
        (row as record) as logical =>
            let
                hasCustomer =
                    (row[顧客コード] <> null and row[顧客コード] <> ""),
                hasPositiveAmount =
                    (row[金額] <> null and row[金額] > 0)
            in
                hasCustomer and hasPositiveAmount,

    SalesTable = Excel.CurrentWorkbook(){[Name="売上"]}[Content],

    AddedValidFlag =
        Table.AddColumn(
            SalesTable,
            "有効行",
            each IsValidSalesRow(_),
            type logical
        )
in
    AddedValidFlag
Power Query

ここでの _ は「行全体(レコード)」を表し、 それを IsValidSalesRow 関数に引数として渡しています。

「行全体を引数として渡し、複雑な判定を関数側で行う」ことで、 テーブル処理のロジックをすっきり書けるようになります。

セキュリティ・品質の観点からの「引数を渡す」

1. 権限情報やロールを引数にする場合

セキュリティに関わる関数では、ロールや権限情報を引数として渡すことがあります。

let
    IsAdminUser =
        (role as text) as logical =>
            role = "Admin"
in
    IsAdminUser
Power Query

呼び出し側:

let
    UserRole = "Admin",
    CanExecute = IsAdminUser(UserRole)
in
    CanExecute
Power Query

このような関数を使う場合、

  • ロール名の管理方法
  • 誰がこの関数や呼び出しコードを編集できるか
  • 誤ってロジックを緩くしてしまわないか

を意識しておく必要があります。

セキュリティに関わる引数(ロール・権限・フラグなど)は、設計と運用の両面で慎重に扱うべき重要な情報です。

2. 設定値を引数にするか、固定値にするか

税率や閾値などの設定値を、

  • 関数の中に固定値として書く
  • 引数として外から渡す

どちらにするかは設計のポイントです。

固定値の例:

let
    CalcTaxIncluded =
        (price as number) as number =>
            price * 1.1   // 税率10%を固定
in
    CalcTaxIncluded
Power Query

引数の例:

let
    CalcTaxIncluded =
        (price as number, taxRate as number) as number =>
            price * (1 + taxRate)
in
    CalcTaxIncluded
Power Query

実務では、

  • 将来変更される可能性が高い値(税率・閾値など)は引数にする
  • 絶対に変わらないルールは固定値でもよいが、コメントで意図を明示する

という考え方が安全です。

実務で使える「引数を渡す」テンプレート

テンプレ1:設定値を引数にする計算関数

let
    CalcFinalAmount =
        (price as number, taxRate as number, discountRate as number) as number =>
            let
                discount = price * discountRate,
                taxed = (price - discount) * (1 + taxRate)
            in
                taxed
in
    CalcFinalAmount
Power Query

呼び出し例:

let
    TaxRate = 0.1,
    DiscountRate = 0.05,

    Final1 = CalcFinalAmount(1000, TaxRate, DiscountRate),
    Final2 = CalcFinalAmount(500, TaxRate, DiscountRate)
in
    [F1 = Final1, F2 = Final2]
Power Query

テンプレ2:テーブルを引数にして集計する

let
    GetSalesSummary =
        (SalesTable as table) as record =>
            let
                AmountList = List.RemoveNulls(SalesTable[金額]),
                TotalAmount = List.Sum(AmountList),
                RowCount = List.Count(AmountList),
                AverageAmount =
                    if RowCount = 0 then
                        null
                    else
                        TotalAmount / RowCount
            in
                [
                    合計金額 = TotalAmount,
                    件数 = RowCount,
                    平均金額 = AverageAmount
                ]
in
    GetSalesSummary
Power Query

テンプレ3:レコードを引数にして品質チェックする

let
    IsValidSalesRow =
        (row as record) as logical =>
            let
                hasCustomer =
                    (row[顧客コード] <> null and row[顧客コード] <> ""),
                hasPositiveAmount =
                    (row[金額] <> null and row[金額] > 0)
            in
                hasCustomer and hasPositiveAmount
in
    IsValidSalesRow
Power Query

まとめ:「関数に引数を渡す」は“ロジックを汎用化する”ための鍵

M言語で「関数に引数を渡す」というのは、 「関数に対して具体的な値やデータを渡し、その値に応じた処理をさせることで、ロジックを汎用的に再利用できるようにすること」です。

これによって、

  • 同じ関数をさまざまな場面で使い回せる
  • 設定値や閾値を柔軟に変えられる
  • テーブルやレコードを引数にして高度な処理を関数化できる
  • 型やnullの扱いを統一し、品質・セキュリティを高められる

というメリットが得られます。

関数そのものだけでなく、「引数の設計」を意識することで、 Power Query のクエリは一気に“実務で通用する設計されたコード”に近づきますので、 ぜひ「何を引数にするか」「型とnullをどう扱うか」を考えながら、 自分の現場のロジックを関数+引数の形で整理していっていただきたいです。

タイトルとURLをコピーしました