宜しくお願い致します。
VB5.0(SP3)で、バイナリデータ変換の際、次の現象が起きてしまいます。
Dim bytBData() As Byte
Dim cnt_i As Integer
Dim cnt_j As Integer
Dim lenBData As Integer
Dim StrSet As String * 1
Sub Main()
Call BinaryWrite("E2")
End Sub
Sub BinaryWrite(strBData)
bytBData = ""
cnt_j = 1
ReDim bytBData(0)
lenBData = Len(strBData) / 2
For cnt_i = 0 To lenBData - 1
ReDim Preserve bytBData(cnt_i)
bytBData(cnt_i) = "&H" + Mid(strBData, cnt_j * 2 - 1, 2)
cnt_j = cnt_j + 1
Next cnt_i
StrSet = StrConv(bytBData, vbUnicode) ← ここが問題?
RESULT = Asc(StrSet)
End Sub
BinaryWrite()の引数が、
00〜80、A0〜DFの時は正しい値として0〜128がかえってきますが、
81〜9F、E0〜FFの時は0がかえってきます。
本当は、129〜159、224〜255がかえってきてほしいのですが。
これについて何か対処方法などございましたらよろしくお願いします。
この関数は本当にエラーなく動いてますか?ざっと見る限り
bytBData(cnt_i) = "&H" + Mid(strBData, cnt_j * 2 - 1, 2)
の部分でcnt_i=0のときエラーとなりませんか?
またバイト配列に入れるのであれば明示的に
bytBData(cnt_i) = Val("&H" + Mid$(---))
としてやった方がいいかもしれません。
この関数の働きを半角2文字で表された16進数の文字列から
先頭の2文字をとり、それを1バイトのバイナリーに変換する
関数と推測すると、これは以下の1行で書けるんじゃないでしょうか?
bytBData = Val("&H" + strBData)
ちなみにA0〜DF及びE0〜FFの値が一バイト目であると
シフトJISコードでは2バイト文字とみなします
ところが元のデータは1バイトしかないためStrConv()が
理解できずに0を返したのだと推測します。
>ちなみにA0〜DF及びE0〜FFの値が一バイト目であると
0x81〜0x9F、0xE0〜0xEFの間ですね。すみません。
のん様、ご回答ありがとうございました。
大変申し訳ありませんが、再度質問させて頂きたく宜しくお願い致します。
>ちなみにA0〜DF及びE0〜FFの値が一バイト目であると
>シフトJISコードでは2バイト文字とみなします
>ところが元のデータは1バイトしかないためStrConv()が
>理解できずに0を返したのだと推測します。
ということは、StrConv()では正しい値を返すのは無理なのでしょうか?
また、正しい値を返すのが無理な場合、何か対処方法などございましたら
教えて頂きたくよろしくお願いします。
> ということは、StrConv()では正しい値を返すのは無理なのでしょうか?
Shift_JIS と UTF-16 を変換するために、vbFromUnicode/vbUnicodeを使うことはできます。
しかし、Shift_JISで定義されていないバイトデータに対してvbUnicodeを適用したり、
UTF-16で定義されていないバイトデータに対してvbFromUnicodeを適用したりすれば、
データが化けてしまう事になるでしょう。
> RESULT = Asc(StrSet)
この部分にも、StrConvと同じ事が言えます。
Shift_JISに無い文字を、Asc, Chr関数などで変換する事はできません。(化けます)
同様にAscW, ChrW関数も、Unicodeに無い文字を変換する事はできません。
(なお、AscB, ChrB関数は文字コード変換を伴わないため、データは化けません)
魔界の仮面弁士さん、ご回答ありがとうございました。
StrConv関数では、無理ということのようなので別の方法を
検討してみようと思います。
そもそもなぜStrConvを使う必要があるのでしょう?
上でも書いたように数字文字列を数値に変換するのであれば
Val関数でできますよ。