タイトル | : Re^9: VB6 上で表示化け |
記事No | : 16469 |
投稿日 | : 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
|