Power Query 実務テンプレ | クレンジング(前処理)系:複数条件で行抽出

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

ゴールのイメージをそろえる

今回のテーマは「Power Query で 複数条件を組み合わせて、欲しい行だけをきれいに抽出する実務テンプレ」です。
“複数条件”というのは、たとえばこんなイメージです。

「売上金額が 10,000 以上 かつ ステータスが『確定』」
「商品区分が『A』 または 『B』 かつ 削除フラグが 0」
「日付が 2024/01/01〜2024/01/31 かつ 顧客ランクが『ゴールド』」

これを Power Query では、Table.SelectRowsand / or / not を組み合わせて書いていきます。
ここをテンプレ化しておくと、「条件が増えても怖くない」状態になります。


例題データを一度イメージで固める

次のようなテーブルを想像してください。

受注番号受注日顧客ランク売上金額ステータス削除フラグ
10012024/01/05ゴールド15000確定0
10022024/01/10シルバー8000確定0
10032024/01/15ゴールド50000
10042024/02/01ブロンズ20000確定1
10052024/01/20ゴールド30000確定0

ここから、例えばこんな条件で抽出したいとします。

「2024年1月のデータで、顧客ランクがゴールド、かつ売上金額が 10,000 以上、かつ削除フラグが 0 の行だけ欲しい」

つまり、条件はこうです。

受注日が 2024/01/01〜2024/01/31
顧客ランク = “ゴールド”
売上金額 >= 10000
削除フラグ = 0

これを Power Query で“読みやすく”書くのが、今回のゴールです。


基本テンプレ:Table.SelectRows と and / or の組み合わせ

まずはストレートに全部書いてみる

上の条件を、そのまま M 言語で書くとこうなります。

let
    Source = ・・・前のステップ・・・,

    Filtered =
        Table.SelectRows(
            Source,
            each
                [受注日] >= #date(2024, 1, 1)
                and [受注日] <= #date(2024, 1, 31)
                and [顧客ランク] = "ゴールド"
                and [売上金額] >= 10000
                and [削除フラグ] = 0
        )
in
    Filtered
Power Query

ポイントを言葉で整理します。

行ごとに評価される「each ~」の中で、条件式を並べている。
and は「かつ」、or は「または」、not は「~ではない」。
日付は #date(年, 月, 日) で書くと、date 型として比較できる。

この形が「複数条件で行抽出」の基本テンプレです。
ここから、読みやすさ・再利用性を上げる工夫を足していきます。


条件が増えてきたときの“読みやすくするコツ”

let ~ in を中にもう一段入れて、条件に名前をつける

条件が 3 個、4 個と増えてくると、
and and and ... が続いて読みにくくなります。
そういうときは、each の中に小さな let ~ in を入れて、条件に名前をつけると一気に見通しがよくなります。

let
    Source = ・・・前のステップ・・・,

    Filtered =
        Table.SelectRows(
            Source,
            each
                let
                    isInJan2024 =
                        [受注日] >= #date(2024, 1, 1)
                        and [受注日] <= #date(2024, 1, 31),

                    isGold =
                        [顧客ランク] = "ゴールド",

                    isHighSales =
                        [売上金額] >= 10000,

                    isNotDeleted =
                        [削除フラグ] = 0
                in
                    isInJan2024
                    and isGold
                    and isHighSales
                    and isNotDeleted
        )
in
    Filtered
Power Query

ここが重要なポイントです。

条件に名前をつけることで、「何をしているか」がコードから伝わる。
条件の追加・削除・修正がしやすくなる(1行だけ直せばいい)。
デバッグもしやすい(どの条件で落ちているかが分かりやすい)。

実務で「複数条件」が増えていくときは、この“条件に名前をつけるスタイル”を強くおすすめします。


AND 条件と OR 条件を混ぜるときの注意点

「A かつ(B または C)」のようなパターン

例えば、こんな条件を考えます。

「顧客ランクがゴールド かつ ステータスが『確定』または『仮』」

日本語で書くと曖昧ですが、論理的にはこうです。

顧客ランク = “ゴールド”
かつ
(ステータス = “確定” または ステータス = “仮”)

これを M で書くときに大事なのは、「かっこ」でグループをはっきりさせることです。

let
    Source = ・・・前のステップ・・・,

    Filtered =
        Table.SelectRows(
            Source,
            each
                [顧客ランク] = "ゴールド"
                and (
                    [ステータス] = "確定"
                    or [ステータス] = "仮"
                )
        )
