m-eye blog

ノンプログラマによるVBAとPythonの学習記録

VBAでカタカナをひらがなに変換するマクロ - 不渡届その4

f:id:m-eye:20181019094618p:plain

 

はじめに

  • ファイルはYahoo! ボックスに公開しているので、ここからダウンロードして自由につかってください。
  • このファイルには「不渡届その1・その2・その3」で作成したマクロを含みます。
  • 動作確認は、Offie 365 Solo + Windows 10でおこなっています。
  • 動作は無保証です。

 

カタカナをひらがなに変換したい

不渡届では、法人名または個人名の「フリガナ」を書くと、「索引(かしら字)」というものを書かなければなりません。

「ハテナブログ」というフリガナに対して「は」というひらがな1文字を書くということです。

「ハテナブログ」 → 「は」

それをいちいち手書きすると面倒くさいので、VBAで自動的に表示してくれ、というリクエストがあり、開発することになりました。

 

変換するためのルール

  • 法人名または個人名のフリガナの頭文字1文字をひらがなに変換する、というルール
  • 濁音(「」など)、半濁音(「」など)は清音(「」など)に変換する、というルール
  • 「ヴ」を「う」に変換するというルール

この3つのルールにもとづいて、フリガナをひらがな1文字に変換します。

 

カタカナとひらがなについて研究する

カタカナをひらがなに変換するには、なんらかの関連性が必要ですが、パソコンであつかう文字にはそれぞれ文字コードがありますので、それを確認します。

 

文字コードを確認する2つの方法

いきなりですが、Excelには文字コードを確認する方法は2つあります。

1つはむかしながらの方法であるCODE関数をつかう方法。これはWorksheetFunctionオブジェクトにふくまれていないので、VBAでつかうときはEvaluateメソッドとともに実行する必要があります。

もう1つはExcel2013からの方法であるUNICODE関数をつかう方法です。こちらはWorksheetFunctionオブジェクトにふくまれますので、VBAでつかうときはWorksheetFunctionオブジェクトとともに実行します。

CODE関数も、UNICODE関数も、文字列の1文字目の文字コードを取得します。

ここでは、UNICODE関数をつかう方法で説明していきます。

ですので、Excel2013以降でないと、実行できません。

Excel2010で試したいときは、CODE関数をつかって試してみてくださいね。

 

文字と文字コードを相互に変換する

UNICODE関数をつかうと、UNICODE("ア")=12450となって、文字を文字コードに変換できます。

文字を文字コードに変換して、カタカナとひらがなの関連性について研究するとしても、最終的に文字コードから文字に変換できなければなりません。

そのときは、文字コードを文字に変換するUNICHAR関数をつかいます。

UNICHAR関数をつかうと、UNICHAR(12450)="ア"となって、文字コードを文字に変換することができます。

ちなみに、Excel2010ではUNICHAR関数ではなく、CHAR関数をつかいます。

 

カタカナとひらがなのそれぞれの文字の文字コードをしらべてみる

UNICODE関数をつかって文字コードをしらべてみます。

f:id:m-eye:20181027130316p:plain

上の図は、ぜんぶのカタカナとひらがなの文字コードをExcel上で一覧表にしたものです。

カタカナについては

列名 内容 列名 内容
A列 カタカナの清音の文字 B列 その文字コード
C列 カタカナの濁音の文字 D列 その文字コード
E列 カタカナの半濁音の文字 F列 その文字コード

ひらがなについては

列名 内容 列名 内容
H列 ひらがなの清音の文字 I列 その文字コード
J列 ひらがなの濁音の文字 K列 その文字コード
L列 ひらがなの半濁音の文字 M列 その文字コード

カタカナとひらがなの関連性については

列名 内容
O列 カタカナの清音の文字コードの数値から、ひらがなの清音の文字コードの数値を引いた差の数値

 

一覧表からわかったこと

  • カタカナの清音の文字コードの数値から、ひらがなの清音の文字コードの数値を引いた差の数値は96である
  • 濁音の文字コードは清音の文字コードに1をたしたものである
  • 半濁音の文字コードは濁音の文字コードに1をたしたものである
  • 半濁音の文字コードは清音の文字コードに2をたしたものである

以上の性質を利用して、マクロを作成します。

 

変換するためのルールを具体化してみる

  1. カタカナの文字列からUNICODE関数でその1文字目の文字コードを取得して、その文字コードから96をひいた数値をUNICHAR関数の引数にして、ひらがなの1文字を取得する
  2. カタカナの濁音・半濁音は清音にしてからひらがなに変換する
  3. カタカナの「ヴ」は「ゔ」にできないで、「う」に変換する

