[VBA]IVS登録の異体字を常用漢字に置換したい(実装編)

本記事は「IVS登録の異体字を常用漢字に置換したい(知識編)」の続きである。

エクセルにおけるIVS登録文字の扱い

シートに張り付けた場合

赤色の文字がIVS登録文字。文字長はLen()を、文字長(Byte)にはLenB()を充てている。Variation Selectorが別の文字として扱われるため、Variation Selector無しより、文字長が長くなっている。通常の文字1つにつきVariation Selectorを表す文字が2文字かつ2バイト付与されていることが分かる。

VBAエディタに張り付けた場合

エディタでは、Shift-JIS上表現できない文字は全て文字化けを起こすため、張り付けると「辻??本迅??田」となる。?は文字コード「2F」の単なるクエスチョンマークであり、枝番としての情報が欠落するため、エディタに直接文字を張り付けて処理をすることはできない。(シートから読み取る必要がある)

実装コード

Option Explicit
' UCS(Universal Coded Character Set)に登録された文字のVariation Selectorを取り除く
' 例.にしんにょうの辻   :8FBB
'     いっしんにょうの辻 :8FBB + E0100(VS)
' 「+E01○○」のVSが環境依存文字として判定されるため削除する必要がある
Public Function Remove(str As String, ByRef replaceMap As Dictionary) As String
    Const REPLACED_MARK As Long = &H0

    Dim i As Long
    For i = 1 To Len(str) - 2
        Dim c As String
        Dim n1 As String
        Dim n2 As String
        Dim code1 As String
        Dim code2 As String
        
        c = Mid(str, i, 1)
        n1 = Mid(str, i + 1, 1)
        n2 = Mid(str, i + 2, 1)
        
        If (IsVariationSelector(n1, n2)) Then
            Call replaceMap.Add(c & n1 & n2, c)
            Mid(str, i + 1, 1) = Chr(REPLACED_MARK)
            Mid(str, i + 2, 1) = Chr(REPLACED_MARK)
            i = i + 2
        End If
    Next
    ' Variation Selectorを全て取り除く
    str = Replace(str, Chr(REPLACED_MARK), "")
    Remove = str
End Function

' 指定文字がVariation Selectorであるか
Private Function IsVariationSelector(c1 As String, c2 As String) As Boolean
    Dim code1 As String
    Dim code2 As String
    code1 = AscW(c1)
    code2 = AscW(c2)
    
    ' Variation Selectorの取りうるコードポイントの範囲に含まれるか
    ' U+E0100 - U+E01EF
    If (code1 = &HDB40 And (&HDD00 <= code2 And code2 <= &HDDEF)) Then
        IsVariationSelector = True
    Else
        IsVariationSelector = False
    End If
End Function

解説

対象の文字がIVS登録文字であるかを判定するとき、各文字の文字コードは確認していない。代わりにVariation Selectorの文字コードであれば、その直前の文字はIVS登録文字であると判定できる。

Variation Selectorの取りうる範囲はU+E0100 – U+E01EFであるが、これはUTF-8の場合である。VBA上でコードポイントを扱う時はUTF-16であるため、取りうる範囲は1バイト目が「DB40」固定、2バイト目が「DD00~DDEF」である。その条件を満たした場合、Variation Selectorを表す2文字・4バイトをReplaceにより取り除いている。

処理速度

300,000件:3.9秒
1,000件:0.013秒
データの10%にIVS登録文字が含まれるとして、その処理速度は上記の通り。