実務で使えるPower Query小技・テクニック | ステップ間の依存関係を理解する

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

「ステップ間の依存関係を理解する」とは何か

Power Query(M言語)でクエリを書くとき、画面左側に「ステップ」が並びますよね。 ソース変更された型フィルター行並べ替え済みの行 …といった流れで、 1つ1つのステップが「前のステップの結果」を受け取りながら処理を積み重ねていきます。

この「前のステップに依存している」という関係をきちんと理解することが、

  • クエリが壊れないように安全に編集する
  • エラーの原因を素早く特定する
  • セキュリティや品質の観点で“どこで何が起きているか”を把握する ための重要な基礎になります。

ここでは、M言語の let ~ in 構造をベースに、 ステップ間の依存関係をステップバイステップで噛み砕いて解説していきます。

M言語の基本構造:let ~ in とステップ

ステップは「名前付きの値」であり、前のステップに依存する

典型的な Mコードは次のような形をしています。

let
    Source = Excel.CurrentWorkbook(){[Name="売上"]}[Content],
    ChangedType = Table.TransformColumnTypes(Source, {{"金額", type number}}),
    FilteredRows = Table.SelectRows(ChangedType, each [金額] > 1000),
    SortedRows = Table.Sort(FilteredRows, {{"金額", Order.Descending}})
in
    SortedRows
Power Query

ここでの各ステップは、

  • Source:元データ
  • ChangedTypeSource に対して型変換を行った結果
  • FilteredRowsChangedType に対してフィルタをかけた結果
  • SortedRowsFilteredRows を並べ替えた結果

というように、必ず「前のステップの結果」を受け取って処理しています。

つまり、

「後ろのステップは、前のステップに依存している」

という構造になっているわけです。

ステップ間の依存関係を“鎖”としてイメージする

上の例を、依存関係の鎖としてイメージするとこうなります。

  • Source ↓(依存)
  • ChangedType
  • FilteredRows
  • SortedRows

この鎖のどこか1つを壊したり、名前を変えたりすると、 その後ろにぶら下がっているステップが一気に影響を受けます。

「ステップ間の依存関係を理解する」というのは、この鎖の構造を頭の中でイメージできるようになることだと考えていただくと分かりやすいです。

ステップバイステップで依存関係を追いかける

ステップ1:各ステップが「どのステップを参照しているか」を見る

先ほどのコードをもう一度見てみます。

Source = Excel.CurrentWorkbook(){[Name="売上"]}[Content],
ChangedType = Table.TransformColumnTypes(Source, {{"金額", type number}}),
FilteredRows = Table.SelectRows(ChangedType, each [金額] > 1000),
SortedRows = Table.Sort(FilteredRows, {{"金額", Order.Descending}})
Power Query

ここで、

  • ChangedTypeSource を参照
  • FilteredRowsChangedType を参照
  • SortedRowsFilteredRows を参照

という依存関係になっています。

まずは、「このステップは、どのステップ名を使っているか」を意識して見ることが、依存関係を理解する第一歩です。

ステップ2:1つのステップを変更したときの影響範囲を考える

例えば、ChangedType のステップを削除したり、名前を変えたりするとどうなるでしょうか。

// ChangedType を削除した場合
let
    Source = Excel.CurrentWorkbook(){[Name="売上"]}[Content],
    // ChangedType がなくなった
    FilteredRows = Table.SelectRows(ChangedType, each [金額] > 1000),
    SortedRows = Table.Sort(FilteredRows, {{"金額", Order.Descending}})
in
    SortedRows
Power Query

この場合、

  • FilteredRowsChangedType を参照している
  • しかし ChangedType が存在しない

ため、FilteredRows のステップでエラーが発生します。

つまり、

「あるステップを変更・削除すると、そのステップを参照している後続ステップがすべて影響を受ける」

ということです。

これが「ステップ間の依存関係」を理解するうえで、最も重要な感覚です。

ステップ3:依存関係を意識した“安全な編集”の考え方

安全にクエリを編集するためには、

  • どのステップがどのステップに依存しているか
  • どのステップを変更すると、どこまで影響が広がるか

を意識しながら作業する必要があります。

