ゴールのイメージをそろえる
今回のテーマは「Power Query で “特定の文字列を含む行だけをきれいに削除する” 実務テンプレ」です。
やりたいことはシンプルです。
「備考に『テスト』と入っている行は全部いらない」
「商品名に『サンプル』を含む行は分析対象から除外したい」
「顧客名に『社内用』が入っている行は本番集計から外したい」
こういう“いらない行の条件”を、文字列ベースでサクッと削れるようにします。
まず「どこに、どんな文字列が紛れているか」をイメージする
ありがちな「特定文字列を含む行」の例
例えば、こんなテーブルを想像してください。
| 商品コード | 商品名 | 備考 |
|---|---|---|
| A001 | 通常商品A | “” |
| A002 | 通常商品B | “テストデータ” |
| A003 | サンプル商品C | “” |
| A004 | 通常商品D(社内用) | “社内検証用” |
| A005 | 通常商品E | “” |
ここで、次のような要望があるとします。
「備考に『テスト』を含む行は削除したい」
「商品名に『サンプル』を含む行も削除したい」
「『社内用』『社内検証用』など、社内向けの行も全部いらない」
つまり、「特定の文字列を含む行を、条件でまとめて落としたい」というニーズです。
基本の型:1列の「特定文字列を含む行」を削除する
備考列に「テスト」を含む行を削除する
まずは一番シンプルなパターンからいきます。
「備考」列に「テスト」という文字列を含む行を削除するテンプレです。
let
Source = ・・・前のステップ・・・,
Filtered =
Table.SelectRows(
Source,
each
let
v = [備考],
t =
if v = null then
""
else
Text.From(v)
in
not Text.Contains(t, "テスト")
)
in
Filtered
Power Queryやっていることを言葉で整理します。
備考列の値を v として取り出す。
NULL の場合は空文字 "" にしておく(Text.Contains でエラーにしないため)。
Text.Contains(t, “テスト”) で、「テスト」を含むかどうかを判定する。
含む行は除外したいので、not Text.Contains(...) を条件にしている。
結果として、「備考に『テスト』を含む行」はすべて削除されます。
応用:大文字・小文字を無視して判定したい場合
Text.Contains の「比較方法」を指定する
英字を扱うときに、「test」「TEST」「Test」を全部同じ扱いにしたいことがあります。
その場合は、Text.Contains の第3引数に Comparer.OrdinalIgnoreCase を渡します。
Text.Contains(t, "test", Comparer.OrdinalIgnoreCase)
Power Queryこれを使えば、「test」「TEST」「TeSt」など、大小文字の違いを無視して判定できます。
日本語だけなら気にしなくていいですが、「英字+日本語」が混ざる現場では覚えておくと便利です。
複数列をまとめて「特定文字列を含む行」を削除する
商品名か備考のどちらかに「サンプル」を含む行を削除したい
今度は、「商品名」か「備考」のどちらかに『サンプル』が入っていたら、その行を削除したい、というパターンです。
let
Source = ・・・前のステップ・・・,
Filtered =
Table.SelectRows(
Source,
each
let
name =
if [商品名] = null then
""
else
Text.From([商品名]),
note =
if [備考] = null then
""
else
Text.From([備考]),
hasSample =
Text.Contains(name, "サンプル")
or Text.Contains(note, "サンプル")
in
not hasSample
)
in
Filtered
Power Queryポイントはこうです。
商品名と備考の両方を文字列として取り出す。
どちらか一方でも「サンプル」を含んでいたら、その行は削除対象。
なので、hasSample を OR で作り、not hasSample をフィルタ条件にしている。
これで、「商品名にサンプル」「備考にサンプル」「両方にサンプル」——どのパターンでも、その行は落ちます。
複数の「NGワード」をまとめて管理したい
「テスト」「サンプル」「社内用」などを一括で扱う
実務では、「NGワード」が1つではなく、複数あることが多いです。
「テスト」「サンプル」「社内用」「検証用」など、
“本番集計から除外したいキーワード”をまとめて管理したい場合は、
リストにしておいて「どれか一つでも含んでいたら削除」というロジックにするとスッキリします。
let
Source = ・・・前のステップ・・・,
// NGワードのリスト
NgWords = {"テスト", "サンプル", "社内用", "検証用"},
Filtered =
Table.SelectRows(
Source,
each
let
// 対象とする列をまとめて文字列にする(ここでは商品名+備考)
name =
if [商品名] = null then
""
else
Text.From([商品名]),
note =
if [備考] = null then
""
else
Text.From([備考]),
targetText = name & " " & note,
// NGワードのどれかを含むかどうか
hasNg =
List.AnyTrue(
List.Transform(
NgWords,
(w) => Text.Contains(targetText, w)
)
)
in
not hasNg
)
in
Filtered
Power Queryここが重要ポイントです。
NgWords に「削除対象のキーワード」を全部並べておく。
商品名と備考をくっつけて、検索対象の文字列 targetText を作る。
List.Transform で「各 NGワード w について Text.Contains(targetText, w)」を評価する。
List.AnyTrue で「どれか一つでも true なら hasNg = true」と判定する。
hasNg が true(NGワードを含む行)は削除したいので、not hasNg を条件にする。
この型を一度作っておけば、NgWords にキーワードを足すだけで、
「除外条件」を柔軟に増やしていけます。
もう一歩進んだ実務テンプレ:関数化して再利用する
「特定文字列を含むかどうか」を判定する関数を作る
毎回同じロジックを書くのが面倒なら、
「NGワードリストと対象文字列を渡すと、含むかどうかを返す関数」を作っておくと便利です。
// クエリ名:fn_HasNgWord
let
HasNgWord = (text as nullable text, ngList as list) as logical =>
let
t =
if text = null then
""
else
Text.From(text),
flags =
List.Transform(
ngList,
(w) => Text.Contains(t, w)
),
result = List.AnyTrue(flags)
in
result
in
HasNgWord
Power Queryこれを使えば、クエリ側はかなりスッキリ書けます。
let
Source = ・・・前のステップ・・・,
NgWords = {"テスト", "サンプル", "社内用", "検証用"},
Filtered =
Table.SelectRows(
Source,
each
let
targetText =
Text.From([商品名]) & " " & Text.From([備考])
in
not fn_HasNgWord(targetText, NgWords)
)
in
Filtered
Power Query「NGワードを含む行を落としている」という意図が、コードから一目で分かるようになります。
重要ポイントの深掘り
「含む」か「完全一致」かを意識する
今回のテーマは「特定文字列を含む行削除」なので Text.Contains を使っていますが、
「完全一致のときだけ削除したい」なら、Text.Contains ではなく単純な比較にします。
例えば、「備考がちょうど『テスト』の行だけ削除したい」なら、
each [備考] <> "テスト"
Power Queryで十分です。
「含む」と「一致」は、意図が全然違うので、ここは意識的に使い分けてください。
前後の空白・全角半角・改行もセットで考える
実務では、次のような“微妙な違い”がよく混ざります。
“テスト”
” テスト “(前後に空白)
“テスト ”(全角スペース付き)
“テスト\r\n”(改行付き)
これらを全部「テストを含む」とみなしたいなら、
先に「トリム」「改行削除」「全角→半角」などのクレンジングを入れておくと、判定が安定します。
あなたがすでに作ってきた前処理テンプレ(トリム、改行削除、不正文字除去など)と、
「特定文字列を含む行削除」を組み合わせると、かなり強い“前処理パイプライン”になります。
実務テンプレとしてのまとめ
「特定文字列を含む行削除」の本質は、次の二つです。
Text.Contains(+必要なら NGワードリスト)で「削除対象かどうか」を論理値で判定する。
その判定を Table.SelectRows の条件にして、「残したい行だけ」をテーブルとして残す。
この型さえ持っておけば、
テストデータ・サンプルデータ・社内用データ・ダミー行など、
「本番集計から外したい行」を、文字列ベースで機械的に落とせるようになります。

