複数引数の関数を作るとは何か
Power Query(M言語)で「複数引数の関数を作る」とは、1つの関数に対して、2つ以上の値やオブジェクトを入力として受け取り、それらを組み合わせて処理するロジックを定義することです。 単一引数の関数でも便利ですが、実務では「金額+税率+割引率」「テーブル+閾値」「文字列+フォーマット指定」など、複数の情報を同時に扱いたい場面が非常に多くなります。
複数引数の関数をきちんと設計できると、
- 設定値を柔軟に変えられる
- 同じ関数をさまざまな場面で再利用できる
- セキュリティや品質チェックを汎用的に書ける といったメリットが得られます。
ここから、初心者向けにステップバイステップで「複数引数の関数」の考え方と書き方を解説していきます。
M言語における複数引数の基本構文
(引数1, 引数2, …) => 式 という形で書きます
複数引数の関数の基本形は次のようになります。
let
CalcTaxIncluded =
(price as number, taxRate as number) as number =>
price * (1 + taxRate)
in
CalcTaxIncluded
Power Queryここでのポイントは、
(price as number, taxRate as number):引数が2つ並んでいるas number:戻り値の型price * (1 + taxRate):2つの引数を使った処理
という構造になっていることです。
引数はカンマ区切りで並べていきます。3つ以上でも同じです。
(price as number, taxRate as number, discountRate as number) as number =>
...
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ここでは、
price:元の金額taxRate:税率discountRate:割引率
という3つの引数を受け取る関数になっています。
ステップ2:呼び出し側で引数を順番通りに渡す
複数引数の関数を呼び出すときは、定義した順番通りに値を渡します。
let
CalcFinalAmount =
(price as number, taxRate as number, discountRate as number) as number =>
let
discount = price * discountRate,
taxed = (price - discount) * (1 + taxRate)
in
taxed,
TaxRate = 0.1,
DiscountRate = 0.05,
Final1 = CalcFinalAmount(1000, TaxRate, DiscountRate),
Final2 = CalcFinalAmount(500, TaxRate, DiscountRate)
in
[F1 = Final1, F2 = Final2]
Power Query重要なのは、
- 引数の「順番」が意味を持つ
- 間違った順番で渡すと、意図しない計算になる
という点です。
例えば CalcFinalAmount(TaxRate, DiscountRate, 1000) のように順番を入れ替えてしまうと、 price に税率が入り、taxRate に割引率が入り…というおかしな状態になり、結果も壊れてしまいます。
複数引数の関数では「引数の順番」が非常に重要な設計要素になります。
ステップ3:テーブル処理の中で複数引数を渡す
実務では、テーブルの列と設定値を組み合わせて複数引数を渡すことが多いです。
let
CalcFinalAmount =
(price as number, taxRate as number, discountRate as number) as number =>
let
discount = price * discountRate,
taxed = (price - discount) * (1 + taxRate)
in
taxed,
TaxRate = 0.1,
DiscountRate = 0.05,
SalesTable = Excel.CurrentWorkbook(){[Name="売上"]}[Content],
AddedFinalAmount =
Table.AddColumn(
SalesTable,
"最終金額",
each CalcFinalAmount([金額], TaxRate, DiscountRate),
type number
)
in
AddedFinalAmount
Power Queryここでは、
- 各行の
[金額]をprice引数として渡し - 共通の
TaxRateとDiscountRateを他の引数として渡しています。
「行ごとの値+共通設定値」を複数引数として渡すのは、実務で非常に強力なパターンです。
型を付けた複数引数の設計
引数ごとに型を明示する
複数引数の関数では、引数ごとに型を付けることで、 関数の意図がよりはっきりします。
(price as number, taxRate as number, discountRate as number) as number =>
...
Power Query型を付けるメリットは、
- 間違った型の値が渡されたときに早期にエラーになる
- 関数の役割が読みやすくなる
- セキュリティ・品質の観点からも安全になる
という点です。
例:文字列クレンジング+フォーマット指定の関数
let
FormatCustomerCode =
(code as nullable text, toUpper as logical, trimSpaces as logical) as nullable text =>
if code = null then
null
else
let
trimmed =
if trimSpaces then
Text.Trim(code)
else
code,
formatted =
if toUpper then
Text.Upper(trimmed)
else
trimmed
in
formatted
in
FormatCustomerCode
Power Queryここでは、
code:対象文字列toUpper:大文字化するかどうかtrimSpaces:前後の空白を削除するかどうか
という3つの引数を受け取り、 それぞれの引数に応じて処理を変えています。
複数引数を使うことで、「同じ関数をさまざまな設定で使い回す」ことができるようになります。
null を含む複数引数の扱い
null を許容する引数は明示的に扱う
複数引数の中に null が入りうる場合、 どの引数が null を許容するのかを明示しておくことが重要です。
例:安全な割り算+閾値判定の関数
let
SafeDivideWithThreshold =
(x as nullable number, y as nullable number, threshold as number) as nullable logical =>
if x = null or y = null or y = 0 then
null
else
let
result = x / y
in
result > threshold
in
SafeDivideWithThreshold
Power Queryここでは、
xとyは null を許容する数値thresholdは必須の数値- 戻り値は「null または logical」
という設計になっています。
呼び出し例:
let
R1 = SafeDivideWithThreshold(10, 2, 3), // 10/2=5 → 5>3 → true
R2 = SafeDivideWithThreshold(10, 0, 3), // y=0 → null
R3 = SafeDivideWithThreshold(null, 2, 3) // x=null → null
in
[R1 = R1, R2 = R2, R3 = R3]
Power Query複数引数の関数では、「どの引数がnullを許容するか」「nullが来たときどう振る舞うか」を設計レベルで決めておくことが非常に重要です。
テーブルやレコードを含む複数引数
テーブル+閾値を引数にする関数
テーブルと設定値を組み合わせて引数にする例です。
let
FilterHighAmountRows =
(SalesTable as table, threshold as number) as table =>
Table.SelectRows(
SalesTable,
each [金額] <> null and [金額] > threshold
)
in
FilterHighAmountRows
Power Query呼び出し側:
let
SalesTable = Excel.CurrentWorkbook(){[Name="売上"]}[Content],
Threshold = 1000,
HighAmountTable = FilterHighAmountRows(SalesTable, Threshold)
in
HighAmountTable
Power Queryここでは、
SalesTable:対象テーブルthreshold:金額の閾値
という2つの引数を受け取り、 「閾値を超える行だけを抽出したテーブル」を返しています。
テーブル+設定値を複数引数として関数化することで、フィルタロジックを汎用的に再利用できるようになります。
レコード+設定値を引数にする関数
1行分のレコードと設定値を組み合わせる例です。
let
IsHighValueCustomer =
(row as record, amountThreshold as number, rankThreshold as text) as logical =>
let
isHighAmount =
(row[金額] <> null and row[金額] > amountThreshold),
isHighRank =
(row[ランク] <> null and row[ランク] <= rankThreshold)
in
isHighAmount and isHighRank
in
IsHighValueCustomer
Power Queryテーブルに適用する例:
let
IsHighValueCustomer =
(row as record, amountThreshold as number, rankThreshold as text) as logical =>
let
isHighAmount =
(row[金額] <> null and row[金額] > amountThreshold),
isHighRank =
(row[ランク] <> null and row[ランク] <= rankThreshold)
in
isHighAmount and isHighRank,
SalesTable = Excel.CurrentWorkbook(){[Name="売上"]}[Content],
AmountThreshold = 1000,
RankThreshold = "B",
AddedHighValueFlag =
Table.AddColumn(
SalesTable,
"重要顧客",
each IsHighValueCustomer(_, AmountThreshold, RankThreshold),
type logical
)
in
AddedHighValueFlag
Power Queryここでは、
- 行全体(レコード)
- 金額閾値
- ランク閾値
という3つの引数を使って、「重要顧客かどうか」を判定しています。
複数引数を使うことで、「行の内容+外部設定」を組み合わせた高度な判定ロジックを関数として表現できるようになります。
セキュリティ・品質の観点からの複数引数
1. 権限判定関数に複数引数を使う
セキュリティに関わる関数では、ロールやフラグなどを複数引数として受け取ることがあります。
let
CanExecuteProcess =
(role as text, isActive as logical, isApproved as logical) as logical =>
(role = "Admin" or role = "Manager")
and isActive
and isApproved
in
CanExecuteProcess
Power Query呼び出し側:
let
Role = "Admin",
IsActive = true,
IsApproved = false,
CanRun = CanExecuteProcess(Role, IsActive, IsApproved)
in
CanRun
Power Queryこのような関数を使う場合、
- ロール名の管理方法
- フラグの意味(誰がどう設定するか)
- 誤って条件を緩くしてしまわないか
を意識しておく必要があります。
セキュリティに関わる複数引数の関数は、コメントやレビューを通じて意図を明確にし、変更時には慎重な運用が求められます。
2. 設定値を「引数にするか」「固定値にするか」の判断
複数引数の設計では、「どこまでを引数にするか」が重要な判断ポイントです。
- 将来変更される可能性が高い値(税率・閾値・ロールなど)は引数にする
- 絶対に変わらないルールは固定値でもよいが、コメントで意図を明示する
例:税率を固定値にした場合
let
CalcTaxIncludedFixed =
(price as number) as number =>
price * 1.1 // 税率10%を固定
in
CalcTaxIncludedFixed
Power Query例:税率を引数にした場合
let
CalcTaxIncludedFlexible =
(price as number, taxRate as number) as number =>
price * (1 + taxRate)
in
CalcTaxIncludedFlexible
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テンプレ2:テーブル+閾値
let
FilterHighAmountRows =
(SalesTable as table, threshold as number) as table =>
Table.SelectRows(
SalesTable,
each [金額] <> null and [金額] > threshold
)
in
FilterHighAmountRows
Power Queryテンプレ3:レコード+設定値で重要顧客判定
let
IsHighValueCustomer =
(row as record, amountThreshold as number, rankThreshold as text) as logical =>
let
isHighAmount =
(row[金額] <> null and row[金額] > amountThreshold),
isHighRank =
(row[ランク] <> null and row[ランク] <= rankThreshold)
in
isHighAmount and isHighRank
in
IsHighValueCustomer
Power Queryまとめ:複数引数の関数を作ることは「ロジックを柔軟に設計すること」
M言語で「複数引数の関数を作る」というのは、 「1つの関数に対して複数の値やオブジェクトを入力として受け取り、それらを組み合わせて汎用的なロジックを設計すること」です。
これによって、
- 同じ関数をさまざまな設定・条件で再利用できる
- テーブルやレコードと設定値を組み合わせた高度な処理を書ける
- 型やnullの扱いを引数ごとに設計でき、品質・セキュリティを高められる
- 実務のロジックを「関数+複数引数」という形で整理しやすくなる
というメリットが得られます。
複数引数は、関数設計を一段階レベルアップさせる重要な要素ですので、 ぜひ「何を引数にするか」「順番と型をどう設計するか」「nullやセキュリティをどう扱うか」を意識しながら、 現場のロジックを複数引数の関数として育てていっていただきたいです。
