メモリ上のUTF-8文字コードをShift-JISに変換するには?

解決


TRY  2006-08-28 01:32:01  No: 132935

こんばんは。初めて書き込みます。
メモリ上のUTF-8の文字をAccessVBAのレポート上に
表示したいのですが、以下の方法でShift-JISに変換
しても正しく変換できません。

変換したいUTF-8の文字:
E382AD E383A3 E38397 E382B7 E383A7 E383B3 E382AA E382B7 E383A0
”キャプション”

Public Function UTF8toSJis(strDst As String) As String

    Dim buff() As Byte
    Dim strTemp As String

    With New ADODB.Stream
        .Open
        .Type = adTypeBinary
        buff = strDst
        .Write buff
        
        .Position = 0
        .Type = adTypeText
        .Charset = "UTF-8"
        strTemp = .ReadText
        .Position = 0
        .SetEOS
        .Charset = "Shift_JIS"
        .WriteText strTemp
        .Position = 0
        .Type = adTypeBinary
        
        UTF8toSJis = .Read
        .Close
    End With

End Function

・引数strDstに変換したいUTF-8の文字を渡しています。
・この関数からの戻り値の文字列をそのままレポートに表示しています。

もしお判りになりましたらアドバイス頂けますでしょうか。
恐れ入りますが、何卒よろしくお願い致します。


Blue  2006-08-28 09:10:38  No: 132936

とりあえず、UTF-8の文字コードのものをString型変数に入れないほうがよさそうですけど。(Shift_JISのもそうだけど)

Sub test()
    Dim utf8(23) As Byte
    Dim sjis()   As Byte
    
    utf8(0) = &HE3: utf8(1) = &H82: utf8(2) = &HAD
    utf8(3) = &HE3: utf8(4) = &H83: utf8(5) = &HA3
    utf8(6) = &HE3: utf8(7) = &H83: utf8(8) = &H97
    utf8(9) = &HE3: utf8(10) = &H82: utf8(11) = &HB7
    utf8(12) = &HE3: utf8(13) = &H83: utf8(14) = &HB3
    utf8(15) = &HE3: utf8(16) = &H82: utf8(17) = &HAA
    utf8(18) = &HE3: utf8(19) = &H82: utf8(20) = &HB7
    utf8(21) = &HE3: utf8(22) = &H83: utf8(23) = &HA0
    sjis = UTF8toSJis(utf8)
    Debug.Print StrConv(sjis, vbUnicode)
End Sub

Public Function UTF8toSJis(ByRef bytDst() As Byte) As Byte()

    Dim uni As String
    'Dim bom(2) As Byte
    'bom(0) = &HEF: bom(1) = &HBB: bom(2) = &HBF
    
    ' UTF-8 -> UTF-16
    With New ADODB.Stream
        .Open
        .Type = adTypeBinary
        '.Write bom
        .Write bytDst
        
        .Position = 0
        .Type = adTypeText
        .Charset = "UTF-8"
        uni = .ReadText
        .Close
    End With
        
    ' UTF-16 -> Shift_JI(StrConv)
    With New ADODB.Stream
        .Open
        .Charset = "Shift_JIS"
        .Type = adTypeText
        .WriteText uni
        
        .Position = 0
        .Type = adTypeBinary
        UTF8toSJis = .Read
        
        .Close
    End With

End Function

ちなみに
>E382AD E383A3 E38397 E382B7 E383A7 E383B3 E382AA E382B7 E383A0
>”キャプション”
にはならないような。。。本当にUTF8なのかな?


魔界の仮面弁士  2006-08-28 09:57:42  No: 132937

レポートに渡すのであれば、Shift_JIS にしては不味いのでは?
VB/VBA 標準の String 型は、Unicode を前提としているはずですし。


Private Sub Command1_Click()
    Dim bin() As Byte
    bin = ToBinary("E382AD E383A3 E38397 E382B7 E383A7 E383B3 E382AA E382B7 E383A0")
    Text1.text = GetString(bin, "UTF-8")
End Sub

Public Function GetString(ByRef bin() As Byte, ByVal encoding As String) As String
    With New ADODB.Stream
        .Open
        .Type = adTypeBinary
        .Write bin
        .Position = 0
        .Type = adTypeText
        .Charset = encoding
        GetString = .ReadText(adReadAll)
        .Close
    End With
End Function

Public Function ToBinary(ByVal text As String) As Byte()
    With CreateObject("Microsoft.XMLDOM").createElement("bin")
        .DataType = "bin.hex"
        .text = text
        ToBinary = .NodeTypedValue
    End With
End Function


Blue  2006-08-28 10:04:08  No: 132938

私のヤツ1文字抜けてましたね、、、

>    With CreateObject("Microsoft.XMLDOM").createElement("bin")
>        .DataType = "bin.hex"
>        .text = text
>        ToBinary = .NodeTypedValue
>    End With
こんな方法があるんですね。勉強になりました。


TRY  2006-08-29 03:10:56  No: 132939

Blue さん、魔界の仮面弁士さん
レスありがとうございました。TRYです。
お返事が遅くなり申し訳ありません。

>とりあえず、UTF-8の文字コードのものをString型変数に入れないほうがよさそうですけど。(Shift_JISのもそうだけど)

blueさん、魔界の仮面弁士さんのサンプルソースを参考に
String型に入れないようにし、さらにShift-JIS変換を
しないようにしたら、関数の変換は正常に行うことが
できました。ありがとうございました。


>にはならないような。。。本当にUTF8なのかな?

UTF-8なんですけど、blueさんご指摘のとおり、”キャプション”
の文字列だけではなかったようです。お恥ずかしい限りです。
申し訳ございません。


>レポートに渡すのであれば、Shift_JIS にしては不味いのでは?
>VB/VBA 標準の String 型は、Unicode を前提としているはずですし。

はい。レポートに表示するにはunicodeなければならないようです。
関数の変換結果をレポートで表示する際、unicodeに変換することで
レポート上に正しく表示することができました。
ご指摘ありがとうございました。


>>    With CreateObject("Microsoft.XMLDOM").createElement("bin")
>>        .DataType = "bin.hex"
>>        .text = text
>>        ToBinary = .NodeTypedValue
>>    End With
>こんな方法があるんですね。勉強になりました。

ToBinary関数の中身はまったく知りませんでした。
勉強不足です。

新参者にもご丁寧にご回答頂き、大変嬉しく思っております。
本当にありがとうございました。今後ともよろしくお願い致します。


※作成する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。







   このエントリーをはてなブックマークに追加