Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 10 Pro : Excel 2016)
1文字が2バイトとは限らないUnicode文字列の扱いについて
投稿日時: 20/08/08 08:22:17
投稿者: S.Kos

こんにちは、みなさま。
 

くさかんむりがチョン切れた「花」など、これまではShift-JISの外字(EUDC)で対応していました。
遅ればせながらMSのお達し(笑)
  https://blogs.windows.com/japan/2020/02/20/about-windows-and-japanese-text/
に沿ってUnicode体系に移行しようと考えています。
 
けれども上記『くさかんむりがチョン切れた「花」』は、MS明朝などには含まれておらず、これを求めて経産省「文字情報基盤整備事業」に辿り着きました。
  https://mojikiban.ipa.go.jp/1300.html
 
同事業で配布される"IPAmj明朝フォント"は、「人名の表記等で、細かな字形の差異を特別に使い分ける必要のある業務等での活用を想定」と銘打つだけに、全ての異字体を含んでいます。
 

必要とするほぼ全ての場所で、問題なくこのフォントを使用できることを確認したのですが、ひとつだけ行き詰まっています。
『くさかんむりがチョン切れた「花」』などを含む文字列長の取得が巧くできません。
 
C#には"LengthInTextElements"が用意されていますが、VBAには無いようで・・・
VBAで、1文字が2バイトとは限らないUnicode文字列、を扱う手立てをご教示いただければ幸いです。
 
 

回答
投稿日時: 20/08/08 10:29:45
投稿者: WinArrow
投稿者のウェブサイトに移動

>Unicode文字列、を扱う手立て
 
具体的に、何をしたいの?

回答
投稿日時: 20/08/08 10:42:42
投稿者: WinArrow
投稿者のウェブサイトに移動

参考情報
 
普通に「花」と入力して、
フォントを「HG正楷書体-PRO」に変更すれば、
くさかんむりがチョン切れた「花」に表示できます。

投稿日時: 20/08/08 10:45:05
投稿者: S.Kos

WinArrowさん、お世話になります。
 
>具体的に、何をしたいの?
>
 
最初の投稿に記した通り、
 『くさかんむりがチョン切れた「花」』などを含む文字列長を取得したい
が、直接の課題です。
つまりは Len() の拡張版を探しています。
 
他の文字列操作関数においても、引数に、『くさかんむりがチョン切れた「花」』などを含む文字列、を
書ければ、との思いから
  VBAで、1文字が2バイトとは限らないUnicode文字列、を扱う手立てを、
と記しました。
 

回答
投稿日時: 20/08/08 11:40:42
投稿者: simple

後学のために教えていただきたいのですが、
Lenと異なるその長さは何のために必要になるのでしょうか。

投稿日時: 20/08/08 12:33:12
投稿者: S.Kos

あぁsimpleさん、またまたお世話になります。
 
二つの文字列データ fsNam = "姓", sdNam = "名" があります。
以下のコードでこれを結合し FlNam="姓名"を得ます。
 
  lnNam = Len(fsNam) + Len(sdNam)
  If 5 <= lnNam Then
    flNam = fsNam & sdNam
  Else
    flNam = fsNam & Space((5 - lnNam) * 2) & sdNam
  End If
 
"姓名"の全長が五文字以上ならそのまま、
でなければ、姓と名の間にスペースを挟んで五文字に、てな用途です。
 
このとき、fsNam=「くさかんむりがちょん切れた花」なら、Len(fsNam)=2 で失敗します。
なので、lenEx(fsnam)=1となる関数は無いか、との主旨です。

回答
投稿日時: 20/08/08 13:10:30
投稿者: simple

Len()が2を返すのですか。それは知りませんでした。
ありがとうございました。
 
 
最初の文字が当該3バイト以上の文字である文字列 s に対して、
Mid(s,2)は何を返すのですか?
思いつきですが、それによっては、
<>""を判定条件とした原始的な繰り返しで
文字列の長さが測れるかもしれませんね。
 
皆さんからよいコメントがあるといいですね。

回答
投稿日時: 20/08/08 13:16:13
投稿者: MMYS

simple さんの引用:
Len()が2を返すのですか。それは知りませんでした。

LEN関数は、サロゲートペアに非対応という、バクに近い仕様。
 
  Dim s As String
  s = ChrW(&HD867) & ChrW(&HDE3D)
  Range("A1").Value = s
  Range("B1").Value = Len(s)
 
上記コードは「ホッケ」は漢字1文字なのに Len=2 と返します。
 

投稿日時: 20/08/08 14:01:00
投稿者: S.Kos

MMYSさん、ご教示のほどありがとうございます。
 
Len関数が「バグに近い仕様」なのだから、その他も推して知るべし、かと・・・。
 
詰まるところ C#にある"LengthInTextElements"の類を探してるのですが、どーやらEXCEL・VBAには無さそうですね。
文字列の先頭から1バイトづつ取得して、サロケートペアかどうかを判断、ってな関数を作るしか他に手はないのでしょうか?
 
 

投稿日時: 20/08/08 20:34:25
投稿者: S.Kos

みなさま、ご教示のほどありがとうございました。
 
四年も前に、同じことを考えられたようです。
              ↓
https://qiita.com/RelaxTools/items/966bfc1810e6c94b9d07
 
未だ精読していませんが、参考になりそうです。
ここで閉じます。