tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルテキストファイルのUNICODE変換
記事No8409
投稿日: 2008/11/11(Tue) 17:39
投稿者まつ
いつもおせわになっております。
VB2005 Vistaで開発しております。

テキストファイルをデータテーブルに取り込み、
DataGridViewに表示する事を試みております。

【テキストファイルの中身】
ハイフンなしの郵便番号,氏名(漢字)


【プログラムソース】
        Dim Dt As New DataTable
        Dim Row As DataRow

        Dt.Columns.Add("郵便番号", Type.GetType("System.String"))
        Dt.Columns.Add("氏名", Type.GetType("System.String"))

        ''カンマ区切りテキストを読み込み、データテーブルに追加
        Dim parser As TextFieldParser
        parser = My.Computer.FileSystem.OpenTextFieldParser( _
                                        TextBox1.Text, ",")
        While Not parser.EndOfData
            Row = Dt.NewRow
            Row.ItemArray = parser.ReadFields

      *****

            Dt.Rows.Add(Row)
        End While
        Call parser.Close()

        DataGridView1.DataSource = Dt


郵便番号は正しく表示されるのですが、漢字氏名が文字化けして表示されてしまいます。
恐らく上記ソースの中の*****の部分でRow.ItemArray(1)を
Unicodeの変換をしなくてはならないかと思い、
            Dim shiftjis As System.Text.Encoding = System.Text.Encoding.GetEncoding("Shift-JIS")
            Dim unicode As System.Text.Encoding = System.Text.Encoding.UTF8
            Dim sjBytes As Byte() = shiftjis.GetBytes(Row.ItemArray(1))
            Dim ucBytes As Byte() = System.Text.Encoding.Convert(shiftjis, unicode, sjBytes)

上記コードを作成しましたが文字化けのままでした。
どうしても解決方法が分からず投稿させていただきました。

お忙しい中とは存じますがお分かりになる方がいらっしゃいましたら
ご教授をお願いできないでしょうか。

[ツリー表示へ]
タイトルRe: テキストファイルのUNICODE変換
記事No8410
投稿日: 2008/11/11(Tue) 20:32
投稿者魔界の仮面弁士
> テキストファイルのUNICODE変換
そもそも、元ファイルの文字コードは何でしょうか?

> Dim parser As TextFieldParser
> parser = My.Computer.FileSystem.OpenTextFieldParser( _
>                                         TextBox1.Text, ",")
上記コードの場合、
 ・ASCII/英数字のみ
 ・UTF-8(BOMあり)
 ・UTF-8(BOMなし)
 ・UTF-16(BOMあり)
などのファイルは扱えるようですが、たとえば
 ・Shift_JIS(日本語を含む)
 ・UTF-16(BOMなし)
などの場合には使えないようです。


> Unicodeの変換をしなくてはならないかと思い、
化けないようにするためには、String として読み込む前に、元ファイルそのものを
変換しておいてください。
化けて取得した String を変換しようとしても、それは破損が進むだけです。


すなわち OpenTextFieldParser を使って処理するのであれば、事前に元ファイルを
 1) ReadAllBytes で Byte 配列に読み込んでおく。
 2) それを System.Text.Encoding.GetEncoding(文字コード).GetString にて
   String に変換。
 3) 変換結果を WriteAllText で UTF-8 ファイルとして保存。
 4) 保存しなおしたファイルを、OpenTextFieldParser で読み直す。
といった手順になるかと思います。


ファイル変換を行いたくないのであれば、OpenTextFieldParser を使うのは諦めて、
ReadAllText 等で元ファイルを直接読み取り、それを Split して切り出すようにするとか。

[ツリー表示へ]
タイトルRe^2: テキストファイルのUNICODE変換
記事No8411
投稿日: 2008/11/11(Tue) 23:23
投稿者Hongliang
> ファイル変換を行いたくないのであれば、OpenTextFieldParser を使うのは諦めて、
> ReadAllText 等で元ファイルを直接読み取り、それを Split して切り出すようにするとか。

TextFieldParser コンストラクタには TextReader や Stream & Encoding も渡せるので、わざわざファイル変換する必要はないでしょう。
FileStream 作って Encoding.GetEncoding で取得した Shift_JIS(多分)の Encoding とともに New TextFieldParser の引数に渡せばいいかと。

[ツリー表示へ]
タイトル重複行の削除  テキストファイルのUNICODE変換
記事No8414
投稿日: 2008/11/12(Wed) 14:11
投稿者まつ
魔界の仮面弁士様 Honglian様
ご丁寧な回答を有難うございます。

そもそも読み込んだときからコードが壊れているとは思いもよりませんでした。

Paserの箇所を以下のように記述し解決いたしました。

            Dim parser As New TextFieldParser(TextBox1.Text, _
                System.Text.Encoding.GetEncoding("Shift_JIS"))

            parser.TextFieldType = FieldType.Delimited
            parser.SetDelimiters(",") ' 区切り文字はコンマ

ところでこのDataGridViewはテーブルにリンクしていないので、
重複行を削除する場合はどのようにしたら良いでしょうか。
テーブルにリンクであればSelect Distinctを使うのですが。

検索などはBindingSourceのFilterを使い上手くいきましたが
重複の削除がどうしてもわかりません。

[ツリー表示へ]
タイトルRe: 重複行の削除  テキストファイルのUNICODE変換
記事No8415
投稿日: 2008/11/13(Thu) 11:09
投稿者魔界の仮面弁士
>> ファイル変換を行いたくないのであれば、OpenTextFieldParser を使うのは諦めて、
> TextFieldParser コンストラクタには TextReader や Stream & Encoding も渡せるので、

おぉーぅ。TextFieldParser に Public コンストラクタがあったのか…。

OpenTextFieldParser / TextFieldParser を使った事が無いので気付いていませんでした。
御指摘ありがとうございます。


> ところでこのDataGridViewはテーブルにリンクしていないので、
ん? DataTable にデータバインドさせているように見えますけれども。。。

> 重複行を削除する場合はどのようにしたら良いでしょうか。

自身でループさせて削除する(または、DataTable.Add 時に重複チェックする)といった
方法ぐらいしか思いつきませんでした…。

Public Sub DictinctRow(ByVal tbl As DataTable)
 Dim dv As New DataView(tbl)
 Dim cols As New List(Of String)()
 For Each col As DataColumn In tbl.Columns
  cols.Add(col.ColumnName)
 Next
 dv.Sort = String.Join(",", cols.ToArray())

 Dim preRow As String = Nothing
 For r As Integer = dv.Count - 1 To 0 Step -1
  Dim s As String = Join(dv(r).Row.ItemArray, vbNullChar)
  If preRow = s Then
   With dv(r).Row
    .Delete()
    If .RowState = DataRowState.Deleted Then
     .AcceptChanges()
    End If
   End With
  Else
   preRow = s
  End If
 Next
End Sub

[ツリー表示へ]
タイトルRe^2: 重複行の削除  テキストファイルのUNICODE変換
記事No8417
投稿日: 2008/11/16(Sun) 01:37
投稿者まつ
魔界の仮面弁士様
いつもありがとうございます。

今回もサンプルソースまでご教授下さり、
誠に有難うございます。

[ツリー表示へ]