タイトル : Re: MidB関数 投稿日 : 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 となっています。 |