この3つを具体的にみていきましょう。

 

カタカナをひらがなに変換する

これが「変換の大原則」です。

セル「J7」に入力されたフリガナをもとに、セル「B8」にひらがなの頭文字を入力します。

 

ソースコード

Private Sub Worksheet_Change(ByVal Target As Range)
    Select Case True
        Case Not Intersect(Target, Range("J7")) Is Nothing
            Dim Katakana As Range
            Dim Hiragana As Range
            
            Set Katakana = Range("J7")
            Set Hiragana = Range("B8")
    
            If Len(Katakana.Value) = 0 Then
                Hiragana.Value = ""
            
            Else
                Dim myCode As Long
                myCode = _
                WorksheetFunction.Unicode(Katakana.Value)
                Hiragana.Value = F_NormalConverter(myCode)
                
            End If
            
            Set Hiragana = Nothing
            Set Katakana = Nothing
    End Select
End Sub

Private Function F_NormalConverter(ByVal myCode As Long) _
    As String
    
    F_NormalConverter = _
        WorksheetFunction.Unichar(myCode - 96)
End Function

 

解説

Worksheet_Changeサブルーチンをつかって、フリガナを入力するセル「J7」の値が変化したときに、セル「B8」の値を変化させます。

セル「J7」にはフリガナを入力するので、オブジェクト変数Katakanaにセル「J7」を代入します。

セル「B8」にはひらがなの頭文字を代入するので、オブジェクト変数Hiraganaにセル「B8]を代入します。

なれてないうちは、「文字列型変数」にセル「J7」・「B8」の値を代入しがちですが、VBAになれてきたら、ぜひとも「オブジェクト型変数」を活用しましょう。

オブジェクト型変数のほうが、プロパティとメソッドをつかうことができるので、自由がきいて使いやすいです。

Katakanaの値をDELETEキーで消去したときは、Hiraganaの値を消去します。

そうでないときは、フリガナが入力されている状態なので、Katakanaセルの値をUNICODE関数で文字コードに変換して、その値を変数myCodeに代入します。

myCodeはカタカナの文字コードの値なので、その値から96を引くと、ひらがなの文字コードの値になります。その値をF_NormalConverterファンクション・プロシージャに代入しします。

F_NormalConverterファンクション・プロシージャでは、myCode - 96の値をUNICHAR関数の引数にして、ひらがなの文字列を取得します。取得したその値はF_NormalConverterファンクション・プロシージャの返り値になりますので、それをHiraganaセルに代入します。

 

カタカナの濁音・半濁音は清音にしてからひらがなに変換する

これはカタカナの文字列を文字コードにもとづいて分類し、変換の大原則に還元してやるということです。

これは一覧表をみて考えるとわかりやすいと思います。

カタカナの濁音・半濁音は清音にするということから始まります。

一覧表をみると、アイウエオ順と文字コードの順番は一致しています。

 

変換の大原則にしたがう場合

拗音の「ァ」から「カ」までは「変換の大原則」にしたがって変換することができます。これは文字コードが12449から12459までです。

同様に拗音の「ッ」の場合は文字コードが12483であり、「ツ」の場合は文字コードが12484であり、「ナ」から「ノ」の場合は文字コードが12490から12494であり、「マ」から「ン」の場合は文字コードが12510から12531です。

いずれの場合も、文字コードの数値から96を引いた数値をUNICHAR関数の引数にして、ひらがなの文字をもとめます。

 

濁音を清音に変換する場合

濁音の文字コードが偶数の場合と奇数の場合で処理がことなります。

 

濁音の文字コードが偶数の場合

「ガ」から「ヂ」までは、濁音を清音に変換してから、ひらがなに変換します。

その前に「ガ」の文字コードをみると12460であり、「か」の文字コードをみると12459です。

ほかの文字も同様であり、濁音の場合の文字コードは「偶数」であり、清音の場合の文字コードは「奇数」です。

したがって、文字コードの数値を「2」で割ってあまりが「0」の場合は濁音の文字コードですので、1を引いてやると、清音の文字コードになります。

割り算をしてあまりを求めるには、MOD演算子をつかいます。

Private Function F_TwoMod_1(ByVal myCode As Long) As Long
    If myCode Mod 2 = 0 Then myCode = myCode - 1
    
    F_TwoMod_1 = myCode
End Function

このファンクション・プロシージャをかましてやることによって、「変換の大原則」にしたがって変換することができます。

 

濁音の文字コードが奇数の場合

