Kana Converter – How to use Evaluate Method
はじめに
・動作は無保証です。
・Excel 2016 + Windows 10、Excel 2010 + Windows 7で動作確認しています。
・ファイルはここからダウンロードしてください。
会社で、取扱う取引先名(会社名)のカタカナのフリガナの頭文字をひらがなに変換するプログラムを作成しました。
イセタン => い
ゲンキショウジ => け
トウキュウデンテツ => と
フジツウ => ふ
パナソニック => は
ロックオン => ろ
ヴェネツィアセイサクジョ => へ
濁音(例えばガ行)の頭文字は清音(カ行)の頭文字に、半濁音(パ行)の頭文字は清音(ハ行)の頭文字に変換する、というしばり(ルール)もありました。
しかし、ウェブで公開するにあたって、ひらがなをカタカナに変換するプログラムを追加し、「ひらがな・カタカナ相互変換プログラム」としました。
いせたん => イ
げんきしょうじ => ケ
とうきゅうでんてつ => ト
ふじつう => フ
ぱなそにっく => ハ
ろっくおん => ロ
ヴぇねつぃあせいさくじょ => へ
ワークシートの説明
上の図をごらんください。「C2」セルに会社名などのカタカナのフリガナ(ひらがなのふりがな)を入力してEnter
キーを押すと、「C3」セルにひらがな(カタカナ)の頭文字1文字を表示します。
このプログラムで特に説明したいのは、Evaluate
メソッドの使い方と「文字コードの整理」の方法です。以下、順に説明します。
ですが、1点だけ、ワークシートについて説明したい部分があります。
「D2」セルに関数が設定されているのですが、その関数がこちら。
ちなみに「D2」セルと「D3」セルの文字は非表示に設定してあります。
=IF(C2="","",IF(AND(CODE(C2)>=9505,CODE(C2)<=9588),CODE(C2)-256,IF(AND(CODE(C2)>=9249,CODE(C2)<=9331),CODE(C2)+256,"")))
このセルに関数を設定しているのは、ここで用いられているCODE
関数がVBAのWorksheetFunction
プロパティで使えないワークシート関数だからです。CODE
関数は引数に文字を指定すると、その文字コードを返す関数ですが、CODE
はWorksheetFunction
オブジェクトのメソッドではないのです。ですので、モジュールに普通に記述するとエラーが発生します。普通とは次のような例をいいます。
Dim myCode As Long If Range(C2).Value = "" Then myCode = "" ElseIf WorksheetFunction.Code(Range(C2).Value) >= 9505, And _ WorksheetFunction.Code(Range(C2).Value) <= 9588 Then myCode = WorksheetFunction.Code(Range(C2)) - 256 ElseIf WorksheetFunction.Code(Range(C2).Value) >= 9249, And _ WorksheetFunction.Code(Range(C2).Value) <= 9331 Then myCode = WorksheetFunction.Code(Range(C2)) + 256 Enf If
この命令文はエラーになります。上に書いたとおり、Code
はWorksheetFunction
のメソッドではないから実行できないのです。だから、セルに関数を設定し、計算をさせています。
これに対して、たとえば、Replace
関数はワークシート関数であり、Worksheetfunction
のメソッドでもあるので、次の例は実行できます。
Dim myString As String myString = Worksheetfunction.Replace(Range(C2), vbLf, vbCrLf)
このように使いづらいCODE
関数ですが、どうしてもプログラム上で使いたい場合はEvaluate
メソッドとともに使用します。
このプログラムのソースコード
Option Explicit Private Sub Worksheet_Change(ByVal Target As Range) Switch = True If Not Intersect(Target, Cells(2, 3)) Is Nothing Then If Len(Cells(2, 3).Value) = 0 Then Range(Cells(3, 3), Cells(3, 4)).Value = "" Else Dim myCode As Long myCode = Evaluate("CODE(C2)") '[CODE(C2)] Select Case myCode 'ひらがな => カタカナ Case 9249 To 9258 Call S_NormalConverter Case 9259 To 9282 Call S_DivideByTwo_1 Case 9283 Call S_NormalConverter Case 9284 To 9289 Call S_DivideByTwo_2 Case 9290 To 9294 Call S_NormalConverter Case 9295 To 9309 Call S_DivideByThree_1 Case 9310 To 9331 Call S_NormalConverter 'カタカナ => ひらがな Case 9505 To 9514 Call S_NormalConverter Case 9515 To 9538 Call S_DivideByTwo_1 Case 9539 Call S_NormalConverter Case 9540 To 9545 Call S_DivideByTwo_2 Case 9546 To 9550 Call S_NormalConverter Case 9551 To 9565 Call S_DivideByThree_2 Case 9566 To 9587 Call S_NormalConverter Case 9588 Call S_VConverter Case Else MsgBox "ひらがな、またはカタカナを" & _ "入力してください。", vbExclamation Range(Cells(3, 3), Cells(3, 4)).Value = "" End Select End If End If Switch = False End Sub Private Property Let Switch(ByVal Flag As Boolean) With Application .ScreenUpdating = Not Flag .EnableEvents = Not Flag End With End Property Private Sub S_NormalConverter() Cells(3, 4).Value = "" Cells(3, 3).Value = Evaluate("CHAR(D2)") '[CHAR(D2)] End Sub Private Sub S_DivideByTwo_1() If Evaluate("MOD(D2, 2)") = 0 Then '[MOD(D2, 2)] Cells(3, 4).Value = Cells(2, 4).Value - 1 Cells(3, 3).Value = Evaluate("CHAR(D3)") '[CHAR(D3)] Else Cells(3, 4).Value = "" Cells(3, 3).Value = Evaluate("CHAR(D2)") '[CHAR(D2)] End If End Sub Private Sub S_DivideByTwo_2() If Evaluate("MOD(D2, 2)") = 1 Then '[MOD(D2, 2)] Cells(3, 4).Value = Cells(2, 4).Value - 1 Cells(3, 3).Value = Evaluate("CHAR(D3)") '[CHAR(D3)] Else Cells(3, 4).Value = "" Cells(3, 3).Value = Evaluate("CHAR(D2)") '[CHAR(C3)] End If End Sub Private Sub S_DivideByThree_1() Select Case Evaluate("MOD(D2, 3)") '[MOD(D2, 3)] Case 0 Cells(3, 4).Value = Cells(2, 4).Value - 1 Cells(3, 3).Value = Evaluate("CHAR(D3)") '[CHAR(D3)] Case 1 Cells(3, 4).Value = Cells(2, 4).Value - 2 Cells(3, 3).Value = Evaluate("CHAR(D3)") '[CHAR(D3)] Case 2 Cells(3, 4).Value = "" Cells(3, 3).Value = Evaluate("CHAR(D2)") '[CHAR(D2)] End Select End Sub Private Sub S_DivideByThree_2() Select Case Evaluate("MOD(D2, 3)") '[MOD(D2, 3)] Case 0 Cells(3, 4).Value = Cells(2, 4).Value - 2 Cells(3, 3).Value = Evaluate("CHAR(D3)") '[CHAR(D3)] Case 1 Cells(3, 4).Value = "" Cells(3, 3).Value = Evaluate("CHAR(D2)") '[CHAR(D2)] Case 2 Cells(3, 4).Value = Cells(2, 4).Value - 1 Cells(3, 3).Value = Evaluate("CHAR(D3)") '[CHAR(D3)] End Select End Sub Sub S_VConverter() If Len(Cells(2, 3).Value) = 1 Then Cells(3, 3).Value = "ふ" Else Select Case Left(Cells(2, 3).Value, 2) Case "ヴァ", "ヴぁ" Cells(3, 3).Value = "は" Case "ヴィ", "ヴぃ" Cells(3, 3).Value = "ひ" Case "ヴェ", "ヴぇ" Cells(3, 3).Value = "へ" Case "ヴォ", "ヴぉ" Cells(3, 3).Value = "ほ" Case Else Cells(3, 3).Value = "ふ" End Select End If End Sub
Worksheet_Changeプロシージャとは
ワークシートのセルのいずれかの値が変更されたとき起動するイベントプロシージャです。「ひらがな・カタカナ相互変換プログラム」シートのシートモジュールに書いています。このプロシージャでは、
Private Sub Worksheet_Change(ByVal Target As Range) If Not Intersect(Target, Cells(2, 3)) Is Nothing Then ~~~~~~~~~~~~ End If End Sub
として、プロシージャが起動する原因となるセルを「C2」セルに限定しています。
Intersect
メソッドは、
Intersect(Rangeオブジェクト1、Rangeオブジェクト2)
という書式で、Range
オブジェクト1とRange
オブジェクト2で共通するRange
オブジェクトを返します。
共通するRange
オブジェクトがない場合は、Nothing
を返します。
「C2」セルとの共通範囲がNothing
でないかどうかを判定するには、
If Not Intersect(Target, Cells(2, 3)) Is Nothing
という書式にします。
共通範囲が「C2」セルだったら、すなわち、プロシージャの適用範囲が「C2」セルのみだったら「~~~~~~~~~~~~」に記述された命令を実行する、ということになります。
Worksheet_Changeプロシージャの使い方は、この使い方が多いです。あるセルの値が変更したら何らかの命令を実行したい、ただ、直接そのような操作を実現するプロシージャはない、したがって、Worksheet_Changeプロシージャでセル範囲を限定して命令を実行する、というパターンが多いと思います。
「Switch」プロパティプロシージャとは
Switch = True ~~~~~~~~~~~~ Switch = False
Worksheet_Changeプロシージャの中で、プロシージャ名の変数Switch
にTrue
、False
を代入して使います。
Private Property Let Switch(ByVal Flag As Boolean) With Application .ScreenUpdating = Not Flag .EnableEvents = Not Flag End With End Property
標準モジュールやシートモジュール(オブジェクトモジュールの1つ)で使われるプロパティプロシージャは、Property Let
プロシージャが多いと思います。Property Let
プロシージャはプロパティに値を設定します。
Evaluateメソッドとは
Evaluate
メソッドとは、このプロシージャでいえば、WorkshetFunction
オブジェクトのメソッドではないワークシート関数を実行するためのメソッドです。このプロシージャでは、CODE
関数や、CHAR
関数、MOD
関数に使用しています。
myCode = Evaluate("CODE(C2)") '[CODE(C2)] Cells(3, 3).Value = Evaluate("CHAR(D2)") '[CHAR(D2)] If Evaluate("MOD(D2, 2)") = 0 Then '[MOD(D2, 2)]
Evaluate
メソッドの中は、ダブルクォーテーションで囲み、その中はセルに記入するのと同じ書き方をする必要があります。本当はもっと複雑な使い方ができるのですが、まずはこのような書き方を覚えましょう。
上の例の右側にあるコメントでは、Evaluate
メソッドの省略形を表示しています。[~~~]
と、大かっこ(スクエアブランケット)で関数を囲むと、Evaluate("~~~")
と書いたのと同じ意味になります。
しかし、この大かっこを使った省略形は、非常にわかりづらいので、あまり使わないほうがいいでしょう。鶏が先か卵が先かということにもなりますが、この省略形はあまり使われないので、わかりづらく、他人様に伝えづらいのが非常に大きな欠点です。
文字コードの整理
ひらがなとカタカナを相互変換するには、文字コードを用いて、文字を数値で表すことが必要です。
下の図を見てください。
かなと文字コードの対応を「文字コード表」シートに表したものですが、濁音・半濁音は清音に変換するというルールに基づいて、薄いみどりや青でその対応を表しています。
頭文字が「が」で文字コードが「9260」であるものは、濁音は清音に変換するので、文字コード「9259」である頭文字「か」に変更します。
1つ目の性質
ひらがなとカタカナの文字コードにはある規則性があります。
ひらがなの「あ」の文字コードは「9250」、カタカナの「ア」の文字コードは「9506」。その差をとると「256」になります。
その他の文字についても、ひらがなとカタカナの文字コードの差はすべて「256」になります。
この性質を用いてひらがなとカタカナの変換をおこないます。
2つ目の性質
清音と濁音、半濁音のあいだにもある規則性があります。
「文字コード表」シートに色付けして表したように、清音と濁音、半濁音は文字コードが隣り合っています。
「か」の文字コードは「9259」、「が」の文字コードは「9260」ですので、文字コードを2で割って余りが「1」なのが清音、余りが「0」なのが濁音で、濁音のほうが必ず大きな文字コードになっています。
したがって、文字コードの数字を2で割って余りが「0」、つまり余りがないものの文字コードの数字から「1」を引いてやればすべて清音に変換できます。
これは、逆のパターンで、余りが「0」なのが清音、余りが「1」なのが濁音というパターンもあります。
半濁音の場合
半濁音があるのは「は行」「ば行」「ぱ行」のひらがなとカタカナに限られます。
ここでは、清音・濁音・半濁音の3つがあるので、文字コードを3で割ってやります。
「は」は文字コードが「9295」、「ば」は文字コードが「9296」、「ぱ」は文字コードが「9297」ですので、余りが「1」であるのが清音、余りが「2」であるのが濁音、余りが「0」であるのが半濁音ということになります。
したがって、3で割って「割り切れる」ものは文字コードの数字から「2」を引いて、3で割って「2余る」ものは文字コードの数字から「1」を引くと、すべて清音に変換できます。
これには、もう1つ、3で割って「2余る」ものが清音になるパターンもあります。
例外について
「ヴ」については、文字列を「ヴァ」「ヴィ」「ヴ」「ヴェ」「ヴォ」に分類して、それぞれの場合に、「は」「ひ」「ふ」「へ」「ほ」に変換します。
プログラムに反映
Dim myCode As Long myCode = Evaluate("CODE(C2)") '[CODE(C2)] Select Case myCode 'ひらがな => カタカナ Case 9249 To 9258 Call S_NormalConverter Case 9259 To 9282 Call S_DivideByTwo_1 Case 9283 Call S_NormalConverter Case 9284 To 9289 Call S_DivideByTwo_2 Case 9290 To 9294 Call S_NormalConverter Case 9295 To 9309 Call S_DivideByThree_1 Case 9310 To 9331 Call S_NormalConverter 'カタカナ => ひらがな Case 9505 To 9514 Call S_NormalConverter Case 9515 To 9538 Call S_DivideByTwo_1 Case 9539 Call S_NormalConverter Case 9540 To 9545 Call S_DivideByTwo_2 Case 9546 To 9550 Call S_NormalConverter Case 9551 To 9565 Call S_DivideByThree_2 Case 9566 To 9587 Call S_NormalConverter Case 9588 Call S_VConverter Case Else MsgBox "ひらがな、またはカタカナを" & _ "入力してください。", vbExclamation Range(Cells(3, 3), Cells(3, 4)).Value = "" End Select
上述の性質に基づいて、文字コードを分類し、上のソースコードに反映しました。
S_NormalConverter
は通常の変換をおこなうサブプロシージャです。
S_DivideByTwo_1
とS_DivideByTwo_2
は文字コードを2で割るサブプロシージャです。
S_DivideByThree_1
とS_DivideByThree_2
は文字コードを3で割るサブプロシージャです。
文字コードの変換をおこなうサブプロシージャ
通常の変換をおこなうサブプロシージャ
Private Sub S_NormalConverter() Cells(3, 4).Value = "" Cells(3, 3).Value = Evaluate("CHAR(D2)") '[CHAR(D2)] End Sub
入力された文字を元に、「ひらがな・カタカナ相互変換プログラム」シート上の「D2」セルに設定されている関数に基づいて、文字コードの変換は自動的におこなわれています。
その関数の答えに基づいて、Cells(3, 3).Value = Evaluate("CHAR(D2)")
という命令文で「C3」セルに変換後の文字を表示します。
CHAR
関数は、文字コードを基準に文字自体を表示する関数です。
文字コードを2で割るサブプロシージャ
Private Sub S_DivideByTwo_1() If Evaluate("MOD(D2, 2)") = 0 Then '[MOD(D2, 2)] Cells(3, 4).Value = Cells(2, 4).Value - 1 Cells(3, 3).Value = Evaluate("CHAR(D3)") '[CHAR(D3)] Else Cells(3, 4).Value = "" Cells(3, 3).Value = Evaluate("CHAR(D2)") '[CHAR(D2)] End If End Sub Private Sub S_DivideByTwo_2() If Evaluate("MOD(D2, 2)") = 1 Then '[MOD(D2, 2)] Cells(3, 4).Value = Cells(2, 4).Value - 1 Cells(3, 3).Value = Evaluate("CHAR(D3)") '[CHAR(D3)] Else Cells(3, 4).Value = "" Cells(3, 3).Value = Evaluate("CHAR(D2)") '[CHAR(C3)] End If End Sub
「D2」セルに表示される文字コードを2で割って、清音の場合は「D2」セルの文字コードをそのままCHAR
関数に代入、濁音の場合は「D2」セルの文字コードから1を引いたものを「D3」セルに代入し、Cells(3, 3).Value = Evaluate("CHAR(D3)")
という命令文で「C3」セルに変換後の文字を表示します。
MOD
関数は、割り算をし、余りを求めます。
MOD(D2, 2)
は、「D2」セルに表示される文字コードを2で割って余りを求めます。
文字コードを3で割るサブプロシージャ
Private Sub S_DivideByThree_1() Select Case Evaluate("MOD(D2, 3)") '[MOD(D2, 3)] Case 0 Cells(3, 4).Value = Cells(2, 4).Value - 1 Cells(3, 3).Value = Evaluate("CHAR(D3)") '[CHAR(D3)] Case 1 Cells(3, 4).Value = Cells(2, 4).Value - 2 Cells(3, 3).Value = Evaluate("CHAR(D3)") '[CHAR(D3)] Case 2 Cells(3, 4).Value = "" Cells(3, 3).Value = Evaluate("CHAR(D2)") '[CHAR(D2)] End Select End Sub Private Sub S_DivideByThree_2() Select Case Evaluate("MOD(D2, 3)") '[MOD(D2, 3)] Case 0 Cells(3, 4).Value = Cells(2, 4).Value - 2 Cells(3, 3).Value = Evaluate("CHAR(D3)") '[CHAR(D3)] Case 1 Cells(3, 4).Value = "" Cells(3, 3).Value = Evaluate("CHAR(D2)") '[CHAR(D2)] Case 2 Cells(3, 4).Value = Cells(2, 4).Value - 1 Cells(3, 3).Value = Evaluate("CHAR(D3)") '[CHAR(D3)] End Select End Sub
「D2」セルに表示される文字コードを3で割って、余りが「2」の場合に清音になるケースでは、余りが「0」の場合に濁音になり、余りが「1」の場合に半濁音になります。
「D2」セルに表示される文字コードを3で割って、余りが「1」の場合に清音になるケースでは、余りが「2」の場合に濁音になり、余りが「0」の場合に半濁音になります。
濁音・半濁音の場合は、「D2」セルの文字コードからそれぞれ、1、2、を引いた文字コードを「D3」セルに代入し、Cells(3, 3).Value = Evaluate("CHAR(D3)")
という命令文で「C3」セルに変換後の文字を表示します。
例外の場合のサブプロシージャ
Sub S_VConverter() If Len(Cells(2, 3).Value) = 1 Then Cells(3, 3).Value = "ふ" Else Select Case Left(Cells(2, 3).Value, 2) Case "ヴァ", "ヴぁ" Cells(3, 3).Value = "は" Case "ヴィ", "ヴぃ" Cells(3, 3).Value = "ひ" Case "ヴェ", "ヴぇ" Cells(3, 3).Value = "へ" Case "ヴォ", "ヴぉ" Cells(3, 3).Value = "ほ" Case Else Cells(3, 3).Value = "ふ" End Select End If End Sub
「C2」セルの文字列の頭文字が「ヴ」の場合は、文字列が「ヴ」1文字の場合は「ふ」に、「ヴァ(ヴぁ)」「ヴィ(ヴぃ)」「ヴェ(ヴぇ)」「ヴォ(ヴぉ)」の場合は、それぞれ「は」「ひ」「へ」「ほ」に変換します。それ以外の場合は「ふ」に変換します。
「MOD」には実は別の使い方があります
ここで今まで使ってきたMOD
はワークシート関数ですが、実はVBAにはMOD
演算子があります。
Evaluate("MOD(D2, 2)") => Cells(2, 4).Value Mod 2 Evaluate("MOD(D3, 2)") => Cells(3, 4).Value Mod 2
Cells(3, 4).Value / 2
の「/」の代わりに「Mod」を使えば、余りが返ってきます。
ここでは説明の都合上、すべてEvaluate
関数で説明するため、Mod
演算子は一番最後に説明しました。
おわりに
今回は非常にニッチなニーズに応えたマクロなのですが、Evaluate
メソッドの使い方、文字コード表の整理の仕方はおもしろいなと思い、記事にしてみました。
コメントを残す