ゴールのイメージをそろえる
今回のテーマは「Power Query で“全ての列の前後の空白(スペース)を一括で削る”実務テンプレ」を身につけることです。
目指すのは、「どの列に空白が紛れ込んでいても、とりあえず一発でキレイにする」状態です。
ポイントはこうです。
文字列列だけに Trim(前後空白除去)をかける。
列が増えても、列名が変わっても壊れない“汎用テンプレ”にする。
ここを押さえておくと、「JOIN が効かない」「集計がズレる」といった“空白トラブル”をかなり防げます。
なぜ「全列トリム」が必要になるのか
ありがちなトラブルの正体
実務データでよくあるのが、次のようなパターンです。
「店舗コード」で結合したのに、一部だけ結合されない。
同じ値で集計しているはずなのに、なぜか別グループとして扱われる。
原因をよく見ると、こうなっていたりします。
"A001" と "A001 "(後ろにスペース)" 東京"(前に全角スペース)"A001 "(半角+全角スペース混在)
見た目は同じでも、文字としては別物なので、JOIN も GROUP BY も効きません。
これを防ぐための“最初の一手”が「全列トリム」です。
例題の前提データをイメージする
こんなテーブルを想像してください
例えば、こんな感じのテーブルがあるとします。
| 店舗コード | 店舗名 | 商品コード | 数量 |
|---|---|---|---|
"A001 " | " 東京店" | "P001" | 10 |
"A002" | "大阪店 " | "P002 " | 5 |
見た目はそれっぽいですが、実際の中身はこうです。
店舗コード:"A001 "(後ろに半角スペース)
店舗名:" 東京店"(前に全角スペース)
商品コード:"P002 "(後ろに半角スペース)
このまま別テーブルと結合しようとすると、かなりの確率で事故ります。
ここに「全列トリム」をかけて、全部 "A001", "東京店", "P002" のように揃えてしまう、というのが今回のゴールです。
基本形:文字列列だけを一括トリムするテンプレ
コード全体を先に出す
Power Query(M 言語)での“全列トリム”の実務テンプレは、こんな形です。
let
Source = ・・・前のステップ・・・,
// 1) 文字列型の列だけを抽出
TextColumns =
Table.ColumnNames(
Table.SelectColumns(
Source,
List.Select(
Table.ColumnNames(Source),
(colName) =>
Value.Type(Source[colName]) = type text
)
)
),
// 2) 文字列列に Text.Trim をかける変換リストを作成
TransformList =
List.Transform(
TextColumns,
(colName) => {colName, Text.Trim, type text}
),
// 3) Table.TransformColumns で一括トリム
Trimmed =
Table.TransformColumns(
Source,
TransformList
)
in
Trimmed
Power Queryいきなり見ると「うっ」となるかもしれませんが、やっていることはシンプルです。
文字列列の名前だけをリストに集める。
その列名リストから「この列に Text.Trim をかける」という指示リストを作る。
その指示リストを Table.TransformColumns に渡して、一括変換する。
ここを順番にかみ砕いていきます。
ステップごとの分解と深掘り
ステップ1:文字列型の列だけを抽出する
TextColumns =
Table.ColumnNames(
Table.SelectColumns(
Source,
List.Select(
Table.ColumnNames(Source),
(colName) =>
Value.Type(Source[colName]) = type text
)
)
),
Power Queryここが一番“トリッキーに見える”ところなので、分解して説明します。
Table.ColumnNames(Source)
Source テーブルの列名を、{"店舗コード", "店舗名", "商品コード", "数量"} のようなリストで返します。
List.Select( ..., (colName) => 条件 )
その列名リストから、「条件を満たす列名だけ」を残します。
ここでの条件は Value.Type(Source[colName]) = type text です。
Value.Type(Source[colName])Source[colName] は「その列の値のリスト」です。Value.Type をかけると、その列の型(type text, type number など)が返ってきます。
つまり、「列の型が text のものだけを選ぶ」というフィルタになっています。
Table.SelectColumns(Source, その列名リスト)
Source から「文字列列だけ」を抜き出したテーブルを作ります。
Table.ColumnNames(そのテーブル)
そのテーブルの列名をもう一度リストとして取り出します。
結果として、TextColumns には「文字列列の名前だけ」が入ります。
例のテーブルなら、TextColumns は {"店舗コード", "店舗名", "商品コード"} になります。
ここでの超重要ポイントは、「列名を手書きしない」ということです。
新しい文字列列が増えても、自動的に対象に含まれます。
ステップ2:変換リスト(TransformList)を作る
TransformList =
List.Transform(
TextColumns,
(colName) => {colName, Text.Trim, type text}
),
Power QueryList.Transform は、「リストの各要素に対して同じ処理をして、新しいリストを作る」関数です。
ここでは、TextColumns の各列名に対して {列名, Text.Trim, type text} という3要素のリストを作っています。
例えば、TextColumns が {"店舗コード", "店舗名", "商品コード"} なら、TransformList はこうなります。
{
{"店舗コード", Text.Trim, type text},
{"店舗名", Text.Trim, type text},
{"商品コード", Text.Trim, type text}
}
Power Queryこれは、Table.TransformColumns に渡すための「変換指示書」です。
「店舗コード列には Text.Trim をかけて、型は text にする」
「店舗名列には Text.Trim をかけて、型は text にする」
…という意味になります。
ステップ3:Table.TransformColumns で一括トリム
Trimmed =
Table.TransformColumns(
Source,
TransformList
)
Power QueryTable.TransformColumns は、「指定した列に対して、指定した関数で値を変換する」関数です。
ここでは、TransformList で「どの列に」「どの関数を」かけるかをまとめて渡しています。
結果として、Source のすべての文字列列に Text.Trim がかかり、
前後の空白が削られたテーブル Trimmed が得られます。
この時点で、さっきの例はこうなります。
| 店舗コード | 店舗名 | 商品コード | 数量 |
|---|---|---|---|
"A001" | "東京店" | "P001" | 10 |
"A002" | "大阪店" | "P002" | 5 |
JOIN も GROUP BY も、安心して使える状態です。
もっとシンプルな「列名を手書きする」版
列が少ない・固定ならこれでもOK
「まずは仕組みより動けばいい」「列はそんなに多くないし増えない」という場合は、
もっとシンプルに「列名を手書きする」版でも構いません。
let
Source = ・・・前のステップ・・・,
Trimmed =
Table.TransformColumns(
Source,
{
{"店舗コード", Text.Trim, type text},
{"店舗名", Text.Trim, type text},
{"商品コード", Text.Trim, type text}
}
)
in
Trimmed
Power Queryこれは、さっきの TransformList を手書きしているだけです。
メリット:読みやすい・直感的。
デメリット:列が増えたら自分で追記しないといけない。
「まずはこれで動かしてみて、慣れてきたら自動判定版に切り替える」というステップでも全然アリです。
実務テンプレとしてのまとめ
「全列トリム(前後空白除去)」の本質は、たった一言です。
「文字列列を自動で見つけて、全部 Text.Trim に通しておく」
これをクレンジングの最初の方に一発入れておくだけで、
JOIN が効かない・集計が割れる・IF で一致しない、といった“空白由来のバグ”をかなり潰せます。
あなたのクエリの中で、「ここから先は“きれいな文字列”として扱いたい」というステップの直前に、
このテンプレを一段挟むイメージで組み込んでみてください。