in
    Filtered
Power Query

かっこがないと、andor の優先順位で意図しない結果になりがちです。
「A かつ(B または C)」なのか、「(A かつ B)または C」なのかは、
必ずかっこで明示してあげてください。


実務でよくある複数条件テンプレ集

日付範囲 + ステータス + フラグ

「2024年1月の確定データで、削除フラグが 0 のものだけ」

Table.SelectRows(
    Source,
    each
        [受注日] >= #date(2024, 1, 1)
        and [受注日] <= #date(2024, 1, 31)
        and [ステータス] = "確定"
        and [削除フラグ] = 0
)
Power Query

数値範囲 + 区分の複数候補

「売上金額が 10,000 以上 かつ 商品区分が A または B」

Table.SelectRows(
    Source,
    each
        [売上金額] >= 10000
        and (
            [商品区分] = "A"
            or [商品区分] = "B"
        )
)
Power Query

文字列の「含む」+フラグ

「商品名に『試供品』を含む かつ 削除フラグが 0」

Table.SelectRows(
    Source,
    each
        Text.Contains(Text.From([商品名]), "試供品")
        and [削除フラグ] = 0
)
Power Query

ここまで来ると、今までやってきた「トリム」「特定文字列行削除」「日付変換」などと組み合わせて、
かなり柔軟な“抽出条件”を組めるようになります。


もう一歩進んだ実務テンプレ:条件を関数化する

「この行が採用かどうか」を判定する関数を作る

条件が複雑になってきたら、
「行を受け取って true/false を返す関数」を作っておくと、クエリ側がかなりスッキリします。

// クエリ名:fn_IsTargetRow
let
    IsTargetRow = (r as record) as logical =>
        let
            isInJan2024 =
                r[受注日] >= #date(2024, 1, 1)
                and r[受注日] <= #date(2024, 1, 31),

            isGold =
                r[顧客ランク] = "ゴールド",

            isHighSales =
                r[売上金額] >= 10000,

            isNotDeleted =
                r[削除フラグ] = 0
        in
            isInJan2024
            and isGold
            and isHighSales
            and isNotDeleted
in
    IsTargetRow
Power Query

これを使うと、クエリ側はこう書けます。

let
    Source = ・・・前のステップ・・・,

    Filtered =
        Table.SelectRows(
            Source,
            each fn_IsTargetRow(_)
        )
in
    Filtered
Power Query

_ は「今見ている行(record)」を表します。
条件が長くなっても、クエリ側は「この行が対象かどうかを関数に聞いているだけ」という形になり、
読みやすさと再利用性が一気に上がります。


重要ポイントの深掘り

「抽出」と「除外」は表裏一体

複数条件で行抽出するとき、
「欲しい行だけ残す」のか、「いらない行だけ落とす」のかは、実は同じことです。

例えば、

「削除フラグ = 0 の行だけ残す」
は、
「削除フラグ = 1 の行を除外する」
と同じ意味です。

M では、not を使って簡単に反転できます。

each [削除フラグ] = 0
Power Query

と書くか、

each not ([削除フラグ] = 1)
Power Query

と書くか。
どちらでも動きますが、「どちらの方が読みやすいか」で選んでください。

条件は「早めに」「まとめて」かけるとクエリが安定する

実務では、次のような順番が安定しやすいです。

型変換(数値・日付・テキストをそろえる)
クレンジング(トリム、全角→半角、改行削除、不正文字除去など)
複数条件で行抽出(欲しい行だけに絞る)

先にクレンジングしておくことで、
「空白や変な文字が原因で条件判定がズレる」ことを防げます。
あなたがここまで積み上げてきた前処理テンプレと、「複数条件抽出」をセットで使うと、
かなり“壊れにくい”クエリになります。


実務テンプレとしてのまとめ

「複数条件で行抽出」の本質は、次の二つです。

Table.SelectRows の each の中で、and / or / not を使って条件を組み立てる。
条件が増えてきたら、let ~ in で条件に名前をつけるか、関数化して読みやすくする。

この型さえ体に入っていれば、
「日付範囲+ランク+金額+フラグ」「区分の複数候補+文字列条件」など、
どんな複雑な抽出条件でも、落ち着いて M に落とし込めるようになります。

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