1

CSVファイルを読み取ってデータテーブルを作成する小さなプログラムがあります。要件の 1 つは、コンマが引用符で囲まれている場合、コンマ (名前などのコンマ) を無視することです。例。

          Name, Age, Location
          "Henderson, David", 32, London
           John Smith, 19, Belfast

プログラムは Henderson の後のカンマを無視し、Henderson, David を 1 つのフィールドとして読み取る必要があります。私の現在のコードは、最後に余分な列を追加するこの仕事を行うことができません。どうすればそれを達成できますか?解決策は、引用符の間のコンマを置き換えるべきではありません。ありがとう。

私の現在のコード。

 Public Function BuildDataTable() As DataTable

    Dim myTable As DataTable = New DataTable("MyTable")
    Dim i As Integer
    Dim myRow As DataRow
    Dim fieldValues As String()        
    Dim myReader As StreamReader = New StreamReader(_fileFullPath, Encoding.GetEncoding("iso-8859-1"))

    Try           
        fieldValues = myReader.ReadLine().Split(_seperator)
        'Create data columns accordingly
        If _hasheader = False Then
            For i = 0 To fieldValues.Length() - 1
                myTable.Columns.Add(New DataColumn("Column(" & i & ")"))
            Next
        Else
            'if the file has header, take the first row as header for datatable
            For i = 0 To fieldValues.Length() - 1
                myTable.Columns.Add(New DataColumn(fieldValues(i).Replace(" ", "")))
            Next
        End If

        myRow = myTable.NewRow

        If _hasheader = False Then
            For i = 0 To fieldValues.Length() - 1
                myRow.Item(i) = fieldValues(i).ToString
            Next
            myTable.Rows.Add(myRow)
        End If

        While myReader.Peek() <> -1
            fieldValues = myReader.ReadLine().Split(_seperator)
            myRow = myTable.NewRow
            For i = 0 To fieldValues.Length() - 1
                myRow.Item(i) = fieldValues(i).Trim.ToString
            Next

            If Not csv2xml.AreAllColumnsEmpty(myRow) = True Then
                myTable.Rows.Add(myRow)
            End If

        End While
    Catch ex As Exception                   
    End Try     
End Function
4

2 に答える 2

3

CSV で二重引用符文字をテキスト修飾子として使用しようとしています。フィールドがテキスト修飾子文字で囲まれている場合、テキスト修飾子を使用すると、フィールド値にフィールド区切り文字を使用できます。

これを自分でプログラムすることはできますが、それは間違いです。これを行うことができる無料の有能な CSV パーサーがたくさんあります。TextFieldParserVisual Basic を使用しているため、 classを確認できます。

CSV の内容を DataTable に書き込むコードを記述する必要があります。

動作しているように見える以下を見つけました:
http://www.vbcode.com/asp/showsn.asp?theID=13645

もう 1 つのオプションは、GenericParsercodeproject.com にあります。この記事のコードが C# で書かれているという事実に悩まされないでください。プロジェクトで DLL (GenericParsing.dll) を参照し、VB で使用することができます。

このパーサーの優れた点は、CSV から DataTable を返すために使用できるメソッドが含まれていることです。サンプルデータで動作する例を次に示します。

Using parser As New GenericParsing.GenericParserAdapter(CSV_FILE_FULLNAME)
    parser.ColumnDelimiter = ","
    parser.TextQualifier = """"
    parser.FirstRowHasHeader = True
    Dim dt As DataTable = parser.GetDataTable()
End Using
于 2012-10-01T20:06:31.390 に答える
0

Split()Visual Basic には詳しくありませんが、関数を使用して行を分割するべきではないと思います。

fieldValues = myReader.ReadLine().Split(_seperator)    ' DO NOT do this

代わりに、各文字を 1 つずつ読み取る独自の分割関数を記述します。次に、二重引用符で囲まれているかどうかを記録するフラグを用意します。


アップデート

実行可能なコード スニペットを作成するには、VB や C# についてあまり知識がなくて申し訳ありません。この疑似コード (実際には JavaScript です) を読んでください...お役に立てば幸いです。

function split_with_quote(string, delimiter, quotation) {
    if (delimiter == null) delimiter = ',';
    if (quotation == null) quotation = '"';
    var in_quotation = false;
    var result = [];
    var part = '';
    for (var i = 0; i < string.length; i++) {
        var ch = string[i];
        if (ch == quotation)  in_quotation = !in_quotation;
        if (ch == delimiter && !in_quotation) {
            result.push(part);
            part = '';
        } else {
            if (ch != quotation) part += ch;
        }
    }
    return result;
}

a = 'abc,def,"ghi,jkl",123';
split_with_quote(a);    // ["abc", "def", "ghi,jkl"]
于 2012-10-01T15:48:48.973 に答える