「ヅ」から「ド」までの場合、「ヅ」の文字コードをみると12485であり、ほかの文字も同様であり、濁音の場合の文字コードは「奇数」であり、清音の場合の文字コードは「偶数」です。

したがって、文字コードの数値を「2」で割ってあまりが「1」の場合は濁音の文字コードですので、1を引いてやると、清音の文字コードになります。

Private Function F_TwoMod_0(ByVal myCode As Long) As Long
    If myCode Mod 2 = 1 Then myCode = myCode - 1
    
    F_TwoMod_0 = myCode
End Function

このファンクション・プロシージャをかましてやることによって、「変換の大原則」にしたがって変換することができます。

 

濁音・半濁音を清音にする場合

例として、「ハ」と「バ」と「パ」の文字コードの関係を整理してみましょう。

「ハ」の文字コードは12495であり、「バ」の文字コードは12496であり、「パ」の文字コードは12497です。

この場合、文字コードの数値を「3」で割ってあまりが「0」の場合は清音の文字コード、「3」で割ってあまりが「1」の場合は濁音の文字コード、「3」で割ってあまりが「2」の場合は半濁音の文字コードだということです。

したがって、「3」で割ってあまりが「0」の場合は、そのままで清音の文字コード。

つぎに、「3」で割ってあまりが「1」の場合は、「1」を引くと清音の文字コード。

さらに、「3」で割ってあまりが「2」の場合は、「2」を引くと清音の文字コード。

以上のことをマクロにするには、Select文とMod演算子をくみあわせます。

Private Function F_ThreeMod(ByVal myCode As Long) As Long
    Select Case myCode Mod 3
        Case 1
            myCode = myCode - 1
            
        Case 2
            myCode = myCode - 2
            
    End Select
    
    F_ThreeMod = myCode
End Function

 

カタカナの「ヴ」を変換する場合

カタカナの「ヴ」の文字コードは12532なので、その場合にHiraganaの値を「う」にします。

 

まとめ

以上をまとめると、次のソースコードになります。

Private Sub Worksheet_Change(ByVal Target As Range)
    Select Case True
        Case Not Intersect(Target, Range("J7")) Is Nothing
            Dim Katakana As Range
            Dim Hiragana As Range
            
            Set Katakana = Range("J7")
            Set Hiragana = Range("B8")
    
            If Len(Katakana.Value) = 0 Then
                Hiragana.Value = ""
            
            Else
                Dim myCode As Long
                myCode = _
                WorksheetFunction.Unicode(Katakana.Value)
                
                Select Case myCode
                    Case 12449 To 12459, 12483 To 12484, _
                         12490 To 12494, 12510 To 12531
                        Hiragana.Value = _
                        F_NormalConverter(myCode)
                    
                    Case 12460 To 12482
                        Hiragana.Value = _
                        F_NormalConverter(F_TwoMod_1(myCode))
                    
                    Case 12485 To 12489
                        Hiragana.Value = _
                        F_NormalConverter(F_TwoMod_0(myCode))
                    
                    Case 12495 To 12509
                        Hiragana.Value = _
                        F_NormalConverter(F_ThreeMod(myCode))
                        
                    Case 12532
                        Hiragana.Value = "う"

                End Select
            End If
            
            Set Hiragana = Nothing
            Set Katakana = Nothing
    End Select
End Sub

Private Function F_NormalConverter(ByVal myCode As Long) _
    As String
    
    F_NormalConverter = _
        WorksheetFunction.Unichar(myCode - 96)
End Function

Private Function F_TwoMod_1(ByVal myCode As Long) As Long
    If myCode Mod 2 = 0 Then myCode = myCode - 1
    
    F_TwoMod_1 = myCode
End Function

Private Function F_TwoMod_0(ByVal myCode As Long) As Long
    If myCode Mod 2 = 1 Then myCode = myCode - 1
    
    F_TwoMod_0 = myCode
End Function

Private Function F_ThreeMod(ByVal myCode As Long) As Long
    Select Case myCode Mod 3
        Case 1
            myCode = myCode - 1
            
        Case 2
            myCode = myCode - 2
            
    End Select
    
    F_ThreeMod = myCode
End Function

 

おわりに

今回のリクエストがあるまで、カタカナとひらがなの文字コードの関係、清音と濁音と半濁音の関係などについて、しらべたこともありませんでしたが、しらべてみたら明確な数値の関係があり、意外とおもしろかったですね。

もっとも、文字コードの世界は深いので、これ以上掘るよりはほかのことを深掘りしようと思います。

 

Copyright 2018 m-eye blog All Rights Reserved.