VBAでテキストの文字種を判定するツールを作成

blackexcel,VBA,テキスト処理,文字種判定

明けましておめでとうございます。black です。

今回は業務に使うツール作成をしてみました。このツールは複数行にリスト化された文字列に対して、各行ごとに含まれる文字種を判定するものです。
テキストデータに意図しない文字種のデータが含まれていないかを確認したい場合があり、業務効率化と勉強がてらに作ってみました。

目次

  1. ツール作り
  2. 使い方
  3. ソース全文

ツール作り

ツールはインターフェイスの作成が不要な EXCEL の VBA で作ることにします。

まずはざっくりと仕様を以下のように決めました。

  • 1 列目のセルを、1 行目から入力行数分まで処理する
  • 入力文字を「全角文字」「半角英数」「全角半角の混在」の種別ごとにおおまかに分ける
  • 全角ひらがな、全角カタカナ、半角文字、半角カナ、半角記号に分類して抽出する
  • 各列の説明を一行目に挿入する (既に説明行がある場合はスキップ)

*完成イメージ

lab_img2

まずは半角か全角か混合かの判定を作成します。

  1. 'ANSI文字列に変換した文字列を取得  
  2.   set_text_ansi = StrConv(set_text, vbFromUnicode)  
  3.     
  4.   If Len(set_text) = LenB(set_text_ansi) Then  '半角のみ  
  5.       ~  
  6.   ElseIf Len(set_text) * 2 = LenB(set_text_ansi) Then  '全角のみ  
  7.       ~  
  8.   Else  '半角と全角の混合  

ここは文字数とバイト数で比較判定する定番の手法を採用しました。

まずは入力文字が半角である場合を作成。

  1. For l_int_1 = 1 To Len(set_text)  
  2.     my_temp = Mid(set_text, l_int_1, 1)  
  3.     If my_temp Like "[a-z]" Or my_temp Like "[A-Z]" Then  
  4.         han_temp = han_temp & my_temp  
  5.     ElseIf my_temp Like "[。-゚]" Then '半角カナの場合  
  6.         kana_temp = kana_temp & my_temp  
  7.     Else 'アルファベット以外  
  8.         kigo_temp = kigo_temp & my_temp  
  9.     End If  
  10. Next  

入力文字を一文字ずつ抽出しLike演算子で判定、
英字、半角カナであればそれぞれの専用の変数に格納、
それ以外は半角記号と見なすようにしました。
注意点は、半角カナのLike演算子の範囲を[ア-ン]にしてしまうと、
濁点半濁点が無視されてしまうので、そこまで含んだ指定にするところでしょうか。

しかしここで数字を失念していたことが発覚。

  1. ElseIf my_temp Like "#" Then  
  2.     ~  

