Linq - インデックスが配列の範囲外にありました

私は現在Linqを使ってCSVファイルを読むプログラムを持っています。最近の変更が行われるまで、CSVファイルにレコードが追加されていたところで、最後の2つの列が空の場所まで、すべてがうまくいっていました。

だから、私が今得ているエラーは、インデックスが配列の境界の外側にあることです。私が持っている質問は、CSVファイルに空の値またはヌル値が設定されている列をどのように処理するのですか?

以下に私の短縮コードを示します。事前に助けてくれてありがとう。

Function readLINQ(ByVal strCustomerFile As String) As DataTable

    Dim readlines = File.ReadAllLines(strCustomerFile)
    File.WriteAllLines(strCustomerFile, readlines.Skip(4).ToArray())

    Dim gTable As New DataTable("CashFile")
    With gTable
        .Columns.Add("Num").DataType = GetType(System.String)
        .Columns.Add("EnvNum").DataType = GetType(System.String)
        .Columns.Add("TransNum").DataType = GetType(System.String)
        .Columns.Add("Envelope").DataType = GetType(System.String)
        .Columns.Add("RemitterName").DataType = GetType(System.String)
        .Columns.Add("InvoiceNumber").DataType = GetType(System.String)

    End With
    Dim lines As String() = System.IO.File.ReadAllLines(strCustomerFile)
    Dim pattern As String = ",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))"



    Dim r As System.Text.RegularExpressions.Regex = New System.Text.RegularExpressions.Regex(pattern)
    Dim custs = From line In lines Where line <> header AndAlso Not String.IsNullOrEmpty(line)
                Let data = r.Split(line)
                Select New With {.Num = data(0), .EnvNum = data(1), .TransNum = data(2), .Envelope = data(3), .RemitterName = data(4), .InvoiceNumber = data(5)}

    Dim xRow As DataRow
    For Each row In custs
        xRow = gTable.NewRow()
        xRow.ItemArray = {row.Num, row.EnvNum, row.TransNum, row.Envelope, _
                          row.RemitterName, row.InvoiceNumber}

        gTable.Rows.Add(xRow)
    Next

    readlines = Nothing
    lines = Nothing

    Return gTable
End Function
0
Microsoft.VisualBasic.FileIO.TextFieldParser クラスを見たことがありますか?
追加された 著者 Daniel A. White,
まず、そのクラスについて聞いたことがあります。私は有望に見える何かを今見ている。しかし、私はすべての情報を個別に広げるのではなく、1つの列に詰め込んでいます。
追加された 著者 user1143550,
Microsoft.VisualBasic.FileIO.TextFieldParser(strcustomerfile&zwnj;)parser.SetDelimiters( "、")Not parser.EndOfData gTable.Rows.Add(parser.ReadLine())End Using End Using
追加された 著者 user1143550,

2 答え

これが実行可能な代替ソリューションになったのです。私はここにすべての列を掲示したので、少し長いかもしれません。この道が誰かを助けることを願っています。

