はじめに
以前、使用する文字の濁点が分離していることに気づかずにVBAで処理を実行し、うまく動作せず、原因追究に少し時間が掛かってしまったという事態がありました。
濁点・半濁点の分離は、見た目ではまったくわかりませんでしたが文字を1文字ずつ削除していくとたしかに2文字に分離していました。
私がこの問題に遭遇した際に、対処法として追加した結合処理をご紹介いたします。
原因について
分離現象が起こる原因としては、文字コードが関係しています。
Windowsのファイルシステムでは文字コード体系 「NFC」 を採用しているのに対し、MacOSでは文字コード体系 「NFD」 を採用しています。
NFCでは濁点・半濁点がある文字をそのまま一文字として表されますが、NFDでは基底文字(例:は)と結合文字(例:゜)の組み合わせとして合成文字(例:ぱ)が表されます。
そのため、例えばファイル名に濁音や半濁音が含まれるファイルが開けなくなったり、文字列操作がうまくいかなかったり・・・さまざまな問題が起こります。
これは、VBAに限らず合成文字が存在する言語では起こりうる問題です。 ”こういった現象がある”ということを知っておくだけでも、エラーが起きた際の原因調査時間は短縮されると思います!
対処方法
では、実際に私が対処法として追加した関数をご紹介いたします。
Function ChangeToNFC(str) As String
Dim targetPosition As Integer '濁点・半濁点の位置
Dim nfdStr As String '基底文字と結合文字の文字列
Dim nfcStr As String '合成文字
Do
targetPosition = InStr(str, ChrW(12441)) '濁点
If targetPosition = 0 Then Exit Do
nfdStr = Mid (str, targetPosition - 1, 2)
nfcStr = ChrW (AscW (Mid (str, targetPosition - 1, 1)) + 1)
str = Replace(str, nfdStr , nfcStr )
Loop
Do
targetPosition = InStr(str, ChrW(12442)) '半濁点
If targetPosition = 0 Then Exit Do
nfdStr = Mid (str, targetPosition - 1, 2)
nfcStr = ChrW (AscW (Mid (str, targetPosition - 1, 1)) + 2)
str = Replace (str, nfdStr , nfcStr )
Loop
ChangeToNFC = str
End Function
-
該当の文字列を引数に渡す
-
Unicodeコードポイントから濁点・半濁点を取得し(ChrW関数)、文字位置から、該当のテキスト内に濁点・半濁点が存在するかを判定する
-
濁点・半濁点がある場合、[基底文字と結合文字の文字列]を取得する
-
取得したUnicodeコードポイントから[合成文字]を取得する
-
該当の文字列の中から、[基底文字と結合文字の文字列]と[合成文字]を置き換える
-
Do~Loopで、濁点・半濁点が文字列になくなるまで繰り返す
以前に紹介した文字列操作関数も多く使用しておりますので、ぜひ見ながら処理を確認してみてください!✨
関連記事
さいごに
NFC/NFD問題は他サイトでもかなり問題視されており、結合処理についてもさまざまな方法が展開されているので、そちらもぜひ参考にしてみてください。
濁点つきの文字は元の文字のコード+1、半濁点つきの文字は+2のコードポイントに存在する ↩︎