いつも参考にさせていただいております。
質問なのですが
aaa=chr(32) とすると
aaaにはバイナリデータで16進数の『20』が返されるのですが、
aaa=chr(242) とすると
aaaにはバイナリデータで16進数の『F2』を返してくれません。
242の値をバイナリデータの『F2』とするにはどのようにしたら
よいのでしょうか?
よろしくお願いいたします。
文字コード上存在しないデータの一部は、正しく変換されません。
バイナリデータとして扱いたい時には、ChrB関数を使うようにしてみてください。
(なお、Chr関数はShift_JIS文字、ChrW関数はUCS2文字を返します)
魔界の仮面弁士様、
ご返答ありがとうございます。
chrB(242) とやると『F2』が返されるということでしょうか?
aaa=chrB(242) としてみたのですが、『F2』は返されませんでした。
現在VB2で作成したプログラムをVB6に移行する作業を行っているのですが、
VB2で aaa=chr(242) とすると『F2』が返されます。
VB2は、文字列をShift_JISのまま扱いますが、
VB4以降では、文字列をUCS-2形式のUnicodeとして扱います。
(UCS-2では、全角半角全ての文字を、2バイトで表現します)
この内部的な文字列変換が理由で、文字コード上に存在しない
幾つかのバイナリデータは、Chr関数で扱えません。
このため、文字列変換を伴わない、ChrB関数を使う事になります。
VB2からの移行の場合、これらの文字列系関数による処理を見直す必要があります。
Chr関数→ChrB, Chr, ChrW関数
Asc関数→AscB, Asc, AscW関数
Left関数, Left$関数→Left, LeftB関数, Left$, LeftB$関数
Right関数, Right$関数→Right, RightB関数, Right$, RightB$関数
Mid関数, Mid$関数→Mid, MidB関数, Mid$, MidB$関数
また、VB2移行時には、文字列数/バイト長を調べるLen関数とLenB関数や、
文字種や文字コード変換に使われるStrConv関数などが良く使われます。
# 他に、MidB/MidB$ステートメントもありますが…これは使わないかな。
> chrB(242) とやると『F2』が返されるということでしょうか?
ですます。以下のようにして確認してみてください。
Dim S As String
Dim B() As Byte
S = ChrB(242)
B = ChrB(242)
Debug.Print Hex(AscB(S))
Debug.Print Hex(B(0))
> aaa=chrB(242) としてみたのですが、『F2』は返されませんでした。
その aaa を、どのようにして確認されましたか?
参考までに教えてください。
> 現在VB2で作成したプログラムをVB6に移行する作業を行っているのですが、
既にご存知かもしれませんが、移行に際して、参考になりそうなページを挙げておきます。
16 ビット版から Visual Basic 6.0 への移植時の注意事項
http://support.microsoft.com/default.aspx?scid=kb;ja;412583
Unicode への変換を伴わずに文字列をバイト配列にコピーする方法
http://support.microsoft.com/default.aspx?scid=kb;ja;187675
魔界の仮面弁士様、
早速のご返答ありがとうございます。
教えてくださったコードをデバックしてみたのですが、
文字キャラクターで『F2』と返されてしまいます。
バイナリデータで開いたときに『F2』となるようには
ならないでしょうか?
Dim aaa As String
aaa=Chr(32)
Debug.Print aaa
とすると、文字キャラクターはスペースが返され、
そのファイルをバイナリエディタで開くと『20』となります。
Dim aaa As String
aaa=Chr(242)
Debug.Print aaa
としたとき、バイナリエディタで『F2』となるようにしたいのです。
現状では『20』となってしまいます。
aaa=ChrB(242) の時も同じです。
242 という値をバイナリエディタで開いたとき『F2』とするような
方法がありますでしょうか?
いや、私の書いた「AscB(S)」や「B(0)」って、まさにその、
バイナリレベルでの確認方法なのですけれど。(^^;
もしかして、ファイルに吐き出してから確認しているのでしょうか。
だとしたら、ファイル出力部分のコーディングに問題があって、
データが化けているのかも知れません。出力部分のコードを見せてください。
先に書きましたように、文字コード上に無いコードは文字列として扱えないため、いろいろと問題が発生します。ファイルに書き出す場合も、バイナリ出力できる命令———例えば、Put#ステートメントとか、ADODB.StreamオブジェクトのSaveToFileメソッドとか———を利用するように心がけてください。
魔界の仮面弁士様、
早速のご返答ありがとうございます。
おっしゃるとおり、ファイルに吐き出してから確認しています。
ただ、確認の仕方が、
Debug.Printのデバックウィンドウ(イミディエイト)で
表示される文字をメモ帳にコピーペーストし、それを保存して、
バイナリエディタでみています。
> Debug.Printのデバックウィンドウ(イミディエイト)で
まず、この時点でNGです。
「文字列」として扱えない以上、Print系メソッドでは
データ化けの要因となってしまいます。
バイト配列として保持しておき、その変数の内容を、VB開発環境の
メニューにある [表示]-[ローカルウィンドウ] で確認するか、
もしくはウォッチ ウィンドウで確認するようにして下さい。
もしくは、AscB関数を使って、1バイトずつ確認していくか、
先の回答にも書きました「バイナリ出力できる命令」を使って
バイナリファイルとして出力するか……ですね。
> 表示される文字をメモ帳にコピーペーストし、
こちらもまた NG です。
たとえイミディエイトに出力されていたとしても、
クリップボードを経由する時点で、さらに化ける可能性があります。
化ける理由は、先に挙げた「対応する文字コードが無い場合」もありますが、
それとは別に、「Unicodeマッピング上の問題」というものもあります。
後者は例えば、「(株)」の文字などで発生します。
「(株)」は、Shift_JISでは Chr(&HFA58) と Chr(&H878A) の2箇所に
配置されていますが、Unicode上は ChrW(&H3231) の1箇所のみです。
その関係で、[FA58]な文字をコピーしたにも関わらず、
ペーストした結果が [878A]の文字になるという事態がおきます。
(文字化けは起きませんが、データ化けは起きる、という現象ですね)
魔界の仮面弁士様、
度々のご返答ありがとうございます。
vb2からvb6の移行は、ちょっとプログラムを書き換えればいい程度だと
思っていましたが『文字コード上に無いコードは文字列として扱えない』
というところで、つっかかってしまいます。
vb6向けに最初から書き直してみます。
どうもありがとうございました。
ツイート | ![]() |