戻る  □一般操作のサロン  □ 使用方法  □ 新着記事  □ 新規に質問する!  □ トピック一覧  □ 検索  □ 過去ログ
[ 最新記事及び返信フォームをトピックトップへ ]
このトピック参照回数 :
エクセルVBAでUNICODEの正規化を行いたい。

    [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のコードが含まれています。

      緑の太文字→注釈
      茶色の太文字→条件分岐
      赤の太文字→ループ
      青の太文字→その他




    [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


      この記事にはVBAのコードが含まれています。

      緑の太文字→注釈
      茶色の太文字→条件分岐
      赤の太文字→ループ
      青の太文字→その他




    [195661] Re[2]: エクセルVBAでUNICODEの正規化を行いたい。-

    解決!!ありがとうございました! / 記事引用/メール受信=OFF■

    □投稿者/ うに -(2023/03/15(23:12))
    □U R L/

      4種類あることは調査してて、その中のNFKCをVBAで実現できれば
      私の目的とすることができる、と考えていました。
      そこまでしか調べることができなかったのですが、
      まさかAPIに専用の関数があるとは思いませんでした。

      教えていただいた方法で問題なく実現できそうです。

      ありがとうございました。



このトピック内容の全ページ数 / [0]

このトピックに書きこむ
Name/
E-Mail/

└>このツリーのレス記事をメールで受信しますか? YES/ NO/
Title/
URL/
Comment/ 通常モード->  図表モード-> (←の場合適当に改行を入れて下さい)
タグが使用できます。例 ⇒ <font color="blue">文字</font>
解決!!ありがとうございました! 解決       保留中です・・・ 保留        迷宮入りorほかあたって見ます・・ 迷宮入       すいませ〜ん。誰か〜! Help! ←※回答者専用
解決したらチェック       保留(コードテスト中など・・)         解決不可orレスが全く付かなくてほかのサイトに行くときなど・・
削除キー/
(半角8文字以内) 


- Child Forum -
Edit:ゆう-G