Function TextFieldReadCSV(ByVal strCustomerFile As String) As DataTable

    'need to skip 4 lines
    Dim readlines = File.ReadAllLines(strCustomerFile)
    File.WriteAllLines(strcustomerfile, readlines.Skip(4).ToArray())

    Dim gTable As New DataTable("CashFile")
    With gTable
        .Columns.Add("Num").DataType = GetType(System.String)
        .Columns.Add("EnvNum").DataType = GetType(System.String)
        .Columns.Add("TransNum").DataType = GetType(System.String)
        .Columns.Add("Envelope").DataType = GetType(System.String)
        .Columns.Add("TID").DataType = GetType(System.String)
        .Columns.Add("TransUID").DataType = GetType(System.String)
        .Columns.Add("Lockbox").DataType = GetType(System.String)
        .Columns.Add("Date").DataType = GetType(System.String)
        .Columns.Add("Time").DataType = GetType(System.String)
        .Columns.Add("Batch").DataType = GetType(System.String)
        .Columns.Add("BatchItem").DataType = GetType(System.String)
        .Columns.Add("TransSource").DataType = GetType(System.String)
        .Columns.Add("Group").DataType = GetType(System.String)
        .Columns.Add("GroupName").DataType = GetType(System.String)
        .Columns.Add("Amount").DataType = GetType(System.String)
        .Columns.Add("ABART").DataType = GetType(System.String)
        .Columns.Add("AccountNum").DataType = GetType(System.String)
        .Columns.Add("CheckNum").DataType = GetType(System.String)
        .Columns.Add("NumImages").DataType = GetType(System.String)
        .Columns.Add("CheckImage").DataType = GetType(System.String)
        .Columns.Add("CheckBack").DataType = GetType(System.String)
        .Columns.Add("EnvelopeImage").DataType = GetType(System.String)
        .Columns.Add("EnvelopeBack").DataType = GetType(System.String)
        .Columns.Add("InvoiceImage").DataType = GetType(System.String)
        .Columns.Add("InvoiceBack").DataType = GetType(System.String)
        .Columns.Add("AllPageImages").DataType = GetType(System.String)
        .Columns.Add("AllPageBack").DataType = GetType(System.String)
        .Columns.Add("RemitterName").DataType = GetType(System.String)
        .Columns.Add("InvoiceNumber").DataType = GetType(System.String)

    End With

    Using MyReader As New Microsoft.VisualBasic.FileIO.TextFieldParser(strCustomerFile)
        MyReader.TextFieldType = FileIO.FieldType.Delimited
        MyReader.SetDelimiters(",")
        Dim currentRow As String()
        While Not MyReader.EndOfData

            currentRow = MyReader.ReadFields()
            Dim currentField As String

            Dim FieldArray(28) As String
            Dim i = 0
            For Each currentField In currentRow
                FieldArray(i) = currentField
                i = i + 1
            Next

            Dim xRow As DataRow

            xRow = gTable.NewRow()
            xRow.ItemArray = {FieldArray(0), FieldArray(1), FieldArray(2), FieldArray(3), FieldArray(4), FieldArray(5), FieldArray(6), FieldArray(7), _
                              FieldArray(8), FieldArray(9), FieldArray(10), FieldArray(11), FieldArray(12), FieldArray(13), FieldArray(14), FieldArray(15), _
                              FieldArray(16), FieldArray(17), FieldArray(18), FieldArray(19), FieldArray(20), FieldArray(21), FieldArray(22), _
                              FieldArray(23), FieldArray(24), FieldArray(25), FieldArray(26), FieldArray(27), FieldArray(28)}

            gTable.Rows.Add(xRow)

        End While
    End Using

    Return gTable
End Function
1
追加された
私のプログラムが、csvファイルを取得しなければならない抽出されたzipファイルを削除してクリーンアップ作業をしていたときに、TextFieldParserクラスの使用に関する問題が発生しました。上記のコードは、MyReader.Close()とMyReader.Dispose()を追加した場所を反映していません... "ディレクトリは空ではありません"という抽出されたフォルダを削除しようとしてもエラーになります。私はそのエラーを他の方法でテストしたことがあります.LINQはそれが不合理である唯一のものと思われます。
追加された 著者 user1143550,

あなたは単に使用することができます

Let data = r.Split(line + ",,")

2つの空のエントリを追加して各行の末尾を追加します。 6つのエントリを持つ行では無視され、4つのエントリでは2つの空のエントリが追加されるため、 data(4)および data(5)は範囲外ではありません。

これにより、RemitterNameとInvoiceNumberが空の文字列になります。私はそれが最後の2つの列がないときに起こるはずであると仮定します。

0
追加された
それが私が目指していたものです。しかし、とにかく、 TextFieldParser はより強固なソリューションのように聞こえます。
追加された 著者 Gert Arnold,
この時点では混在したバッグです。すべての列に値がある20個のレコードがあります。しかし、最後の10レコードはRemitterNameとInvoiceNumberに何もない場所です。私は、Microsoft.VisualBasic.FileIO.TextFieldParserクラスを使用して実行可能なソリューションを得たと思います。
追加された 著者 user1143550,
Gert、私はちょうどあなたの先端のために感謝を言いたいと思った。 TextFieldParserで「ディレクトリが空ではありません」というエラーで新たな問題が発生したため、これをテストしました。私が扱っている.zipファイルから作成された抽出されたフォルダでプログラムがクリーンアップを行っているときのエラーです。私はこのエラーでハングアップしない唯一のものと思われるので、LINQで作業する必要があります。
追加された 著者 user1143550,