がんばれ! isKanjiメソッドくん!!!!!!!!
文字列から漢字のみ抽出する
isKanjiメソッドを強引に使う
前回
作成したisKanjiメソッドの使いどころを無理矢理発明した。
準備
まず、
こんな風にシートを作っておいて、A1セルに「TextCell」、C2セルに「BaseCell」と名前を定義しておく。ちなみに、シートには「Main」と名前を付けている。
んで、コマンドボタンを押したら、C2セルから下にずらーっとA1セルの文字列から漢字だけを抽出して1列に並べる。
ついでに、D列にはそれぞれの漢字の読みも書き込んでしまおう。
もちろん、何の役に立つのかは分からない。諸君が自分で考えてくれたまえ。これは役に立つツール類の紹介ではなくて、私自身の勉強なのだ。
コーディング
とりあえず、コードを載っけてしまおう。
リスト1 標準モジュール
Public Sub pickOutAndOrderKanji() Dim Sh As Worksheet Set Sh = ThisWorkbook.Worksheets("Main") Dim textCell As Range Set textCell = Sh.Range("TextCell") Dim baseCell As Range Set baseCell = Sh.Range("BaseCell") baseCell.CurrentRegion.ClearContents Dim wholeString As String wholeString = textCell.Value If Len(wholeString) < 1 Then _ makeUserSick ("文字がないやんけぼけー!"): Exit Sub '……(1)' Dim i As Integer Dim n As Integer Dim targetChar As String Dim tmp As String n = 0 For i = 1 To Len(wholeString) '……(2)' targetChar = Mid(wholeString, i, 1) '……(3)' If isKanji(targetChar) Then '……(4)' With baseCell .Offset(n, 0).Value = targetChar '……(5)' tmp = Application.GetPhonetic(targetChar) '……(6)' tmp = StrConv(tmp, vbHiragana) .Offset(n, 1).Value = tmp End With n = n + 1 '……(7)' End If Next End Sub
出だしの7行は、「Main」シートやら文字列の入ったセルやら基準になるセルなんかを変数にぶち込んだり、前回の書き込みを削除したり、といった処理。
んで、準備ができたら、まず(1)の
If Len(wholeString) < 1 Then _ makeUserSick ("文字がないやんけぼけー!"): Exit Sub
で処理対象文字列を調べる。文字数が0だったらそもそも処理する意味がないので、ここで終了。ちなみに、makeUserSickメソッドというのは、このとき作成したもの。
ここからが処理の中心。(2)からのForループでは、
For i = 1 To Len(wholeString)
開始・終了条件をこのように設定。1文字目から最終文字目までをループ処理する。
んで、Forブロックの中身へ。
(3)の
targetChar = Mid(wholeString, i, 1)
では、Mid関数を使って1文字を切り出し、変数targetCharにぶち込む。
(4)の
If isKanji(targetChar) Then
では、このとき作成したisKanjiメソッドでtargetCharの中身が漢字かどうかを判定。True、すなわち漢字だったら以下の処理を行う。
まず(5)。
.Offset(n, 0).Value = targetChar
C列に文字を書き込む。isKanjiメソッドがTrueを返しているのだから、漢字が書き込まれることになる。
で、(6)からの3行。
tmp = Application.GetPhonetic(targetChar) tmp = StrConv(tmp, vbHiragana) .Offset(n, 1).Value = tmp
まず、
tmp = Application.GetPhonetic(targetChar)
Application.GetPhoneticメソッドを用いて、読み仮名を変数tmpにぶち込む。ただ、この時点ではtmpの中身はカタカナなので、次の
tmp = StrConv(tmp, vbHiragana)
でStrConv関数を用いて平仮名に変えてtmpにぶち込む。
最後に
.Offset(n, 1).Value = tmp
でD2セルから数えて上から n 番目(開始は0)のセルにtmpの中身を書き込む。
最後に(7)の
n = n + 1
で n をインクリメントする。
実行結果
上掲のpickOutAndOrderKanjiメソッドをコマンドボタンに登録し、ボタンクリックで実行してみる。
ちなみに、A1セルに入っている文字列は、
お前はアホか。アホちゃいまんねん、馬鹿ですねん。競輪は日本の国技です。「C#(シーシャープ)」は、完全にオブジェクト指向プログラミング(OOP)のための言語です。こう書くと何か難しい言語のような感じを受けるかも知れませんが、心配はいりません。オブジェクト指向プログラミングでは、難しいことは全部カプセル化し、プログラマはその恩恵を受けるだけなのです。
というものとする。
ほい。この通り、うまく行って……
ない!!!!!!!!
orz
よく見ると、11行目、もともと「C」(半角アルファベットの"C")、「#」(半角記号の"#")だったところが、漢字でもないのに出力されてしまっている。これが、このとき申し上げたisKanjiメソッドの致命的な欠陥です。
何がイカンのか
原因は非常にカンタン。
たとえば、1バイト文字の文字コード「DF」(半角カタカナの半濁点"゚")を調べてみる。
10進数に直すと「223」、つまり、正の数なんである。
このとき、漢字かどうかの判定をどうしていたか。
Asc(char) >= &H889F
こんな条件式で判定していたのである。
2バイト文字の文字コードは全て負の数だったので、こんな条件式では当然1バイト文字は全てTrueになってしまうのである。
コードの修正
そこで、isKanjiメソッドのコードを以下のように修正する。
リスト2 標準モジュール
Public Function isKanji(ByVal targetCharacter As String) As Boolean Dim char As String char = targetCharacter If Len(char) <> 1 Then Err.Raise Number:=10001, _ Description:="引数は1文字のみにしてください。" If Asc(char) > 0 Then isKanji = False: Exit Function '……(*)' If Asc(char) >= &H889F Then isKanji = True Else isKanji = False End If End Function
付け加えたのは(*)の
If Asc(char) > 0 Then isKanji = False: Exit Function
だけ。要するに、文字コードが正の数だったら即Falseを返してFunctionを抜けるようにしているだけ。
テスト
生まれ変わったisKanjiメソッドをテストしてみる。
イミディエイト・ウインドウで
?isKanji("F")
を始めいろいろな1バイト文字を引数にしてisKanjiメソッドを実行してみると、
ほれ、ちゃんと期待したとおりの結果が出ている。
おわりに
これで一件落着、めでたしめでたし……と思いきや、
orz
わがisKanjiメソッドの運命やいかに!(続きません)