ExcelはUnicodeに対応していまして、例えば
"ああ😊ああ"
なんて文字列もセルに記述できるわけです。
ちなみにセル内のデータは\xl\sharedStrings.xmlにUTF-8で格納されていまして、"😊"はU+1F60A(バイナリとしてはF0 9F 98 8A)となっています。
さて、これを、例えばセルA1に記述してから
Call MsgBox(Me.Cells(1, 1))
なんてやってみると、
化けます。
Me.Cells(2, 1) = Me.Cells(1, 1)
とフルコピーすると正常にコピーされますが、
Me.Cells(3, 1) = Mid(Me.Cells(1, 1), 3, 1)
とすると絵文字がうまく取り出せません。内部的には2文字扱いになっているらしく、
Me.Cells(3, 1) = Mid(Me.Cells(1, 1), 3, 2)
で絵文字1文字が取り出せます。
"😊あ"と2文字取り出すためには
Me.Cells(3, 1) = Mid(Me.Cells(1, 1), 3, 3)
と3文字分取り出す必要があるわけですね。
InStrとかはもっと厳しい。文字位置が化けるのみならず、そもそもVBEがUnicodeに対応していないので、コードエディタで
InStr(Me.Cells(1, 1), "😊")
と入力した時点で
InStr(Me.Cells(1, 1), ??")
になっちゃいます。
---
テキストファイルの書き出しもうまくいきません。
とやってみると、できあがったファイルはShift-JIS、先ほどのメッセージボックスと同じように絵文字部分が「??」となります。
まあ、VBAのファイルI/Oはネットワークパス(UNC形式)にも対応していない今時のネットワークだらけの作業環境ではあまり使い物にならないことで有名なのですが。
では、ネットワーク系にも使えるFSO(FileSystemObject)経由ならどうなのか。
VBEのメニューから ツール > 参照設定 で「Microsoft Scripting Runtime」を指定してから
としてやれば一応書き出せますが......「TristateTrue」だとUTF-16ですね。
今時の各種システムはUTF-8が主流なので、これではちょっときびしい。いやちょっと気の利いた市販アプリであれば複数種の文字コードに対応していたりなんなら自動判別までしてくれますが、SIが作る業務系だとそんな汎用性はコストがかさむだけなので、まあUTF-8固定なことが多いわけです。ちょっと提供時期が古かったりSierの頭が古かったりするといまだにShift-JISオンリーなんてのもありますが、今や人名地名もUnicode抜きではまともに表記できないご時世ですのでいかがなものかと。
ちなみに「TristateFalse」だとShift-JISになり、Unicode文字が混じった文字列を保存しようとするとエラーになります。
じゃあ、ADODBを使えばどうなのか。(正直VBAのファイルI/OなんでADODBを使うセオリーができているのかよくわかっていません。なんかしらの経緯があると思うんですが)
VBEのメニューから ツール > 参照設定 で「Microsoft ActiveX Data Objects 6.1 Library」を指定してから
としてやれば、おおこれはうまくいきました。
これからVBAでファイルI/O系を扱うならADODB経由がまあ無難なのではないかと。
ーーー
Microsoftが「もうVBAには抜本的な修正を加えない」と言い切っちゃってるので、ワークシートとVBAの文字コードの扱いの乖離はこれからもずっとこのままなんじゃないかなーと思っています。
最近妙に「Python使ってExcelを自動化」なんてのが流行っているようですが、あるいはこのへんの解決策への一案という面もあるのかもしれませんね。(確認していませんが)
確認環境: Excel for Microsoft365 MSO バージョン2011 ビルド13426.20308 16.0.13426.20308
0 件のコメント :
コメントを投稿