なのでLIKE演算子で0~9の場合の条件分岐を追加しました。
さらに数字のみの場合や、日付の場合にも処理も分けた方がよさそうだと思い分岐を追加。

  1. If VarType(set_text) = 8 Then '項目が文字型の時  
  2.     ~  
  3. ElseIf VarType(set_text) = 7 Then '項目が日付型の時  
  4.     ~  
  5. Else '項目がそれ以外の型の時(数字とみなす)  
  6.     If InStr(set_text, "."Then '小数を含む数字の場合  
  7.         result = "数字(小数)"  
  8.         Cells(i, int_cell).Value = "<ALL(小数)>"  
  9.     Else  
  10.         result = "数字"  
  11.         Cells(i, int_cell).Value = "<ALL>"  
  12.     End If  
  13. End If  

ここではVarType関数を使いました。戻り値で変数の型などを返してくれるので、文字、日付、数字などを大別するには便利です。

半角の対応は以上です。

次は全角の場合の対応です。

  1. If set_text = StrConv(set_text, vbHiragana) Then '全てひらがな  
  2.     ~  
  3. ElseIf set_text = StrConv(set_text, bvkatakana) Then '全てカタカナ  
  4.     ~  
  5. Else '全角混合  

各入力値を、元の値と、ひらがな変換したものと比較して一致していればひらがなと判定、
カタカナも同様に、という手段を取ろうと思いましたが、これには落とし穴が。。。
テストしてみると、全角の記号や長音が含まれていた時それを識別できないことが判明。
結局はここもLIKE演算子で対応することに。

  1. '検証文字をばらす  
  2. For l_int_1 = 1 To Len(set_text)  
  3.         my_temp = Mid(set_text, l_int_1, 1)  
  4.     If my_temp Like "[あ-ん]" Then '五十音ひらがな  
  5.         hira_temp = hira_temp & my_temp  
  6.     ElseIf my_temp Like "[ア-ン]" Then  '五十音カタカナ  
  7.         zenkana_temp = zenkana_temp & my_temp  
  8.     ElseIf my_temp Like "ー" Then '長音対応  
  9.         hira_temp = hira_temp & my_temp  
  10.         zenkana_temp = zenkana_temp & my_temp  
  11.     Else 'それ以外(全角記号など)  
  12.         str_temp = my_temp  
  13.     End If  
  14. Next  

やることは半角の時と同様ですが、長音のみはひらがなとカタカナどちらにも属するようにしています。

これで全角の場合も完成です。

全角と半角が混合している場合は上記を組み合わせて対応。
さて、これで基礎は完成しました。

次は空白文字の対応です。
ここまでの対応で、全角、半角それぞれの空白文字も記号として振り分けはされるのですが、
ぱっと見た目には分かりません。
そこで、空白文字判定用のカラムを追加し、空白文字あれば"○"が入るように対応。

あとは結果表示の調整です。
分類したデータが続き文字でない場合に、わかりやすいように間にカンマを挟むモジュールを追加します。

  1. Function add_comma(temp As VariantAs Variant  
  2.     If temp <> "" And Right(temp, 1) <> "," Then  
  3.         temp = temp & ","  
  4.     End If  
  5.     add_comma = temp  
  6. End Function  

これを文字判定の都度実行させます。

それと、一行目に各列の説明を挿入するコードも入れておきます。

  1. '各列の説明行の追加  
  2. chk_str_header = "検証文字列"  
  3. If Cells(1, 1) <> chk_str_header Then  
  4.     Application.CutCopyMode = False  
  5.     Range("1:1").Insert  
  6.     With Cells(1, 1)  
  7.         .Value = chk_str_header  
  8.         .Interior.Color = RGB(255, 255, 0)  
  9.     End With  
  10.     With Cells(1, hantei_cell)  
  11.         .Value = "型判定"  
  12.         .Interior.Color = RGB(0, 255, 255)  
  13.     End With  
  14.     Cells(1, zenkaku_cell).Value = "他全角"  
  15.     Cells(1, zenhira_cell).Value = "ひらがな"  
  16.     Cells(1, zenkana_cell).Value = "全角カナ"  
  17.     Cells(1, hankaku_cell).Value = "半角文字"  
  18.     Cells(1, hankana_cell).Value = "半角カナ"  
  19.     Cells(1, kigo_cell).Value = "半角記号"  
  20.     Cells(1, int_cell).Value = "数字"  
  21.     Cells(1, space_cell).Value = "全角空白"  
  22.     With Range("A1:J1")  
  23.         .Font.Bold = True  
  24.         .Borders.LineStyle = xlContinuous  
  25.         .HorizontalAlignment = xlCenter  
  26.     End With  
  27. End If  

これで完成です。

使い方

Excel を開き、一番左の列に判別させたい文字列を入力します。

lab_img3

Visual Basic Editor に以下の ソース全文 を貼り付けて実行します。

実行した結果は以下のようになります。

lab_img1

カンマが含まれていた場合に見づらかったり、VBAなので処理速度がお察しの通りだったりと、
まだまだ問題もありますが、とりあえずは要求を満たすものができました。

専門職ではないので作りの甘い部分はありますが、
同じようなものが欲しい人の参考になればと思います。

ソース全文

  1. Sub text_judge()  
  2.     Dim chk_str_header, my_temp, str_temp, hira_temp, zenkana_temp, num_temp, han_temp, kana_temp, kigo_temp As String  
  3.     Dim i, max_row, zenkaku_cell, zenhira_cell, zenkana_cell, hankaku_cell, hankana_cell, kigo_cell, int_cell, space_cell As Integer  
  4.     hantei_cell = 2     '型判定結果のcolumn位置  
  5.     zenkaku_cell = 3    '全角文字のcolumn位置  
  6.     zenhira_cell = 4    '全角ひらがなのcolumn位置  
  7.     zenkana_cell = 5    '全角カタカナのcolumn位置  
  8.     hankaku_cell = 6    '半角文字のcolumn位置  
  9.     hankana_cell = 7    '半角カナのcolumn位置  
  10.     kigo_cell = 8       '半角記号のcolumn位置  
  11.     int_cell = 9        '数字のcolumn位置  
  12.     space_cell = 10     '全角空白のcolumn位置  
  13.       
  14.     '各列の説明行の追加  
  15.     chk_str_header = "検証文字列"  
  16.     If Cells(1, 1) <> chk_str_header Then  
  17.         Application.CutCopyMode = False  
  18.         Range("1:1").Insert  
  19.         With Cells(1, 1)  
  20.             .Value = chk_str_header  
  21.             .Interior.Color = RGB(255, 255, 0)  
  22.         End With  
  23.         With Cells(1, hantei_cell)  
  24.             .Value = "型判定"  
  25.             .Interior.Color = RGB(0, 255, 255)  
  26.         End With  
  27.         Cells(1, zenkaku_cell).Value = "他全角"  
  28.         Cells(1, zenhira_cell).Value = "ひらがな"  
  29.         Cells(1, zenkana_cell).Value = "全角カナ"  
  30.         Cells(1, hankaku_cell).Value = "半角文字"  
  31.         Cells(1, hankana_cell).Value = "半角カナ"  
  32.         Cells(1, kigo_cell).Value = "半角記号"  
  33.         Cells(1, int_cell).Value = "数字"  
  34.         Cells(1, space_cell).Value = "全角空白"  
  35.         With Range("A1:J1")  
  36.             .Font.Bold = True  
  37.             .Borders.LineStyle = xlContinuous  
  38.             .HorizontalAlignment = xlCenter  
  39.         End With  
  40.     End If  
  41.       
  42.     max_row = ActiveSheet.UsedRange.Find("*", , xlFormulas, , xlByRows, xlPrevious).Row  
  43.     i = 2  
  44.       
  45.     For i = 2 To max_row   'A列の最後まで繰り返し  
  46.         set_text = Cells(i, 1)  
  47.            
  48.         '値がない場合はスキップ  
  49.         If Len(set_text) = 0 Then  
  50.             GoTo Continue  
  51.         End If  
  52.            
  53.         'ANSI文字列に変換した文字列を取得  
  54.         set_text_ansi = StrConv(set_text, vbFromUnicode)  
  55.           
  56.         'まず全角のみ、半角のみか判定  
  57.           
  58.         If Len(set_text) = LenB(set_text_ansi) Then  
  59.         '半角だけの時  
  60.             If VarType(set_text) = 8 Then  
  61.                 result = "半角英数"  
  62.                   
  63.                     '変数初期化  
  64.                     han_temp = ""  
  65.                     kana_temp = ""  
  66.                     kigo_temp = ""  
  67.                     num_temp = ""  
  68.                       
  69.                     If set_text Like "* *" Then '半角スペース検索  
  70.                         Cells(i, space_cell).Value = "○"  
  71.                     End If  
  72.                       
  73.                     '検証文字をばらす  
  74.                     For l_int_1 = 1 To Len(set_text)  
  75.                         my_temp = Mid(set_text, l_int_1, 1)  
  76.                         If my_temp Like "[a-z]" Or my_temp Like "[A-Z]" Then '半角英字の場合  
  77.                             han_temp = han_temp & my_temp  
  78.                             num_temp = add_comma(num_temp)  
  79.                             kana_temp = add_comma(kana_temp)  
  80.                             kigo_temp = add_comma(kigo_temp)  
  81.                               
  82.                         ElseIf my_temp Like "[。-゚]" Then        '半角カナの場合  
  83.                             kana_temp = kana_temp & my_temp  
  84.                             num_temp = add_comma(num_temp)  
  85.                             han_temp = add_comma(han_temp)  
  86.                             kigo_temp = add_comma(kigo_temp)  
  87.                           
  88.                         ElseIf my_temp Like "#" Then    '数字の場合  
  89.                             num_temp = num_temp & my_temp  
  90.                             han_temp = add_comma(han_temp)  
  91.                             kana_temp = add_comma(kana_temp)  
  92.                             kigo_temp = add_comma(kigo_temp)  
  93.                               
  94.                         Else        'アルファベット以外  
  95.                             kigo_temp = kigo_temp & my_temp  
  96.                             han_temp = add_comma(han_temp)  
  97.                             kana_temp = add_comma(kana_temp)  
  98.                             num_temp = add_comma(num_temp)  
  99.                           
  100.                         End If  
  101.                     Next  
  102.                                                                                          
  103.                     Cells(i, hankaku_cell).Value = han_temp  
  104.                     Cells(i, hankana_cell).Value = kana_temp  
  105.                     Cells(i, kigo_cell).Value = kigo_temp  
  106.                     Cells(i, int_cell).Value = num_temp  
  107.   
  108.                   
  109.             ElseIf VarType(set_text) = 7 Then   '項目が日付の時  
  110.                 result = "日付"  
  111.                   
  112.             Else    '数字のみの場合、小数と整数に分ける  
  113.                 If InStr(set_text, "."Then  
  114.                     result = "数字(小数)"  
  115.                     Cells(i, int_cell).Value = "<ALL(小数)>"  
  116.                 Else  
  117.                     result = "数字"  
  118.                     Cells(i, int_cell).Value = "<ALL>"  
  119.                 End If  
  120.             End If  
  121.               
  122.         ElseIf Len(set_text) * 2 = LenB(set_text_ansi) Then '全角  
  123.           
  124.             my_temp = ""  
  125.             str_temp = ""  
  126.             hira_temp = ""  
  127.             zenkana_temp = ""  
  128.               
  129.             '検証文字をばらす  
  130.             For l_int_1 = 1 To Len(set_text)  
  131.                 my_temp = Mid(set_text, l_int_1, 1)  
  132.                     'ひらがな、カタカナ、長音、その他で処理を分ける  
  133.                     If my_temp Like "[あ-ん]" Then  
  134.                         hira_temp = hira_temp & my_temp  
  135.                         zenkana_temp = add_comma(zenkana_temp)  
  136.                         str_temp = add_comma(str_temp)  
  137.                     ElseIf my_temp Like "[ア-ン]" Then  
  138.                         zenkana_temp = zenkana_temp & my_temp  
  139.                         hira_temp = add_comma(hira_temp)  
  140.                         str_temp = add_comma(str_temp)  
  141.                     ElseIf my_temp Like "ー" Then  
  142.                         hira_temp = hira_temp & my_temp  
  143.                         zenkana_temp = zenkana_temp & my_temp  
  144.                         str_temp = add_comma(str_temp)  
  145.                     Else  
  146.                         str_temp = str_temp & my_temp  
  147.                         hira_temp = add_comma(hira_temp)  
  148.                         zenkana_temp = add_comma(zenkana_temp)  
  149.                     End If  
  150.             Next  
  151.                                              
  152.             If set_text Like "* *" Then    '全角スペース検索  
  153.                 Cells(i, space_cell).Value = "○"  
  154.             End If  
  155.               
  156.             Cells(i, zenkaku_cell).Value = str_temp  
  157.             Cells(i, zenhira_cell).Value = hira_temp  
  158.             Cells(i, zenkana_cell).Value = zenkana_temp  
  159.             result = "全角文字"  
  160.               
  161.         Else  
  162.             '半角全角混合の処理  
  163.               
  164.             '初期化  
  165.             my_temp = ""  
  166.             str_temp = ""  
  167.             hira_temp = ""  
  168.             zenkana_temp = ""  
  169.             han_temp = ""  
  170.             kana_temp = ""  
  171.             kigo_temp = ""  
  172.             num_temp = ""  
  173.               
  174.             '検証文字をばらす  
  175.             For l_int_1 = 1 To Len(set_text)  
  176.                 my_temp = Mid(set_text, l_int_1, 1)  
  177.                 If LenB(StrConv(my_temp, vbFromUnicode)) = 2 Then   '全角の場合  
  178.                   
  179.                     If my_temp Like "[あ-ん]" Then  
  180.                         hira_temp = hira_temp & my_temp  
  181.                         zenkana_temp = add_comma(zenkana_temp)  
  182.                         str_temp = add_comma(str_temp)  
  183.                     ElseIf my_temp Like "[ア-ン]" Then  
  184.                         zenkana_temp = zenkana_temp & my_temp  
  185.                         hira_temp = add_comma(hira_temp)  
  186.                         str_temp = add_comma(str_temp)  
  187.                     ElseIf my_temp Like "ー" Then  
  188.                         hira_temp = hira_temp & my_temp  
  189.                         zenkana_temp = zenkana_temp & my_temp  
  190.                         str_temp = add_comma(str_temp)  
  191.                     Else  
  192.                         str_temp = str_temp & my_temp  
  193.                         hira_temp = add_comma(hira_temp)  
  194.                         zenkana_temp = add_comma(zenkana_temp)  
  195.                     End If  
  196.                               
  197.                       
  198.                     han_temp = add_comma(han_temp)  
  199.                     han_temp = add_comma(han_temp)  
  200.                     kana_temp = add_comma(kana_temp)  
  201.                     kigo_temp = add_comma(kigo_temp)  
  202.                 Else        '半角の場合  
  203.                     If my_temp Like "[a-z]" Or my_temp Like "[A-Z]" Then  
  204.                         han_temp = han_temp & my_temp  
  205.                         str_temp = add_comma(str_temp)  
  206.                         kana_temp = add_comma(kana_temp)  
  207.                         kigo_temp = add_comma(kigo_temp)  
  208.                         num_temp = add_comma(num_temp)  
  209.                       
  210.                     ElseIf my_temp Like "[。-゚]" Then        '半角カナの場合  
  211.                         kana_temp = kana_temp & my_temp  
  212.                         han_temp = add_comma(han_temp)  
  213.                         kigo_temp = add_comma(kigo_temp)  
  214.                         num_temp = add_comma(num_temp)  
  215.                       
  216.                     ElseIf my_temp Like "*#*" Then          '数字の場合  
  217.                         han_temp = add_comma(han_temp)  
  218.                         kana_temp = add_comma(kana_temp)  
  219.                         kigo_temp = add_comma(kigo_temp)  
  220.                         num_temp = num_temp & my_temp  
  221.                           
  222.                     Else        'アルファベット以外  
  223.                         kigo_temp = kigo_temp & my_temp  
  224.                         han_temp = add_comma(han_temp)  
  225.                         kana_temp = add_comma(kana_temp)  
  226.                         num_temp = add_comma(num_temp)  
  227.                     End If  
  228.                                                                                          
  229.                     str_temp = add_comma(str_temp)  
  230.                     hira_temp = add_comma(hira_temp)  
  231.                     zenkana_temp = add_comma(zenkana_temp)  
  232.                 End If  
  233.             Next  
  234.               
  235.             If set_text Like "* *" Or set_text Like "* *" Then  
  236.                 Cells(i, space_cell).Value = "○"  
  237.             End If  
  238.               
  239.             Cells(i, zenkaku_cell).Value = str_temp  
  240.             Cells(i, zenhira_cell).Value = hira_temp  
  241.             Cells(i, zenkana_cell).Value = zenkana_temp  
  242.             Cells(i, hankaku_cell).Value = han_temp  
  243.             Cells(i, hankana_cell).Value = kana_temp  
  244.             Cells(i, kigo_cell).Value = kigo_temp  
  245.             Cells(i, int_cell).Value = num_temp  
  246.             result = "混在"  
  247.               
  248.         End If  
  249.           
  250.         Cells(i, hantei_cell) = result  
  251.   
  252. Continue:  
  253.     Next  
  254.   
  255. End Sub  
  256.   
  257. '分類分けで、続いている文字でなければカンマを挟むためのモジュール  
  258. Function add_comma(temp As VariantAs Variant  
  259.       
  260.     If temp <> "" And Right(temp, 1) <> "," Then  
  261.         temp = temp & ","  
  262.     End If  
  263.   
  264.     add_comma = temp  
  265. End Function  

blackexcel,VBA,テキスト処理,文字種判定

Posted by black