電子書籍の厳選無料作品が豊富!

https://oshiete.goo.ne.jp/qa/9098167.html

このページで質問してご回答いただいたのですが
質問文が長くなってしまったので
再度質問させていただきます。

自分でもいろいろと試していて、
特性が大分分かってきました。

ただ、まだ理解できていないのが以下の二つの現象です。

引数として文字列を使った場合
r2() = StrConv("あいうえお", vbFromUnicode)
シフトJISへの変換は正常に行われるのですが
r2() = StrConv("あいうえお", vbUnicode)
Unicodeへ変換すると、なぜか空要素が途中に入ったUnicode配列が出力されます。
Unicodeの配列をUnicodeに変換しても
同じように配列の内容はそのままで空要素が入ったUnicode配列が出力されます。
この空要素の入ったUnicode配列をシフトJISへ変換しようとすると
r2() = StrConv(CStr(r2()), vbFromUnicode)
なぜかシフトJISではなく元の空要素のない正常なUnicode配列が出力されます。

空要素の入ったUnicode配列が出力されるのも疑問ですが
シフトJISへの変換で元に戻せるのは一体どういう仕様なのでしょうか?


それとあと一つ気になったのが、
シフトJISの禁則文字を含んだ文字列を
配列に変換後にもう一度元の文字列に戻した時、変換の仕方で文字化けするものとしないものがあります。
文字化けしない方法
(文字列→SHIFT_JIS →Unicode(スペース無し)→文字列)
r4() = StrConv("あいう\ku予定表", vbFromUnicode)
r5() = StrConv(CStr(r4()), vbUnicode)
mozi = CStr(r5())

文字化けする方法
(文字列 →Unicode(スペース有り)→Unicode(スペース無し)→文字列)
r6() = StrConv("あいう\ku予定表", vbUnicode)
r7() = StrConv(CStr(r6()), vbFromUnicode)
mozi = CStr(r7())

ここで謎なのはr5とr7は全く同じ配列なのに
CStrをかけて文字列に変換すると違う結果が得られることです。

これは一体なぜなのでしょうか?

質問者からの補足コメント

  • 詳しく調べてくださりありがとうございます。
    非常に納得しました。

    No.1の回答に寄せられた補足コメントです。 補足日時:2015/11/01 15:10

A 回答 (1件)

気になったの体系的に変換後のByte列を確認してみました。


まず前提としてプログラムソース上に書かれた文字列(例:"あいうえお")はUnicodeであって、cp932(sjis)ではありません。(プログラムaaa()のr0より)

確認結果は以下の様になりました。

 変換方法    変換元文字  変換後
1.vbFromUnicode  Unicode    cp932(sjis)
2.vbFromUnicode  異常Unicode  Unicode
3.vbFromUnicode  cp932     3Fの連なり(異常)

4.vbUnicode    Unicode    異常Unicode
5.vbUnicode    異常Unicode  異常Unicode(0が更に追加される)
6.vbUnicode    cp932     Unicode

 ※異常Unicodeとは、0が間に挟まる文字列です。


1番と6番が変換方法と変換前の文字コードが適合している正常な使用方法で結果も正常となります。
その他は変換方法と変換前の文字コードが適合していない誤った使用方法となり、結果は正常なものではありません。2番は変換結果がUnicodeとなって一見正常と見えますが誤った使用方法です。


ご質問後半ですが
r6()の変換が誤った変換(Unicode文字列をvbUnicodeで変換)を行っているため結果が正常にならないのだと思います。



※下記で、StrConv()の第一引数をCStr()で囲んでいないのは、無くても結果が変わらなかったので省略したためです。

Option Explicit

Sub msg(ByVal str As String, ByRef a() As Byte)
Dim s As String
Dim i As Integer
Dim v() As String

s = str & "= "
ReDim v(UBound(a()))
For i = 0 To UBound(a())
v(i) = Hex(a(i))
Next
MsgBox s & Join(v())
Range("a1") = s & Join(v())
End Sub

Sub aaa()
Dim r0() As Byte
Dim r1() As Byte
Dim r2() As Byte
Dim r3() As Byte
Dim r4() As Byte
Dim r5() As Byte
Dim r6() As Byte

r0() = "あいうえお"
Call msg("r0", r0()) '42,30 ~ 4A,30 プログラムソース上の文字列はUnicode

r1() = StrConv("あいうえお", vbFromUnicode)
Call msg("r1", r1()) '82,A0 ~ 82,A8 vbFomUnicode(Unicode)はcp932へ正常変換

r2() = StrConv("あいうえお", vbUnicode)
Call msg("r2", r2()) '42,0,30,0 ~ 4A,0,30,0 vbUnicode(Unicode)は異常Unicodeへ異常変換(0が挟まる)

r3() = StrConv(r1(), vbUnicode)
Call msg("r3", r3()) '42,0,30,0 ~ 4A,0,30,0 vbUnicode(cp932)は異常Unicodeへ異常変換(0が挟まる)

r4() = StrConv(r1(), vbFromUnicode)
Call msg("r4", r4()) '3F ~ 3F vbFromUnicode(cp932)は異常変換

r5() = StrConv(r2(), vbFromUnicode)
Call msg("r5", r5()) '42,30 ~ 4A,30 vbFromUnicode(異常Unicode)はUnicodeへ正常変換(見た目)

r6() = StrConv(r2(), vbUnicode)
Call msg("r6", r6()) '42,0,0,0,30 ~ 4A,0,0,0,30 vbUnicode(異常Unicode)は更に異常Unicodeへ変換

End Sub

Sub bbb()
Dim r4() As Byte
Dim r5() As Byte
Dim r6() As Byte
Dim r7() As Byte

r4() = StrConv("あいう\ku予定表", vbFromUnicode)
r5() = StrConv(CStr(r4()), vbUnicode)
Call msg("r5", r5()) 'r5= 42 30 44 30 46 30 5C 0 6B 0 75 0 88 4E 9A 5B 68 88


r6() = StrConv("あいう\ku予定表", vbUnicode)
r7() = StrConv(CStr(r6()), vbFromUnicode)
Call msg("r7", r7()) 'r7= 42 30 44 30 46 30 5C 0 6B 0 75 0 81 45 9A 5B 68 81 45

End Sub
この回答への補足あり
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!