Excel シートのテキストデータの全角・半角文字を変換・置換する手順と、それを自動化するマクロを検討します。
全角文字と半角文字
日本語の文字コードには歴史的経緯のためか、英数字・記号・カタカナの文字に全角と半角の2種類の文字種があって区別されます。
説明文などのテキストデータで全角・半角が統一されていないのは見苦しいだけでなく、文書の信頼性が問われます。
またデータとしても、システムによっては両者を区別しなかったり、どちらかに自動変換(正規化)されることもあるのですが、基本的に、全角と半角が混在していると何かとトラブルの元になりやすいです。
半角カタカナは最近使われなくはなってきていますが、かつては印字スペースの節約のためにも使われ、今でもレシートや通帳の印字でよく使われています。
Excelで半角カタカナを使う理由は無いはずなのですが、古いシステムとの連携データ作成などでまだ需要は残っているようです。
手作業で全角・半角の文字置換をするには
Word には全角・半角を置換するコマンドがあるようですが、Excelでは提供されていません。
その代り、文字種を変換する関数が用意されていて、数式で使用できます。
ASC()
全角→半角変換JIS()
半角→全角変換
ASC()/JIS()は全ての英数字・記号・カタカナを変換し、それ以外の文字には影響しませんので、文章テキストをそのまま処理できます。
ただ、たとえばテキストデータ中にある英数字を半角に統一するために ASC() を使うと、文章中のカタカナまで半角カタカナになってしまいます。説明文のような自然文が主体のテキストデータでは、もう少し細やかな制御が欲しいところです。
また、関数を使った変換には作業用のセルをいったん用意し、数式データをやり取りすることになります。作業的に難しい事ではないのですが、ちょっと億劫です。
ここでは、少し無理やりですが、キー操作だけでASC()/JIS()関数処理を行う手順を考えます。
ある列にあるテキストを半角に変換したいとします。
【手順例】
- 対象データ範囲を選択します
- 作業用のセル(列)を挿入します
- キー操作:
Ctrl
+Shift
++
⇒Enter
- キー操作:
- 作業用セルに文字種を変換する数式を入力します
- キー操作(半角):
=asc(
⇒→
⇒Ctrl
+Enter
- キー操作(全角):
=jis(
⇒→
⇒Ctrl
+Enter
- キー操作(半角):
変換文字をコピーし、元データのセルに値として貼り付けます
- キー操作:
Ctrl
+C
⇒Shift
+→
⇒Ctrl
+Alt
+V
⇒V
⇒Enter
- キー操作:
作業用セル(列)を選択し削除します
- キー操作:
Shift
+←
⇒Ctrl
+-
- キー操作:
慣れるにはちょっと無理があります。素直に作業用の別シートでコピー&ペーストしながら加工したほうが早そうです。
全角・半角文字を変換するマクロ
セルのテキストで全角・半角を変換するマクロを作成してみました。
変換したいテキストのセルを選択して、本マクロを実行するとセル内のテキストの文字種が変換されます。
変換対象としたい文字種をある程度選べるように、変換パターンによって複数のマクロに分けました。
たとえば、「文字種変換_半角→全角」マクロはカタカナ、英数字、記号等をすべて半角文字にしますが、「文字種変換_全角英数→半角英数」マクロは英数字のみ半角に変換します。
適宜必要なマクロを選んで実行してください。
使用上の注意点として、本マクロは選択範囲のセルの全ての文字を変換処理しますが、元に戻すことができません。
大切なデータを安全に扱うためには、いったん別シートにコピーしてから処理するか、ファイルをバックアップしておくなど、慎重に操作されることをお勧めします。
Option Explicit Sub 文字種変換_全角→半角() replaceRangeText Selection.Cells, proc:="strConvNarrow" End Sub Sub 文字種変換_半角→全角() replaceRangeText Selection.Cells, proc:="strConvWide" End Sub Sub 文字種変換_全角英数→半角英数() replaceRangeText Selection.Cells, proc:="replaceRegex", target:="[0-9A-Za-z_]+", func:="strConvNarrow" End Sub Sub 文字種変換_半角英数→全角英数() replaceRangeText Selection.Cells, proc:="replaceRegex", target:="\w+", func:="strConvWide" End Sub Sub 文字種変換_全角カナ→半角カナ() replaceRangeText Selection.Cells, proc:="replaceRegex", target:="[。「」ーァ-ヶ]+", func:="strConvNarrow" End Sub Sub 文字種変換_半角カナ→全角カナ() replaceRangeText Selection.Cells, proc:="replaceRegex", target:="[。「-゚]+", func:="strConvWide" End Sub Sub 文字種変換_全角記号→半角記号() replaceRangeText Selection.Cells, proc:="replaceRegex", _ target:="[\uFF01-\uFF0F\uFF1A-\uFF20\uFF3B-\uFF40\uFF5B-\uFF5E\u201D\u2019\uFFE5\u2018]+", _ func:="strConvNarrow" End Sub Sub 文字種変換_半角記号→全角記号() replaceRangeText Selection.Cells, proc:="replaceRegex", _ target:="[\u0021-\u002F\u003A-\u0040\u005B-\u0060\u007B-\u007E]+", _ func:="strConvWide" End Sub Sub replaceRangeText(rng As Range, proc As String, Optional target As Variant, Optional func As Variant) Application.ScreenUpdating = False On Error GoTo finish Dim txtArea As Range Dim txtCol As Range Dim text As String If WorksheetFunction.CountA(rng) = 0 Then Beep ElseIf rng.Cells.Count = 1 Then If VarType(rng.Value) = vbString Then rng.Value = Application.Run(proc, rng.Value, target, func) End If Else For Each txtArea In rng.SpecialCells(xlCellTypeConstants, xlTextValues).Areas For Each txtCol In txtArea.Columns text = joinColumnValues(txtCol, vbNullChar) text = Application.Run(proc, text, target, func) txtCol.Value = splitTranspose(text, vbNullChar) Next Next rng.Select End If finish: If Err.Number <> 0 Then MsgBox Err.Description Application.ScreenUpdating = True End Sub Private Function joinColumnValues(col As Range, delim As String) As String Dim vals As Variant Dim arr() As String Dim i As Integer If col.Cells.Count = 1 Then joinColumnValues = col.Value Else vals = col.Value ReDim arr(1 To UBound(vals, 1)) For i = 1 To UBound(arr) arr(i) = vals(i, 1) Next joinColumnValues = Join(arr, delim) End If End Function Private Function splitTranspose(text As String, delim As String) As Variant Dim vals As Variant Dim arr() As String Dim i As Integer arr = Split(text, delim) ReDim vals(1 To UBound(arr) + 1, 1 To 1) For i = 0 To UBound(arr) vals(i + 1, 1) = arr(i) Next splitTranspose = vals End Function Private Function strConvNarrow(text As String) As String strConvNarrow = StrConv(text, vbNarrow) End Function Private Function strConvWide(text As String) As String strConvWide = StrConv(text, vbWide) End Function Private Function replaceRegex(text As String, targetPattern As String, replaceFunc As String) As String Dim regex As Object Dim matches As Object Set regex = CreateObject("VBScript.RegExp") regex.Global = True regex.pattern = "(" & targetPattern & "|^)(.|\r|\n)*?(?=" & targetPattern & "|$)" regex.MultiLine = False Set matches = regex.Execute(text) If matches.Count = 0 Then replaceRegex = text Exit Function End If Dim fragment As String Dim match As String Dim arr() As String ReDim arr(matches.Count - 1) Dim i As Integer For i = 0 To matches.Count - 1 fragment = matches(i).Value match = matches(i).SubMatches(0) arr(i) = Replace(fragment, match, Application.Run(replaceFunc, match), 1, 1) Next replaceRegex = Join(arr, "") End Function
【使い方】
- 上記 VBA プログラムを標準モジュールにコピー&ペーストします
- 文字種置換したいセル範囲を選択します
- 希望する文字種置換を行うマクロを実行します
- セル内容のテキストが対象となる文字が置換されています
【注意】 本マクロによる処理結果は、「元に戻す」(Undo)ことが出来ません。
まとめ
Excel のテキスト置換コマンドに全角・半角の文字種を変換する機能がなく、ASC()/JIS()関数を利用した手順を考えましたがテキスト置換の代わりとしては手順につらいところがあります。
一方、マクロでは、セル範囲指定による一括置換ができるうえ、ASC()/JIS()関数よりきめの細かい文字種処理を提供も可能になりました。
本記事の内容は Windows 10 の Excel 2013 で確認しました。