このトピックに書きこむ |
---|
Re[2]: エクセルVBAでUNICODEの正規化を行いたい。 | |
---|---|
[195661] Re[2]: エクセルVBAでUNICODEの正規化を行いたい。- ■ / 記事引用/メール受信=OFF■ □投稿者/ うに -(2023/03/15(23:12)) □U R L/ 4種類あることは調査してて、その中のNFKCをVBAで実現できれば 私の目的とすることができる、と考えていました。 そこまでしか調べることができなかったのですが、 まさかAPIに専用の関数があるとは思いませんでした。 教えていただいた方法で問題なく実現できそうです。 ありがとうございました。 |
[195660] Re[1]: エクセルVBAでUNICODEの正規化を行いたい。- ■記事引用/メール受信=OFF■ □投稿者/ まる -(2023/03/15(11:00)) □U R L/ 調査済かもしれませんが.... 正規化には4種類の正規化形式あり、同一文字とみなすレベルを指定できるみたいです。 h ttps://qiita.com/fury00812/items/b98a7f9428d1395fc230 .NETだと「String.Normalizeメソッド」が標準で用意されているので VBAからはPowerShellを使えば利用可能でしょう。 h ttps://learn.microsoft.com/ja-jp/dotnet/api/system.string.normalize?view=net-8.0 以下ではWin32APIを使ってみました。ほぼ↓のパクリです。 h ttps://stackoverflow.com/questions/44929724/vba-string-normalization-via-winapi Private Declare PtrSafe Function NormalizeString Lib "Normaliz" ( _ ByVal normForm As Long, _ ByVal lpSrcString As LongPtr, _ ByVal cwSrcLength As Long, _ ByVal lpDstString As LongPtr, _ ByVal cwDstLength As Long _ ) As Long Public Enum NormalizationForm NormOther = 0 NormC = 1 NormD = 2 NormKC = 5 NormKD = 6 End Enum Public Function NormalizeStr(source As String, ByVal normForm As NormalizationForm) As String Dim buffer As String, size As Long size = NormalizeString(normForm, StrPtr(source), Len(source), StrPtr(buffer), 0) buffer = String$(Abs(size) + 1, 0) size = NormalizeString(normForm, StrPtr(source), Len(source), StrPtr(buffer), Len(buffer)) If size >= 0 And size < Len(buffer) Then NormalizeStr = Left$(buffer, size) Else NormalizeStr = source End If End Function Sub test() Range("A1:A5").Value = "ピノキオ" Range("B1").Value = ChrW(&H30D2) & ChrW(&H309A) & "ノキオ" '正規化なし Range("B2").Value = NormalizeStr(ChrW(&H30D2) & ChrW(&H309A) & "ノキオ", NormC) Range("B3").Value = NormalizeStr(ChrW(&H30D2) & ChrW(&H309A) & "ノキオ", NormD) Range("B4").Value = NormalizeStr(ChrW(&H30D2) & ChrW(&H309A) & "ノキオ", NormKC) Range("B5").Value = NormalizeStr(ChrW(&H30D2) & ChrW(&H309A) & "ノキオ", NormKD) Range("C1:C5").Formula = "=A1=B1" End Sub |
[195659] エクセルVBAでUNICODEの正規化を行いたい。- ■親トピック/記事引用/メール受信=OFF■ □投稿者/ うに -(2023/03/14(22:14)) □U R L/ Sub a() Range("A1").Value = "ピノキオ" Range("B1").Value = ChrW(&H30D2) & ChrW(&H309A) & "ノキオ" Range("C1").Formula = "=A1=B1" End Sub 上記を実行すると、 A1セルにもB1セルにも「ピノキオ」という文字列がセットされます。 見た目上は2つに違いはありません。しかし、文字自体は別物です。 B1の状態の「ピノキオ」をA1の「ピノキオ」に変換(※)したいのですが、 他の開発言語では専用の関数などが用意されているようですが、 エクセルVBAでできますでしょうか。 ※“UNICODEの正規化”と言うみたいです。 結合文字(上記例では半濁音 ChrW(&H309A) )を含んだ文字列を 結合済文字?(純粋な1文字)に変換。 実際には、シートには手入力したり、ブラウザなどからコピペした文字列などがセットされています。 その中には、結合文字などを含んだりしていて、見た目上、まったく同じであっても、 内部文字コードは違う為、検索してもヒットしなかったり、という弊害が発生しています。 UNICODEでは起こる事象なので、そこは仕方ないのですが、 それを回避するために正規化をする必要があります。 エクセルVBAで正規化する方法があるのか、という質問となります。 よろしくお願いします。 この記事にはVBAのコードが含まれています。 緑の太文字→注釈 茶色の太文字→条件分岐 赤の太文字→ループ 青の太文字→その他 |