tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板
VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板
[ツリー表示へ]  [ワード検索]  [Home]

タイトル Re^9: VB6 上で表示化け
投稿日: 2018/10/16(Tue) 23:49
投稿者魔界の仮面弁士
> 入力は Excel で入力し、CSV で出力するという流れで作成していました。
> 日本語と英語の時は、これで良かったのですが、
> 取り急ぎ韓国語も同じやり方で作成したのですが、これが間違いの元でした。

多言語ファイルを、UTF-8(UTF-16 でも可)な CSV ファイルとして
保持しているのであれば、それは特に間違っていないと思います。
しかし、Shift_JIS な CSV だとしたら NG です。

※ Excel 2016 の場合、2016 年 10 月の機能更新によって、xlCSVUTF8 すなわち
  『CSV UTF-8 (カンマ区切り) (*.csv)』形式での保存がサポートされています。


> Line Input # で読み込んでいます。
> 読み込んだ1行分の文字列を "," で区切って読み込む処理をしています。

問題はここ。多言語ファイルを Line Input # で読み取ってはいけません。

Line Input # は、既定のコードページで読み込むための物なので、
たとえば、Latin-1 な英語ファイルを日本語環境で Line Input # するのさえ NG です。

UTF-8 を対象とするなら、ADODB.Stream を使うようにしてみてください。
また、UTF-16 の場合は Scripting.TextStream を使うこともできます。


''Microsoft ActiveX Data Object を参照設定している場合
'Dim stm As ADODB.Stream
'Set stm = New ADODB.Stream
'
''追加の参照設定を含めていない場合
Dim stm As Object
Set stm = CreateObject("ADODB.Stream")


stm.Charset = "UTF-8"
stm.Open

'このファイルは UTF-8 で保存された CSV ファイルであることを前提としている。
stm.LoadFromFile "C:\path\utf8.csv"


Dim strAllText As String
'strThreeCharacter = stm.ReadText(3)  '文字数(Long値)を渡すと、指定した文字数だけ読み取り
'strSingleLine = stm.ReadText(-2)     'adReadLine(-2)を渡すと、1 行ずつ読み取り
strAllText = stm.ReadText(-1)         'adReadAll(-1)を渡すと、すべてのテキストをまとめて読み取り

stm.Close


' 先頭に Byte Order Mark があれば取り除く。
' 通常は自動判定で取り除かれるはずだが念のため。
If Left(strAllText, 1) = ChrW(&HFEFF) Then
  strAllText = Mid(strAllText, 2)
End If


'CR改行、LF改行、CRLF改行が混在していた場合に、「CRLF改行」に統一する場合はこれを実行。
strAllText = Replace(Replace(Replace(strAllText, vbCrLf, vbLf), vbCr, vbLf), vbLf, vbCrLf)
'ただしセル内改行された Excel 製 CSV などの場合は、セル内改行(LF)とレコード区切り(CRLF)が
'区別されているので、上記の置換処理を行ってはいけない。


'改行とカンマごとに Split で区切って、csv(rowIndex)(colIndex) 形式のジャグ配列に変換する処理
Dim csv As Variant

Dim rows As Object, cols As Object
Set rows = CreateObject("Scripting.Dictionary")
Set cols = CreateObject("Scripting.Dictionary")
Dim vntRow As Variant, vntCol As Variant
For Each vntRow In Split(strAllText, vbCrLf, -1, vbBinaryCompare)  'vbBinaryCompare を忘れずに
    If vntRow <> "" Then
        cols.RemoveAll
        For Each vntCol In Split(vntRow, ",", -1, vbBinaryCompare)  'vbBinaryCompare を忘れずに
            cols.Add "C" & CStr(cols.Count), vntCol
        Next
        rows.Add "R" & CStr(rows.Count), cols.Items()
    End If
Next
csv = rows.Items()
Set rows = Nothing
Set cols = Nothing


'--- 以下確認処理:配列を列挙して内容を一行ずつ表示 ---
Dim varCell As Variant, varLine As Variant
Dim strLine As String, result As VbMsgBoxResult

'  Debug.Print や MsgBox は Unicode 非対応のため、これだと確認できない
For Each varLine In csv
    '表示用に、各列を「◆」で再結合
    strLine = Join(varLine, "◆")
    result = MsgBox(strLine, vbInformation Or vbOKCancel, "MsgBox だと化ける")
    If result = vbCancel Then Exit For  'キャンセルされたら列挙終了
    
    '同じ内容を Debug.Print で出力
    For Each varCell In varLine
        Debug.Print varCell,
    Next
    Debug.Print
Next


'  WshShell.Popup メソッドは Unicode を表示できる
Dim wshShell As Object
Set wshShell = CreateObject("WScript.Shell")
For Each varLine In csv
    '表示用に、各列を「◆」で再結合
    strLine = Join(varLine, "◆")
    result = wshShell.Popup(strLine, 0, "WshShell.Popup なら化けない", vbInformation Or vbOkCancel)
    If result = vbCancel Then Exit For  'キャンセルされたら列挙終了
Next

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。