LoginSignup
1
0

More than 1 year has passed since last update.

VBA ある文字がCobining DiaCritical Marksと合成されているかを判定する関数

Last updated at Posted at 2023-02-25

分記要素とでも訳すべき

https://symbl.cc/jp/unicode/blocks/combining-diacritical-marks/
英語でも日本語でも長すぎる。
分記要素とすべきだろう。要素だから合成可能。分記は分音記号の意味。
そもそもDiaCritical自体が分音記号という意味があるので冗長ですらある。
このような分記要素が追加されているか、判定する関数がVBAにはない。
Splitting string by combining character groups
ここをヒントにして、2つの関数を作った。
まず分音記号要素が使われているかどうかを判定する関数である。

現在はVersion 1.0だけ

Combining Diacritical Marks (0300–036F), since version 1.0, with modifications in subsequent versions down to 4.1
1.0だけといっても、コード上は後から追加すればいいような気もするが0300台よりさらにマイナーになる。
Combining Diacritical Marks Extended (1AB0–1AFF), version 7.0
https://symbl.cc/jp/unicode/blocks/combining-diacritical-marks-extended/
そもそも表示できない
Combining Diacritical Marks Supplement (1DC0–1DFF), versions 4.1 to 5.2
https://symbl.cc/jp/unicode/blocks/combining-diacritical-marks-supplement/
古代ギリシア語!?
Combining Diacritical Marks for Symbols (20D0–20FF), since version 1.0, with modifications in subsequent versions down to 5.1
https://symbl.cc/jp/unicode/blocks/combining-diacritical-marks-for-symbols/
記号用ダイアクリティカルマーク(合成可能)

などがあるが使い方が思い浮かばない。

コードの原理

Len関数で文字の長さを計る。あれば必ず2字以上になる。
char = AscW(Mid(str, i, 1))

鍵は2つ

1 AscWとMid

まずMidを使う。そして
AscW(Mid(str, i, 1))

  1. AscWを使う
  2. Midを使う。
  3. Midで切るのは1字

2 値が該当するか

If Not (char >= &H300 And char <= &H36F)
ここで判定している。
理論的に言えば、ここのコードを追加すれば他も判定できそうだ。しかし、使用されている状況が不明なため、これ以上はコードを改善することが難しい。

Function isDiaCriticalMark(str As Variant) As Boolean
Dim i As Long
Dim strLen As Integer
  strLen = Len(str)
 Dim unicode() As String
    ReDim unicode(strLen)
 Dim unicodeLength As Integer
     unicodeLength = 0

    ' Split str into unicode()
 Dim char As Integer
    For i = 1 To strLen
        char = AscW(Mid(str, i, 1))
      If Not (char >= &H300 And char <= &H36F) Then
                unicodeLength = unicodeLength + 1
        Else
                isDiaCriticalMark = True
                Exit Function
       End If

    Next i
isDiaCriticalMark = False
Exit Function
End Function

1文字になっているのはそのままなので検知できない。

例えば
Ä
これは1文字&ExC4;なので分音記号を分解できないため、記号があるかどうか判定できない。
ただし、こうした文字はコード表ではある程度固まっているので、必要であれば正規表現で探して判定することになるだろう。そもそも分解して分記要素の有無を判定するのはコードが変わるからだが、&ExC4;は分解できないし、そのまま入力もコードに変換することも可能なので、今回の関数の判定対象でない。別途作成する必要がある。

このコードの必要性

目的と長所

例えばダブルローラインはU+2017に分解されることがあるが、実際にコードポイントとして存在する。‗&#x2017;しかし、これは合成可能ではない。合成可能なものは̳&#x0333;である。ところが文字の分解のしかたを間違うと、0333が出てこない。そこで、この関数で判定して分解方法を変える必要がある。ほかにやり方があるのかもしれないが、とりあえず、これだとWinApiや参照設定は必要ない。

短所

  • 最初から1文字になっているものは判定できない。例Ä&#xC4;
  • 2文字以上連続している場合に向かない。
  • 主要なコード0300番台のみ判定。しかしこれでもかなり判定できる。あとは表示ができないとか、古代ギリシア語など。表示ができずさらに使い方がわからないので今回は断念。判定を追加すればいいと思われるが確証が持てない。
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0