こんにちは! 健史です。
ExcelVBAで文字列のバイト数を求める関数[LenB]について、
[LenB]だけでは想定するバイト数は求めることはできません!
以下'ABC'は半角であり3バイト、'項目'は4バイト、合計の'7'が表示されるはずですが、1行目は'10’が表示されます!
その場合は、LenBの対象をStrConv("対象文字", vbFromUnicode)にすることで求めることができます。
' 10が表示される、[Len × 2]と同じ MsgBox LenB("項目ABC") ' 7が表示される MsgBox LenB(StrConv("項目ABC", vbFromUnicode))
上記だけで解消できますが、理由など調べた内容を記事にしました。
LenBだけでは使えない訳
[LenB]だけでバイト数を求められないのは、Microsoft Excelの仕様であり、言語の種類によります。
[LenB]だけでバイト数を求められない言語とは、以下の記事より日本語のほか3か国語が対象です。
新しく購入したPCに電源を入れ、初期設定するときの言語選択において設定する言語のことでしょう。
[設定]-[日付と時刻]-[言語]で確認できます。
テキストファイルやCSVファイルは、SJISやUnicodeなどいろいろなコードで作られますが、Excelで開くと読み込めます。
ただし文字化けする場合もあります。確認しているのは[UTF-8 BOM無し]のCSV形式の日本語です。
Excel上に読み込まれたデータは、日本語など「DBCSをサポートする言語」では、半角文字も全てが2バイトのUnicodeになっているようです。
具体例です。16進数で表すと、
・半角の'A'は、SJIS:41[1バイト]、UniCode:0041[2バイト]
・全角の'A'は、SJIS:8260[2バイト]、UniCode:FF21[2バイト]
です。
内部では半角文字も2バイトになっているで、LenBで求めると文字数の2倍すなわち[Lenで求めた値 × 2](2倍した値)が返ってきます。
そこでLenBを使用する際には、StrConv("対象文字", vbFromUnicode)関数で「文字列をUnicodeからシステムの既定の文字コードに変換する」必要があります。
内部で2バイトになってしまった半角文字を1バイトに戻すことであり、StrConv関数で「既定の文字コード表」に戻すのです。
調べた限りにおいては「システムの既定の文字コード表」が「SJIS」のことなのか明確に分かりませんでしたが、この記事ではSJISとして記載しています。
理解した内容をイメージにしてみました。文字'A'を16進で表示しています。
LeftB、RightB、MidBはどうなの?
LeftB、RightB、MidBもLenB同様にStrConvで変換したものを対象にする必要があるのでは?と思っていましたが、こちらは使えないように思えます。
以下試した結果です。
表中「StrConv後の関数変換」の値が文字化けしているのは、StrConvでExcel上では扱えない「既定の文字コード」に変換しているからなのでしょう。
今後使わなければならないシーンがあるかもしれませんが、今のところB無しのLeft、Right、Midで問題なく処理できると考えています。
最後に
何も知らない状態でバイト数を求めたい場合は、「LenB関数だけで求められる!」と思われることでしょう。
少なくとも私は思っていました。
だってLenB関数なのですから。
そして求められなくて、ネットで解決策を探すことになります。
ExcelVBAにおけるLenBを修正することによる影響が限定的で小さいのであれば、「DBCS言語でLenBを使う場合は、StrConv関数で変換した値を対象にする」といった修正がなされれば幸いと思います。
マイクロソフト様には、Excelの製作者でないにも関わらず、修正の可否・規模も分からないにも関わらず申し訳ありませんが、ご検討頂ければ幸いと存じます。
LenBについては別でも記事にしますが、私にとっては不可欠の関数です!
そんなこともあり疑問に思っていたことを調査してまとめてみました。
誤りや不明な点が判明した場合には訂正していきます。
コメント