具体的には、

  • 前のステップの名前を変えるときは、後続ステップの参照もすべて更新する
  • 前のステップの処理内容を大きく変えるときは、後続ステップの前提が崩れないか確認する
  • 不要なステップを削除するときは、そのステップが参照されていないか必ず確認する

といったことが大切です。

依存関係を意識せずにステップをいじると、 「一見動いているように見えるが、後続のロジックが前提と違うデータを受け取ってしまう」という危険な状態になりかねません。

実務でよくある「依存関係の落とし穴」

1. 型変換ステップを削除してしまう

よくあるのが、変更された型 ステップを「邪魔だから」と削除してしまうケースです。

let
    Source = Excel.CurrentWorkbook(){[Name="売上"]}[Content],
    // ChangedType を削除
    FilteredRows = Table.SelectRows(Source, each [金額] > 1000),
    SortedRows = Table.Sort(FilteredRows, {{"金額", Order.Descending}})
in
    SortedRows
Power Query

一見すると動きそうですが、

  • Source の段階では「金額」が text 型のまま
  • FilteredRows[金額] > 1000 を評価すると、文字列比較になってしまう
  • その結果、意図しないフィルタ結果になる

という問題が起きます。

ここでは、

FilteredRowsChangedType に依存していて、 ChangedType が“金額を number にしている”ことを前提にロジックが書かれている」

という依存関係があるわけです。

依存関係を理解せずに前のステップを削除すると、エラーではなく“静かなバグ”が発生することがあるという点が、実務では非常に危険です。

2. フィルタ条件の前提が変わる

例えば、次のようなステップがあるとします。

let
    Source = Excel.CurrentWorkbook(){[Name="売上"]}[Content],
    FilteredRows = Table.SelectRows(Source, each [金額] > 0),
    ValidRows = Table.SelectRows(FilteredRows, each [顧客コード] <> null and [顧客コード] <> "")
in
    ValidRows
Power Query

ここで、FilteredRows の条件を変更した場合、 ValidRows の前提も変わる可能性があります。

FilteredRows = Table.SelectRows(Source, each [金額] >= 0)
Power Query

この変更自体は小さく見えますが、

  • ValidRows は「金額が正の行だけが来る」という前提で書かれているかもしれない
  • その前提が崩れると、後続の集計や判定ロジックに影響が出る

ということがありえます。

「前のステップの条件を変えると、後続ステップの前提も変わる」 という依存関係を意識しておくことが、品質を守るうえで重要です。

3. セキュリティチェックのステップを飛ばしてしまう

セキュリティに関わる場面では、 「特定のステップが“フィルタ”や“チェック”の役割を担っている」ことがあります。

let
    Source = Excel.CurrentWorkbook(){[Name="ユーザー"]}[Content],

    ActiveUsers =
        Table.SelectRows(Source, each [IsActive] = true),

    AdminUsers =
        Table.SelectRows(ActiveUsers, each [Role] = "Admin")
in
    AdminUsers
Power Query

ここで、もし ActiveUsers のステップを削除してしまうと、

  • AdminUsers は「非アクティブなユーザーも含めて Admin を抽出する」ことになる
  • 本来は「アクティブな Admin だけ」を対象にしたかったのに、前提が崩れる

というセキュリティ上の問題が発生します。

セキュリティや権限に関わるステップは、後続ステップの前提として非常に重要な依存関係を持っているため、 削除や変更には特に慎重さが求められます。

ステップ間の依存関係を“見える化”する考え方

1. ステップ名に役割を込める

依存関係を理解しやすくするために、 ステップ名に「役割」を込めておくことが有効です。

悪い例:

Source
Step1
Step2
Step3
Power Query

良い例:

Source
ChangedType
FilteredValidSales
SortedByAmount
Power Query

こうしておくことで、

  • FilteredValidSales は「有効な売上だけを残すステップ」
  • SortedByAmount は「金額で並べ替えるステップ」

という意味が伝わり、 「どのステップがどの前提に依存しているか」が読み取りやすくなります。

2. 重要な前提はコメントで明示する

