Linq - Index超出了数组的范围

时间:2012-02-06 15:44:51

标签: .net vb.net linq csv

我目前有一个使用Linq读取CSV文件的程序。一切都工作得很好,直到最近的一次更改,其中CSV文件已添加记录,其中最后2列为空。

所以,我现在得到的错误是Index超出了数组的范围。我的问题是如何处理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

2 个答案:

答案 0 :(得分:1)

这最终成为可行的替代解决方案。我在这里发布了所有列,所以它可能有点长。希望这有助于有人在路上。

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 :(得分:0)

你可以简单地使用

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

通过它添加两个空条目添加每行的结尾。对于包含6个条目的行,它们会被忽略,对于包含4个条目的行,它们会添加两个空条目,因此data(4)data(5)不会超出范围。

这会使RemitterName和InvoiceNumber为空字符串。我假设当最后两列不存在时会发生这种情况。