user1143550
user1143550

Reputation: 35

Linq - Index was outside the bounds of the array

I currently have a program that uses Linq to read a CSV file. Everything was working great until a recent change was done where the CSV file had records being added to it where the last 2 columns where empty.

So, the error I am getting now is Index was outside the bounds of the array. The question I have is how do I handle a column where an empty or null value is set in the CSV file?

Here's my abbreviated code below. Thanks for any help in advance.

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

Upvotes: 0

Views: 1561

Answers (2)

user1143550
user1143550

Reputation: 35

This is what ended up being a viable alternative solution. I posted all of the columns here so it may be a bit long. Hope this helps someone down the road.

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

Upvotes: 1

Gert Arnold
Gert Arnold

Reputation: 109185

You could simply use

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

by which you add two empty entries add the end of each line. They are ignored for lines with 6 entries and for lines with 4 entries they add two empty entries, so data(4) and data(5) are not out of bounds.

This causes RemitterName and InvoiceNumber to be empty strings. I assume that is what should happen when the last 2 columns are absent.

Upvotes: 0

Related Questions