依存関係の中でも、特に重要な前提(型、フィルタ条件、セキュリティチェックなど)は、 コメントで明示しておくと安全です。

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

    // 金額を number 型に変換する。以降のステップは数値として扱う前提。
    ChangedType =
        Table.TransformColumnTypes(
            Source,
            {{"金額", type number}}
        ),

    // 金額が正の行のみを対象とする。以降の集計は「売上のみ」を前提。
    FilteredPositiveSales =
        Table.SelectRows(
            ChangedType,
            each [金額] > 0
        )
in
    FilteredPositiveSales
Power Query

コメントによって、

  • どのステップがどんな前提を作っているか
  • 後続ステップが何に依存しているか

が明確になり、 編集時やレビュー時に「ここを変えるとどこまで影響するか」を判断しやすくなります。

3. 依存関係を意識したテンプレート思考

実務では、次のような「依存関係テンプレート」を意識しておくと便利です。

  1. Source:元データ
  2. Typed:型を整える(後続ステップはこの型に依存)
  3. Filtered:対象行を絞る(後続ステップはこの条件に依存)
  4. Enriched:列追加・計算(後続ステップはこの計算結果に依存)
  5. Final:最終形(レポートや出力がこの形に依存)

このような「役割ごとの鎖」を意識してクエリを設計すると、 ステップ間の依存関係が自然と整理され、 壊れにくく・読みやすいクエリになります。

実務で使える「依存関係を意識した」テンプレート

テンプレ1:売上クエリの基本構造

let
    // 1. 元データ
    Source = Excel.CurrentWorkbook(){[Name="売上"]}[Content],

    // 2. 型を整える(後続はこの型に依存)
    Typed =
        Table.TransformColumnTypes(
            Source,
            {
                {"顧客コード", type text},
                {"顧客名", type text},
                {"金額", type number},
                {"売上日", type date}
            }
        ),

    // 3. 対象行を絞る(後続はこの条件に依存)
    FilteredPositiveSales =
        Table.SelectRows(
            Typed,
            each [金額] > 0
        ),

    // 4. 列追加・計算(後続はこの計算結果に依存)
    AddedTaxAmount =
        Table.AddColumn(
            FilteredPositiveSales,
            "消費税額",
            each [金額] * 0.1,
            type number
        ),

    // 5. 最終形(レポートはこの形に依存)
    SortedByAmount =
        Table.Sort(
            AddedTaxAmount,
            {{"金額", Order.Descending}}
        )
in
    SortedByAmount
Power Query

テンプレ2:ユーザー権限クエリの依存関係

let
    Source = Excel.CurrentWorkbook(){[Name="ユーザー"]}[Content],

    // 1. 型を整える
    Typed =
        Table.TransformColumnTypes(
            Source,
            {
                {"UserId", type text},
                {"Role", type text},
                {"IsActive", type logical}
            }
        ),

    // 2. アクティブユーザーのみ(後続は「アクティブである」前提に依存)
    ActiveUsers =
        Table.SelectRows(
            Typed,
            each [IsActive] = true
        ),

    // 3. 管理者のみ(後続は「アクティブな Admin」前提に依存)
    ActiveAdmins =
        Table.SelectRows(
            ActiveUsers,
            each [Role] = "Admin"
        )
in
    ActiveAdmins
Power Query

まとめ:「ステップ間の依存関係を理解する」は“クエリの因果関係を理解する”こと

Power Query(M言語)で「ステップ間の依存関係を理解する」というのは、 「このステップが、どのステップの結果を前提にして動いているか」を理解することです。

それによって、

  • ステップを変更・削除したときの影響範囲を予測できる
  • 静かなバグ(エラーにならないが結果がおかしい状態)を防ぎやすくなる
  • セキュリティや品質に関わる前提を壊さないように編集できる
  • クエリ全体の“因果関係”を把握し、保守性の高い設計ができる

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

ぜひ、

  • 「このステップはどのステップに依存しているか」
  • 「このステップを変えると、どこまで影響が広がるか」
  • 「重要な前提(型・フィルタ・セキュリティチェック)はどのステップで作られているか」

という視点を持ちながら、 Power Query のステップを“鎖”としてイメージし、 実務のクエリを壊れにくく・安全で・読みやすいものに育てていっていただきたいです。

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