【VBA】1桁の数字は全角文字に、2桁以上の数字は半角文字にする【Excel版】

1桁の数字は全角文字で表記し,2桁以上の数字は半角文字で表記するというローカルルールをご存じでしょうか。Pフォントが発明されて久しい現在、こんな旧時代の遺物は絶滅してほしいと切に願うところでありますが、いまだにこの謎ルールは健在のようです。

思うに、この労働生産性を損なう謎ルールは、印刷することを前提にした文化において続いているようです(個人の感想です)。

印刷するなんて紙の無駄、基本ディスプレイでお仕事するのが当たり前であれば、1桁の数字を全角にするアホらしさに気が付くのですが(なぜなら校正ツールがチェックしたときに警告してきますよね?”英数字が半角に統一されていません”と。)、印刷してなんぼの世界では致し方ないのかもしれません。

という訳で本日は、1桁の数字は全角に、連続する数字は半角に直してくれるVBAを紹介します。

免責事項

本ブログで公開しているコードは、十分にテストしたものでありますが、エラーやバグがあったとしても対応しかねます(こっそりメールで教えてくださると喜びます)。本ブログで公開しているコードを実行し、損害を被ったとしても当方では責任は負えません。また、コードをコピーして個人で使う分にはかまいませんが、著作権は放棄していません。

コード

Option Explicit
'1桁数字を全角に、2桁以上の数字を半角にする
Public Sub 全角半角変換()
    
    Dim c As Variant
    Dim Reg As Object
    
    '処理開始
    Call StartProgram(Reg)
    
    '各セルに対して処理を実施
    For Each c In Selection
        '一つ一つのセルに対して全角半角変換を実行
        Call Width2HalfConversion(c, Reg)
    Next c

    '処理終了
    Call EndProgram(Reg)
End Sub
'処理開始
Private Sub StartProgram(ByRef Reg As Object)
    Set Reg = CreateObject("VBScript.RegExp")
End Sub

'一つ一つのセルに対して全角半角変換を実行
Private Sub Width2HalfConversion(ByRef c As Variant, ByRef Reg As Object)
    Dim oMatches As Object
    Dim oMatch As Object
    Dim lCount As Long
    Dim ii As Long
    Dim stAfter As String
    Dim stConv As String
    
    'パラメータ設定
    Reg.Global = True   '検索範囲は文字列の最後まで
    Reg.IgnoreCase = True   '大文字小文字は区別しない
    
    '連続した数字(13桁まで対応。間にカンマやピリオドを含む)
    Reg.Pattern = "[0-90-9,,..]{2,13}"
    
    Set oMatches = Reg.Execute(c.Value)
    lCount = oMatches.Count
    stAfter = c.Value
    
    For ii = 0 To lCount - 1
        Set oMatch = oMatches.Item(ii)
        stConv = StrConv(oMatch.Value, vbNarrow)
        
        stAfter = Replace(stAfter, oMatch.Value, stConv)
    Next ii
    
    '単体の数字
    '正規表現を使わず、1文字1文字チェックしていく
    'すでにここまでに連続する数値は半角になっている前提
    Dim Buf As String, flg As Boolean, lLen As Long

    lLen = Len(stAfter) '文字列の長さを把握
    flg = False         '数値スイッチはオフ
    For ii = 1 To lLen
        Buf = Mid(stAfter, ii, 1)   '1文字分をBufに格納
        If IsNumeric(Buf) And Not flg Then  '1文字が数値であり、直前の文字の数値スイッチがオフなら
            If Not IsNumeric(Mid(stAfter, ii + 1, 1)) And "." <> Mid(stAfter, ii + 1, 1) And "," <> Mid(stAfter, ii + 1, 1) Then
                '直後の1文字が、数値でもピリオドでもカンマでもないなら
                Mid(stAfter, ii, 1) = StrConv(Buf, vbWide)  '全角数字に変換
            End If
        End If
        flg = IsNumeric(Buf)    '数値スイッチに現在の文字の判定を格納
    Next ii
    
    c.Value = stAfter
End Sub

'処理終了
Private Sub EndProgram(ByRef Reg As Object)
    Set Reg = Nothing
End Sub

なんのへんてつもない、標準モジュールのコードです。

コピペして標準モジュールに貼り付けてください。

コードの解説

最初に正規表現で連続する数字を半角に変換しています。

連続する数字の中にはピリオドやカンマが含まれる場合も想定しています。

次に、単体の数字を全角に変換しています。

ExcelのVBAは後読みに(<=)には対応していないということだったので、単体の数字を探すのは1文字ずつチェックすることにしました。

使い方

こういうExcelがあったとします。

このセルの中に入っている数字は全部半角です。

セルを三つとも選択します。

セルを選択したところ

この状態で開発→マクロ→全角半角変換→実行

実行後

実行後結果

半角が全角になったのが分かりますでしょうか?

メイリオフォントだと分かりづらいですね。

分かりやすいようにMSゴシックにして、比較したのが下記です。

これにより、何が良いかというと、せっかく全部の英数字を半角に統一して作成した書類を提出後、決裁者から「これ、1桁は全角にして」というアホみたいな指示をもらって著しくやる気をなくす人を減らす効果があります(経験談)。

なお、このVBAはセルの中の値を置換する都合上、セルの中の一部の文字列の色を変えたり、太字にしたりしてあった場合、その編集は失われます。悪しからずご了承ください。

標準モジュールは、用が済んだら解放してください。くれぐれも提出する書類の中に(ブックの中に)残しておかないようにしてください(無用の混乱を招くので)。

まとめ

私が前職をやめた理由の一つがこれです(本当)。

1桁の数字を全角にする文化が嫌いです。なぜなら労働生産性が下がるから。

印刷技術が発達していなかった当時は、等幅フォントの場合、1桁の数字は全角、2桁の数字は半角にすれば、ちょうどよく印刷幅に収まったのでしょうね。

しかし、Pフォント(非等幅フォント、プロポーショナルフォント)を使ったが最後、この変なルールを守ったところで印刷したときのレイアウトは崩れてしまう訳で、いつまでもこのルールに拘泥する必要はないと個人的には思っています。

私のように、提出した後で修正するのが、「中身ではなく形の問題?!それって本質なの!?」とがっかりする人が一人でも減りますように。

何かのお役に立てば幸いです。

ここまでお読みくださりありがとうございました。