関数に引数を渡すとは何か
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.1CalcTaxIncluded(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引数として渡し - 共通の
TaxRateをtaxRate引数として渡しています。
「行ごとの値」と「共通設定値」を組み合わせて関数に渡す」というのが、実務で非常によく使うパターンです。
引数の型を意識する
引数に型を付けるメリット
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をどう扱うか」を考えながら、 自分の現場のロジックを関数+引数の形で整理していっていただきたいです。
