えくせるちゅんちゅん

ことりがエクセルをちゅんちゅんするブログ

文字列中の濁音を清音に変換するVBA汎用関数を作ってみた

GW1日目。今日は自作の文字列処理ライブラリに入っていた濁音を清音に変換する関数が、あまりにイケてないので書き直してみました。


作ったもの

以下のように文字列を変換する関数を作成した。

変換前 変換後
1 こんにちは こんにちは
2 ことりちゅんです。 ことりちゅんてす。
3 VBAで遊ぼう VBAて遊ほう
4 この前新しいルータを買いました。 この前新しいルータを買いました。
5 RTX830です。 RTX830てす。
6 この関数ならハンカクカタカナもバッチリです。 この関数ならハンカクカタカナもハッチリてす。


総当りではかっこよくないので、半角カタカナにすると清音と濁点が分離するという性質を活用している。


修正前のソースコード

関数名で検索したらこのサイトが出てきて、内容がほぼ同一のため数年前にコピーしたものと思われる。

今までお世話になりました。ありがとう。

Public Function RemoveDakuten(base_string As String, Optional fExtend As Boolean = False) As String
    Dim i As Long, j As Long, k As Long
    Dim strBase As String   '濁音(半濁音)を清音にしたカタカナ主体文字列
    Dim katakanaTxt As String   '濁音・半濁音のままのカタカナ主体文字列
    Dim strDst As String    '元のtxt文字列から濁点・半濁点を清音に変換した文字列
    
    strBase = base_string
    strDst = base_string
    katakanaTxt = StrConv(base_string, vbKatakana) '全角カタカナへ変換
    
    i = Len(base_string)
    If (i > 0) Then
        strBase = StrConv(katakanaTxt, vbNarrow) '半角カタカナへ変換
        strBase = Replace(strBase, Chr(222), "") '濁点除去
        If (fExtend = True) Then
            strBase = Replace(strBase, Chr(223), "") '半濁点除去
        End If
        strBase = StrConv(strBase, vbWide) '全角カタカナへ変換
        For j = 1 To i
            If (Mid(strBase, j, 1) <> Mid(katakanaTxt, j, 1)) Then
                If (InStr("ヴ", Mid(katakanaTxt, j, 1)) = 1 Or _
                  InStr(StrConv(Mid(katakanaTxt, j, 1), vbHiragana), Mid(base_string, j, 1)) <> 1) Then
                    strDst = Mid(strDst, 1, j - 1) & _
                                Mid(strBase, j, 1) & _
                                Mid(base_string, j + 1, i - j)
                Else
                    strDst = Mid(strDst, 1, j - 1) & _
                                StrConv(Mid(strBase, j, 1), vbHiragana) & _
                                Mid(base_string, j + 1, i - j)
                End If
            End If
        Next
    End If
    RemoveDakuten = strDst
End Function


書き下ろしたソースコード

インデントが大幅に軽減され、とてもスッキリとしたコードとなった。

StrConvVbStrConv列挙体を使っているので、その仕様だけ理解しておくこと。


まとめ

昔かき集めたコードは、ネットから拾ってきてそのままのものが多々ある。

特に利用頻度の少ない関数はメンテされていないため、久々に使おうとすると仕様に漏れがあったりする。

こういう機会で綺麗にしていければ良いなと思う。


なお、今回はStrConvで行ったが、StrConvには文字化けバグがあるという話もあるので、Replaceで総当り置換したほうが安全かもしれない。まだ厳密にチェックしていないので、使う人は注意すること。

こんなマイナーな関数、使う人いないか・・・。


以上


何か御座いましたらコメント欄、またはTwitterからどうぞ♪

それではまた来週♪ ちゅんちゅん(・8・)