見えない文字、そこにいる?EXCEL VBAで探そう。
「見えないスペース」の正体は? テキスト編集でハマりがちな落とし穴と対策
「あれ? 見た目は完璧なのに、なぜかうまくデータが処理できない…」
「後ろにスペース入ってないし、TABも入ってない、改行もない?」
こんな経験はありませんか? 特にデータを扱っていると、視覚的には問題ないのに、システムやマクロが予期せぬ挙動をすることがあります。その原因の一つが、今回ご紹介する「見えないスペースや文字」の存在。
😱 見えない文字、そこにいた!
Windowsのメモ帳や一般的なテキストエディタでも、肉眼では確認できない特殊な文字が存在することがあります(Macでも似たような状況は考えられます)。
この文字は、見た目では全く判別できないため、非常に気づきにくいのが厄介な点です。
💡 どうやって見つける?
カーソルを問題の箇所に持って行き、一文字ずつ移動させてみてください。もし、明らかにスペースがないはずの場所でカーソルが「一歩分」動くようなら、そこに「見えない文字」が潜んでいる証拠です。
また、手軽にチェックできる便利なツールもあります。
💻 さぶみっと様サイトのツール: [https://form.submitmail.jp/tools/check/]
このサイトで確認したいテキストを入力すると、目に見えない文字を検出してくれるので、困ったときには活用してみましょう!


🧐 正体は「LRM」? データ処理を邪魔する制御文字
今回、特に問題となることが多い文字の一つが、LRM(Left-to-Right Mark / 左から右へのマーク)です。
これはUnicodeで定義されている制御文字の一種です。
### LRMとは?
LRMは目には見えませんが、テキストの表示方向を制御するために使われます。
アラビア語やヘブライ語のように右から左(RTL)に書く言語と、日本語や英語のように左から右(LTR)に書く言語が混在するテキストにおいて、文字の並び順がおかしくならないように調整する役割を持っています。
メモ帳のようなシンプルなエディタやEXCEL、この制御文字を特に表示しないため、「見えない文字」として残ってしまうのです。sakuraエディタも拡大すると何となく分かる程度です。
なぜ混入するの?
LRMのような文字は、以下のようなケースで意図せずデータに紛れ込むことがあります。
ウェブサイトからのコピー&ペースト:
ウェブサイトのデザインによっては、RTL言語とLTR言語の混在を考慮して、表示を安定させるために見えない制御文字が使用されており、それがコピー時に一緒に貼り付いてしまう。
システム間の文字コード変換:
異なる言語環境のシステム間でデータがやり取りされた際、表示の整合性を保つために自動的に挿入される。
🛠️ 見えない文字をクリーンアップ! 削除テクニック集
手で一文字ずつ消すことも可能ですが、データ処理の自動化を図るなら、マクロやExcel関数で事前に削除するのが最も効率的です。
※筆者流です
VBA(マクロ)編
VBAでは、LRMを通常の文字として扱い、そのUnicodeコードポイントを指定して削除します。
LRMのUnicodeコードポイントは $U+200E$ です。VBAではこれを `ChrW(&H200E)` で指定します。
vba、LRM(左から右へのマーク)を削除
データフィールド = Replace(データフィールド, ChrW(&H200E), “")
この方法で、他の一般的な見えない文字やスペースもまとめて削除しておくと安心です。
※Replace関数は、指定した文字列を別の文字列に置き換える(この場合は空文字に置き換えることで削除する)ために使用します。
こんな感じで作りこんでます。
データフィールド = Replace(データフィールド, " “, “") '### スペース
データフィールド = Replace(データフィールド, ChrW(65039), “") '### ChrW(65039)
データフィールド = Replace(データフィールド, ChrW(160), “") '### ChrW(160)
データフィールド = Replace(データフィールド, ChrW(11), “") '### ChrW(11)
データフィールド = Replace(データフィールド, ChrW(&H200E), “") '### 見えないスペースLRM ChrW(&H200E)
EXCEL関数編
Excelの関数を使う場合も、同様にUnicodeコードポイントを指定します。
LRMのUnicodeコードポイントは (8206)です。
=SUBSTITUTE(A1, UNICHAR(8206), “")
UNICHAR(8206):
Unicodeコードポイント 8206 (LRM) に対応する文字を返します。
SUBSTITUTE:
セル A1 の中の LRM を、空文字 (`""`) に置き換える(つまり削除する)という処理です。
—–
💡 まとめ:見えない敵に打ち勝とう(笑)
目に見えない文字は、データクレンジングの大きな障害となり得ますが、その正体と対策さえ知っていれば怖くありません。
もしデータ処理で原因不明のエラーに遭遇したら、まずは「見えないスペース」を疑ってみてください。マクロや関数で対策リストを整備しておけば、もう二度とこの問題に時間を取られることはないでしょう!
あなたのデータ処理が、よりスムーズに進みますように!といいつつ、割とEXCELの沼にはまる筆者です。
見た目は普通 テキストの濁点が化ける。変換マクロ作ってみた。
Geminiに書いてもらいました。自分のは汚いので、、、
Sub InvisibleCharCleaner()
'
' 選択範囲(Selection)のデータから、主な見えない文字を一括削除するマクロ
'
Dim r As Range
Dim cell As Range
' 処理対象が選択されているか確認
If Selection Is Nothing Then
MsgBox "処理するセル範囲を選択してください。", vbExclamation
Exit Sub
End If
' 選択された範囲を変数にセット
Set r = Selection
' 処理開始の確認メッセージ
If MsgBox("選択した " & r.Cells.Count & " 個のセルから、見えない文字を一括削除します。よろしいですか?", vbYesNo) = vbNo Then
Exit Sub
End If
' 処理速度向上のため、画面描画を停止し、イベントを無効化
Application.ScreenUpdating = False
Application.EnableEvents = False
' 選択範囲内の各セルをループ処理
For Each cell In r.Cells
' セルに値がある場合のみ処理を実行
If Not IsEmpty(cell.Value) Then
Dim OriginalValue As String
OriginalValue = cell.Value
' ----------------------------------------------------
' 📝 削除対象の文字リストとコードポイント
' ----------------------------------------------------
' 1. LRM (左から右へのマーク) - Unicode: U+200E
OriginalValue = Replace(OriginalValue, ChrW(&H200E), "")
' 2. 標準的なスペース (半角・全角)
OriginalValue = Replace(OriginalValue, " ", "") ' 半角スペース
OriginalValue = Replace(OriginalValue, " ", "") ' 全角スペース
' 3. NBSP (非改行スペース) - Unicode: U+00A0
OriginalValue = Replace(OriginalValue, ChrW(160), "")
' 4. 異体字セレクタ - Unicode: U+FE0F
OriginalValue = Replace(OriginalValue, ChrW(65039), "")
' 5. 各種制御文字・タブ・改行
OriginalValue = Replace(OriginalValue, vbTab, "") ' 水平タブ
OriginalValue = Replace(OriginalValue, ChrW(11), "") ' 垂直タブ (VT)
OriginalValue = Replace(OriginalValue, vbCr, "") ' 改行コード (CR)
OriginalValue = Replace(OriginalValue, vbLf, "") ' 改行コード (LF)
' ----------------------------------------------------
' クリーンアップ後の値をセルに戻す
cell.Value = OriginalValue
End If
Next cell
' 処理を元に戻す
Application.ScreenUpdating = True
Application.EnableEvents = True
MsgBox "見えない文字の削除が完了しました!", vbInformation
End Sub
















ディスカッション
コメント一覧
まだ、コメントがありません