タイトル | : Re: MidB関数 |
記事No | : 13686 |
投稿日 | : 2009/05/16(Sat) 17:54 |
投稿者 | : 魔界の仮面弁士 |
> あるテキストファイルを line input で1行ずつ読み込んで、midB関数で一部分を切取りたいのですが、MidB関数がうまく動いてくれません。 16bit 版である VB2、VB3、VB4(16bit) であれば、そのコードでうまくいきますが、 32bit 版である VB4(32bit)、VB5、VB6 では違う結果となります。
これは、32bit 版の Visual Basic で使われている文字コードが Shift_JIS ではなく、 すべての文字を 2 バイトで表現する「Unicode」(UTF-16)で管理されているためです。
'--------- Dim A1 As String A1 = " ああ-1 いい"
MsgBox Len(A1) 'VB2 では「11」、VB6 でも「11」 MsgBox LenB(A1) 'VB2 では「15」、VB6 では「22」
MsgBox MidB(A1, 4, 6) 'VB2では「ああ-1」、VB6では「???」(文字化けして表現不可) MsgBox Mid(A1, 4, 6) 'VB2 も VB6 も「ああ-1 」 '---------
> MidB関数は全角は2バイト半角は1バイトで計算するはずなのになぜなのでしょうか? だからこそです。32bit 版 VB では、すべての文字が 2 バイトで表されています。
詳細情報として、Visual Basic 6.0 リリースノート (Readmevb.htm) の 「32 ビット環境での文字列操作関数の動作について」 「32 ビットでの文字列操作の 注意事項」 「ANSI 文字列のバイト単位の操作をする関数の例」 を参照しておいてください。
> " ああ-1 いい" という文字列 これは String 型ですよね。メモリ上に保持されているバイナリは、16進数表記で [VB2] 20 20 20 82 A0 82 A0 2D 31 20 20 82 A2 92 A2 [VB6] 20 00 20 00 20 00 42 30 42 30 2D 00 31 00 20 00 20 00 44 30 44 30 と並んでいます。下段が 32bit 版である VB6 のメモリ配置です。
MidB(A1, 4, 6) という事は、(先頭を1とした)4バイト目から6バイト分なので、 [VB2] -- -- -- 82 A0 82 A0 2D 31 -- -- -- -- -- -- [VB6] -- -- -- 00 20 00 42 30 42 -- -- -- -- -- -- -- -- -- -- -- -- -- の部分が取り出される事になります。
これを String として処理するために、文字列としてデコードすると、 16 bit 版の VB と 32 bit 版の VB とでは、それぞれ 'VB2 S1 = Chr(&H82) & Chr(&HA0) & Chr(&H82) & Chr(&HA0) & Chr(&H2D) & Chr(&H31) MsgBox S1 '「ああ-1」となる。
'VB6 S2 = ChrB(&H00) & ChrB(&H20) & ChrB(&H00) & ChrB(&H42) & ChrB(&H32) & ChrB(&H42) MsgBox S2 '文字化けして「???」となる。 S3 = ChrW(&H2000) & ChrW(&H4200) & ChrW(&H4232) MsgBox S3 '文字化けして「???」となる。 と処理される事になります(ちなみに、VB6 の方の S2 と S3 は同一です)。
もし、VB2 の場合と同様に、「ああ-1」と取り出したいのであれば、StrConv 関数を併用して、 Shift_JIS バイナリと Unicode バイナリの相互変換を行う必要があります。
'-------------------- Dim A1 As String A1 = " ああ-1 いい"
Dim SJIS As String, Cut As String, Unicode As String SJIS = StrConv(A1, vbFromUnicode) Cut = MidB(SJIS, 4, 6) Unicode = StrConv(Cut, vbUnicode)
MsgBox Unicode '「ああ-1」となる。 '--------------------
上記のようにすれば、望む結果になるかと思います。
ちなみにこの場合、それぞれの文字列のメモリ構成は、 [A1] 20 00 20 00 20 00 42 30 42 30 2D 00 31 00 20 00 20 00 44 30 44 30 [SJIS] 20 20 20 82 A0 82 A0 2D 31 20 20 82 A2 92 A2 [Cut] 82 A0 82 A0 2D 31 [Unicode] 42 30 42 30 2D 00 31 00 となっています。
|