半角カタカナを全角に変換する
ここでは半角カタカナを全角に変換するコードを2つの紹介します。
1つ目は正規表現とStrConv関数を使う方法で、2つ目は半角カタカナの配列と全角カタカナの配列を使う方法です。
1つ目の方が汎用性はありますが、2つ目の方がコードは分かりやすいです。お好みでどちらかを使ってください。
なお、全角カタカナを半角に変換する方法は「VBAで文字列の全角カタカナを半角に変換する」をご参照ください。
文字コード判別の事前設定
以下のVBAコードは事前に正規表現の参照設定をしておく必要があります。
VBAの画面でツールメニュー→参照設定のダイアログを開き、「Microsoft VBScript Regular Expressions 5.5」にチェックを付けることで正規表現のRegExpクラスが利用できるようになります。
1. 正規表現とStrConv関数を使って半角カタカナを全角に変換する方法
以下のマクロは第一引数の文字列に含まれる半角カタカナを全角に変換し、第二引数で返却します。半角カタカナではない文字は変換しません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
Sub CnvHanKanaToZen(a_sHan, a_sZen) Dim reg As New RegExp '// 正規表現クラスオブジェクト Dim oMatches As MatchCollection '// RegExp.Execute結果 Dim oMatch As Match '// 検索結果オブジェクト Dim i '// ループカウンタ Dim iCount '// 検索一致件数 Dim sConv '// 全角カタカナ変換後文字列 '// 検索条件=連続する半角カタカナ reg.Pattern = "[。-゚]+" '// 検索範囲=文字列の最後まで検索 reg.Global = True '// 引数文字列から半角カタカナを検索 Set oMatches = reg.Execute(a_sHan) '// 検索一致件数を取得 iCount = oMatches.Count '// 変換後文字列に変換前文字列を設定 a_sZen = a_sHan '// 文字列の右側から、連続する半角カタカナの数だけループ For i = iCount - 1 To 0 Step -1 '// 検索に一致した半角カタカナ部分を取得 Set oMatch = oMatches.Item(i) '// 検索に一致した半角カタカナを全角に変換 sConv = StrConv(oMatch.Value, vbWide) '// 検索一致部分のみを全角に変換 a_sZen = Left(a_sZen, oMatch.FirstIndex) & sConv & Mid(a_sZen, oMatch.FirstIndex + oMatch.Length + 1) Next End Sub |
コード説明
概要
正規表現で半角カタカナを検索します。検索は1文字ずつではなく濁音や半濁音や長音を含む連続する半角カタカナはまとめて検索しています。その後、検索で見つかった半角カタカナの数だけループし、見つかった半角カタカナを全角に変換し、元々半角カタカナがあった位置に差し込んでいます。
1行目 | 第一引数に変換前の文字列、第二引数に変換後の文字列が返却されます。 |
2行目 | RegExpクラスのインスタンス変数を作成しています。事前に参照設定をしていることが前提になります。 |
3行目 | 正規表現での検索結果を格納するMatchCollectionクラスの変数です。 |
4行目 | MatchCollectionクラスの変数の各コレクション保持用の検索結果Matchクラスの変数です。 |
5、6、7行目 | 処理中に使うローカル変数です。 |
10行目 | Patternプロパティには正規表現での検索条件を指定します。ここでは正規表現での半角カタカナである[。-゚]+を指定しています。半角カタカナが連続する場合はまとめて検索一致にするために+を指定しています。なお、[。-゚]は文字コードでの[\uFF61-\uFF9F]と書いても同じ意味になります。私は[。-゚]の方がかわいいのでこっちを使ってます。 |
12行目 | Globalプロパティには文字列の検索範囲を指定します。Trueは文字列の最後まで検索します。 |
14行目 | 指定した検索条件で第一引数の文字列から検索します。検索結果はMatchCollectionクラスオブジェクトが返却されます。 |
17行目 | ループ処理用にループカウンタ変数に検索で一致した数を設定しています。 |
20行目 | 第一引数の文字列の内容を初期値として第二引数に設定しています。以降の処理で半角カタカナの部分は全角カタカナに変換されていきます。 |
23行目 | 見つかった検索結果を後ろからループしています。ここは好みの問題ですが、ループで半角から全角に変換されると変換後のa_sZen変数の文字列長が短くなります。その際に、MatchCollectionクラスのoMatches変数に格納されている各検索結果のFirstIndexの値がループ中に全角に変換後のa_sZen変数とは異なってきます。後ろからループを行うとそれを防ぐことが出来るため、後ろからループしています。 |
25行目 | 現ループの検索結果を取得しています。 |
26行目 | 現ループの検索結果の半角カタカナをStrConv関数で全角に変換しています。ここで変換しているのは検索で見つかった半角カタカナの部分だけになります。 |
31行目 | 第二引数の変数の半角カタカナ部分のみを全角カタカナに変換しています。Left関数とRight関数で変換対象外の部分を連結しています。もしこのやり方ではなくReplace関数で一気に文字列全体に対して変換を行うとバグになります。たとえば、「パアガーパアカ バー」という文字列を変換すると「パアガーパアカ バー」が正しいのですが、先頭からループすると「パアカ゛ーパアカ バー」のように3文字目の「ガ」が「カ゛」となってしまいます。原因は正規表現で検索した場合、「パ」「ガーパ」「カ」「バー」の4つが検索されます。これを先頭から文字列全体に対してReplace変換すると、1つ目の「パ」はいいのですが、2つ目が「ガーパ」とパだけが全角になり、次のループで「ガーパ」がヒットせず、変換が正しくおこなえない恐れがあります。 |
利用サンプル
A1からB2セルに入力されている状態で、それらのセルの値の半角カタカナを全角に変換して、A4セル以降に貼り付けるサンプルです。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Sub CnvHanKanaToZenTest() Dim r As Range Dim c As Range Dim s Set r = Range("A1:B2") For Each c In r s = "" Call CnvHanKanaToZen(c.Value, s) c.Offset(3, 0).Value = s Next End Sub |
実行前
実行後(セルの幅は手で変えてます)
処理速度の向上方法
CnvHanKanaToZen関数の内部処理でRegExpクラスをNewしていますが、これを呼び出し元で行うようにするとインスタンスの生成がなくなるため処理速度は向上します。
2. 半角カタカナと全角カタカナの対応表を使って変換する方法
以下のマクロは半角カタカナと全角カタカナには何があるのかを列挙しておいて、変換元の文字列に含まれる半角カタカナを全て全角カタカナに置換する方法です。
半角カタカナの25文字分までが濁音と半濁音の2文字用、といった決め打ちのコーディングで、どちらかと言えば、「動けばOK」みたいなコードです。「美しくない!」と感じる方にはおすすめしません。
正規表現や文字コードを意識する必要がなく、処理はより単純です。使い方は先に紹介した関数と同じですので省略します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
Sub CnvHanKanaToZenEx(a_sHan, a_sZen) Dim sHanList '// 半角文字列挙 Dim sZenList '// 全角文字列挙 Dim sHanAr() '// 半角文字配列 Dim sZenAr() '// 全角文字配列 Dim sHan '// 半角文字 Dim sZen '// 全角文字 Dim i '// ループカウンタ Dim iLen '// 文字数 '// 半角文字と全角文字を列挙(並び順は半角と全角で同じ文字にする) sHanList = "ガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポ。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン" sZenList = "ガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポ。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン" '// 文字数を取得 iLen = Len(sZenList) '// 配列を初期化 ReDim sHanAr(iLen) ReDim sZenAr(iLen) '// 文字数ループし、半角文字と全角文字をそれぞれ配列化 For i = 0 To iLen - 1 '// 半角のガからポまでは記号を含めて2文字ずつ取得 If (i < 25) Then sHanAr(i) = Mid(sHanList, (i * 2) + 1, 2) Else sHanAr(i) = Mid(sHanList, i + 26, 1) End If '// 全角文字を取得 sZenAr(i) = Mid(sZenList, i + 1, 1) Next '// 第二引数に初期値として第一引数を設定 a_sZen = a_sHan '// 全角カタカナの種類数ループ For i = 0 To iLen - 1 '// カタカナの文字を半角から全角に置換 a_sZen = Replace(a_sZen, sHanAr(i), sZenAr(i)) Next End Sub |