Excelへ外部データを貼り付けたり、複数人が入力した名簿やアンケートを集計したりすると、文字列の前後や途中に不要な空白が混入することがあります。画面上では同じように見える値でも、Excel内部では別の文字列として扱われる場合があります。
空白の除去は、文字列をきれいに見せるための化粧ではありません。同じ意味を持つ値を、同じ値として比較・集計できる状態へ戻すデータクレンジングです。
本稿では、最初に一つのサンプル表を作り、その表へ列を追加しながら処理を進めます。途中で別の例へ切り替えないため、TRIMで整う通常の空白、内部に残る全角空白、改行や特殊空白、完全削除してよい値の違いを同じデータ上で比較できます。
| 基本 | =TRIM(A2) |
|---|---|
| 実務向け | =TRIM(SUBSTITUTE(SUBSTITUTE(CLEAN(A2),CHAR(160)," ")," "," ")) |
| 新関数版 | =LET(cleaned,CLEAN(A2),spaceNormalized,SUBSTITUTE(SUBSTITUTE(cleaned,CHAR(160)," ")," "," "),TRIM(REGEXREPLACE(spaceNormalized," +"," "))) |
最初に、記事全体で使用するサンプルデータを作る
A列に「元データ」、B列に「用途」を入力します。A2:A9には、半角スペース、全角スペース、連続空白、改行、ノーブレークスペースなど、実務で遭遇しやすい問題を意図的に含めます。
| A | B | |
|---|---|---|
| 1 | 元データ | 用途 |
| 2 | ␠愛知県 | 都道府県 |
| 3 | 愛知県␠ | 都道府県 |
| 4 | □愛知県 | 都道府県 |
| 5 | 山田□□太郎 | 氏名 |
| 6 | 東京␠␠都 | カテゴリ名 |
| 7 | 営業部↵第一課 | 部署名 |
| 8 | ABC SERVICE | 会社名 |
| 9 | 090␠1234␠5678 | 電話番号 |
※「␠」は半角スペース、「□」は全角スペース、「↵」はセル内改行を可視化した記号です。8行目の空白はWebページなどに含まれるノーブレークスペースを想定しています。
実際にExcel上で再現する場合は、次の数式をA2:A9へ入力します。文字として見えない空白や改行を、関数で確実に作れるためです。
| A2 | =" "&"愛知県" |
|---|---|
| A3 | ="愛知県"&" " |
| A4 | =" "&"愛知県" |
| A5 | ="山田"&" "&"太郎" |
| A6 | ="東京"&" "&"都" |
| A7 | ="営業部"&CHAR(10)&"第一課" |
| A8 | ="ABC"&CHAR(160)&"SERVICE" |
| A9 | ="090 1234 5678" |
以降は、このA2:A9を固定して使用します。処理結果はC列以降へ順番に追加し、最後に同じ表の中で比較します。
空白処理は「見栄え」ではなく、集計結果を守るために行う
A2:A4はいずれも「愛知県」に見えます。しかし、A2には先頭の半角スペース、A3には末尾の半角スペース、A4には先頭の全角スペースが含まれています。
- ピボットテーブルで同じカテゴリが複数に分かれる
- COUNTIF・SUMIF・SUMIFSの件数や合計が合わない
- XLOOKUP・VLOOKUP・MATCHで一致しない
- UNIQUEで実質的に同じ値が複数表示される
- 重複削除や名寄せで同一候補を見落とす
したがって、空白処理は集計後の体裁調整ではなく、集計・照合・名寄せを始める前に行う前処理です。
同じサンプルデータへTRIM関数を適用する
C1に「TRIM後」と入力し、C2へ次の数式を入力してC9までコピーします。
| C2 | =TRIM(A2) |
|---|
日本語版ExcelのTRIM関数は、半角スペースだけでなく全角スペースも対象にします。前後の空白を削除し、文字列の途中に連続する空白は1個だけ残します。
| A | B | C | |
|---|---|---|---|
| 1 | 元データ | 用途 | TRIM後 |
| 2 | ␠愛知県 | 都道府県 | 愛知県 |
| 3 | 愛知県␠ | 都道府県 | 愛知県 |
| 4 | □愛知県 | 都道府県 | 愛知県 |
| 5 | 山田□□太郎 | 氏名 | 山田□太郎 |
| 6 | 東京␠␠都 | カテゴリ名 | 東京␠都 |
| 7 | 営業部↵第一課 | 部署名 | 営業部↵第一課 |
| 8 | ABC SERVICE | 会社名 | ABC SERVICE |
| 9 | 090␠1234␠5678 | 電話番号 | 090␠1234␠5678 |
A2~A6はTRIMだけで改善しました。先頭・末尾の半角空白だけでなく、A4の先頭にある全角空白も削除され、A5の連続する全角空白は1個に整理されます。一方、改行を含むA7とノーブレークスペースを含むA8は残ります。A9の内部空白も1個ずつなので、そのまま残ります。
POINT
TRIMは半角・全角を問わず、文字列の前後にある通常の空白を削除し、途中に連続する通常の空白を1個に整理します。ただし、セル内改行やノーブレークスペースなど、通常の空白とは異なる文字までは処理できません。
内部空白の表記統一・改行・特殊空白まで、同じ表で処理する
D1に「標準クレンジング後」と入力し、D2へ次の数式を入力してD9までコピーします。
| D2 | =TRIM(SUBSTITUTE(SUBSTITUTE(CLEAN(A2),CHAR(160)," ")," "," ")) |
|---|
数式は内側から、次の順番で処理します。
- CLEAN関数で改行・タブなど一部の制御文字を取り除く
- CHAR(160)のノーブレークスペースを半角スペースへ変換する
- 内部に残る全角スペースを半角スペースへ統一する
- TRIM関数で前後と連続する半角スペースを整える
| A | C | D | |
|---|---|---|---|
| 1 | 元データ | TRIM後 | 標準クレンジング後 |
| 2 | ␠愛知県 | 愛知県 | 愛知県 |
| 3 | 愛知県␠ | 愛知県 | 愛知県 |
| 4 | □愛知県 | 愛知県 | 愛知県 |
| 5 | 山田□□太郎 | 山田□太郎 | 山田␠太郎 |
| 6 | 東京␠␠都 | 東京␠都 | 東京␠都 |
| 7 | 営業部↵第一課 | 営業部↵第一課 | 営業部第一課 |
| 8 | ABC SERVICE | ABC SERVICE | ABC␠SERVICE |
| 9 | 090␠1234␠5678 | 090␠1234␠5678 | 090␠1234␠5678 |
D列ではA2:A8までの表記が実務上扱いやすい形へそろいました。ただし、A9の電話番号は内部空白が意味のない区切りなので、別の処理が必要です。ここで「空白を1個残して統一する処理」と「すべて削除する処理」を分ける必要が見えてきます。
LET・REGEXREPLACE・MAPでも、同じA2:A9を処理する
D列の数式は十分実用的ですが、関数が入れ子になっているため処理内容を読み取りにくくなります。LET関数を使うと、中間結果に英語名を付けられます。ここでは
source、cleaned、nbspNormalized、spaceNormalized
に統一します。
| E2 | =LET(source,A2,cleaned,CLEAN(source),nbspNormalized,SUBSTITUTE(cleaned,CHAR(160)," "),spaceNormalized,SUBSTITUTE(nbspNormalized," "," "),TRIM(spaceNormalized)) |
|---|
E2をE9までコピーすると、結果はD列と同じになります。変数名はすべて英語に統一しているため、後続のREGEXREPLACE版やMAP版とも対応関係を追いやすくなります。LET関数の利点は結果を変えることではなく、何をどの順序で処理したかを数式内に残せることです。
REGEXREPLACE関数を利用できるExcelでは、同じ処理を次のように記述できます。
| F2 | =LET(cleaned,CLEAN(A2),spaceNormalized,SUBSTITUTE(SUBSTITUTE(cleaned,CHAR(160)," ")," "," "),TRIM(REGEXREPLACE(spaceNormalized," +"," "))) |
|---|
正規表現の +
は「半角スペースが1個以上連続する箇所」を意味します。今回の結果はD列・E列とほぼ同じですが、将来タブや複数種類の区切り文字をまとめて扱う場合に拡張しやすくなります。
※REGEXREPLACE関数を利用できないExcelでは、D列のTRIM・CLEAN・SUBSTITUTEによる式を使用してください。
ここまでは各行へ数式をコピーしました。MAP関数を使うと、A2:A9全体を一つの数式で処理できます。G1に「MAP一括処理」と入力し、G2へ次の数式を入力します。
| G2 | =MAP(A2:A9,LAMBDA(value,IF(value="","",LET(cleaned,CLEAN(value),spaceNormalized,SUBSTITUTE(SUBSTITUTE(cleaned,CHAR(160)," ")," "," "),TRIM(REGEXREPLACE(spaceNormalized," +"," ")))))) |
|---|
結果はG2:G9へスピルします。同じクレンジングロジックを一か所で管理できるため、対象範囲が増えても数式を行ごとに修正する必要がありません。
💡 同じデータで比較すると、新関数の役割が分かりやすい
D列、E列、F列、G列は、ほぼ同じ結果を返します。違いは「何ができるか」よりも、数式の読みやすさ、拡張性、一括処理のしやすさにあります。同じA2:A9へ適用することで、各関数の役割を結果ではなく設計面から比較できます。
同じサンプルのうち、電話番号だけは空白をすべて削除する
A5の氏名「山田 太郎」やA8の会社名「ABC SERVICE」では、内部空白は語の区切りです。したがって、D列のように半角1個へ統一するのが妥当です。
一方、A9の電話番号「090 1234 5678」は、比較・検索用データとしては空白を含まない方が扱いやすくなります。H1に「用途別の最終結果」と入力し、H2へ次の数式を入力してH9までコピーします。
| H2 | =LET(cleaned,TRIM(SUBSTITUTE(SUBSTITUTE(CLEAN(A2),CHAR(160)," ")," "," ")),IF(B2="電話番号",SUBSTITUTE(cleaned," ",""),cleaned)) |
|---|
| A | B | H | |
|---|---|---|---|
| 1 | 元データ | 用途 | 用途別の最終結果 |
| 2 | ␠愛知県 | 都道府県 | 愛知県 |
| 3 | 愛知県␠ | 都道府県 | 愛知県 |
| 4 | □愛知県 | 都道府県 | 愛知県 |
| 5 | 山田□□太郎 | 氏名 | 山田␠太郎 |
| 6 | 東京␠␠都 | カテゴリ名 | 東京␠都 |
| 7 | 営業部↵第一課 | 部署名 | 営業部第一課 |
| 8 | ABC SERVICE | 会社名 | ABC␠SERVICE |
| 9 | 090␠1234␠5678 | 電話番号 | 09012345678 |
ここで重要なのは、同じ空白でも一律に消さないことです。列の用途に応じて、内部空白を1個残すか、完全に削除するかを決めます。
同じ表のまま、修正の有無と文字数の変化を検証する
I1に「判定」、J1に「削除・統一文字数」と入力します。
| I2 | =IF(A2<>H2,"修正あり","変更なし") |
|---|---|
| J2 | =LEN(A2)-LEN(H2) |
それぞれI9、J9までコピーすると、最初から使用してきた同じサンプル表が完成します。
| A | B | H | I | J | |
|---|---|---|---|---|---|
| 1 | 元データ | 用途 | 最終結果 | 判定 | 文字数差 |
| 2 | ␠愛知県 | 都道府県 | 愛知県 | 修正あり | 1 |
| 3 | 愛知県␠ | 都道府県 | 愛知県 | 修正あり | 1 |
| 4 | □愛知県 | 都道府県 | 愛知県 | 修正あり | 1 |
| 5 | 山田□□太郎 | 氏名 | 山田␠太郎 | 修正あり | 1 |
| 6 | 東京␠␠都 | カテゴリ名 | 東京␠都 | 修正あり | 1 |
| 7 | 営業部↵第一課 | 部署名 | 営業部第一課 | 修正あり | 1 |
| 8 | ABC SERVICE | 会社名 | ABC␠SERVICE | 修正あり | 0 |
| 9 | 090␠1234␠5678 | 電話番号 | 09012345678 | 修正あり | 2 |
A8はノーブレークスペースを通常の半角スペースへ置換していますが、どちらも1文字なので文字数差は0です。したがって、LENの差だけでは修正の有無を判定できません。A列とH列を直接比較するI列も併用する必要があります。
IMPORTANT
文字数が減ったから正しいとは限りません。内部の意味ある空白を誤って消した場合も文字数は減ります。元データを残し、用途列と最終結果を並べて確認することが重要です。
まとめ ―― 一つのサンプル表で試すと、関数の役割と判断基準がつながる
本稿ではA2:A9の同じサンプルデータを使い、TRIMだけの結果、複合クレンジング、LET・REGEXREPLACE・MAPによる書き換え、用途別の完全削除、最後の差分検証まで進めました。
| TRIM | =TRIM(A2) |
|---|---|
| 標準式 | =TRIM(SUBSTITUTE(SUBSTITUTE(CLEAN(A2),CHAR(160)," ")," "," ")) |
| LET版 | =LET(source,A2,cleaned,CLEAN(source),nbspNormalized,SUBSTITUTE(cleaned,CHAR(160)," "),spaceNormalized,SUBSTITUTE(nbspNormalized," "," "),TRIM(spaceNormalized)) |
| 正規表現版 | =LET(cleaned,CLEAN(A2),spaceNormalized,SUBSTITUTE(SUBSTITUTE(cleaned,CHAR(160)," ")," "," "),TRIM(REGEXREPLACE(spaceNormalized," +"," "))) |
| MAP一括 | =MAP(A2:A9,LAMBDA(value,IF(value="","",LET(cleaned,CLEAN(value),spaceNormalized,SUBSTITUTE(SUBSTITUTE(cleaned,CHAR(160)," ")," "," "),TRIM(REGEXREPLACE(spaceNormalized," +"," ")))))) |
| 用途別 | =LET(cleaned,TRIM(SUBSTITUTE(SUBSTITUTE(CLEAN(A2),CHAR(160)," ")," "," ")),IF(B2="電話番号",SUBSTITUTE(cleaned," ",""),cleaned)) |
- 通常の半角・全角スペース:TRIMで前後を削除し、連続部分を1個へまとめる。
- 内部空白の表記統一:全角を半角へそろえる場合はSUBSTITUTEを組み合わせる。
- 改行・特殊空白:CLEANとCHAR(160)を指定したSUBSTITUTEを組み合わせる。
- 新関数:LETで読みやすくし、REGEXREPLACEで拡張し、MAPで範囲全体へ一括適用する。
- 内部空白:氏名・会社名では残し、電話番号などでは完全削除を検討する。
- 検証:元データを上書きせず、修正判定と文字数差を同じ表で確認する。
空白処理では、関数を知るだけでなく、各処理が同じデータをどう変えるかを比較することが重要です。一つの表を最後まで使うことで、技術的な処理と、列の意味に基づく判断を切り離さずに学べます。