vb.netcsvtextfieldparser

FileIO.TextFieldParser get unaltered row for reporting on failed parse


I want to output the current row if there is an error but I'm getting a message that the current record is nothing.

Here is my code:

Dim currentRow As String()
Using MyReader As New FileIO.TextFieldParser(filenametoimport)
  MyReader.TextFieldType = FileIO.FieldType.Delimited
  MyReader.SetDelimiters(",")

  While Not MyReader.EndOfData
    Try
      currentRow = MyReader.ReadFields()
      ImportLine(currentRow)
    Catch ex As FileIO.MalformedLineException
      report.AppendLine()
      report.AppendLine($"[{currentrow}]")
      report.AppendLine("- record is malformed and will be skipped. ")
      Continue While
    End Try
  End While
end Using

I need to output the currentrow so that I can report to the user that there was a bad record.

report.AppendLine($"[{currentrow}]")

I understand that the value would be null if the parse failed but is there a way to get the current record?

How do I output this record if it failed to parse the record?

Thanks for the assistance!


Solution

  • You can't get the raw data directly in the exception, but you can at least get the line number where the error occurred. You may be able to use that line number to go back and find the offending record:

    Dim currentRow As String()
    Using MyReader As New FileIO.TextFieldParser(filenametoimport)
      MyReader.TextFieldType = FileIO.FieldType.Delimited
      MyReader.SetDelimiters(",")
    
      While Not MyReader.EndOfData
        Try
          currentRow = MyReader.ReadFields()
          ImportLine(currentRow)
        Catch ex As FileIO.MalformedLineException
          report.AppendLine($"{vbCrLf}- record at line {ex.LineNumber} is malformed and will be skipped. ")
        End Try
      End While
    End Using
    

    TextFieldParser also provides access to the underlying stream, and provides a ReadLine() method, so if you're really desparate to write the code you could walk back the stream to the previous line ending and then call MyReader.ReadLine() to get the record (which would in turn advance the stream again to where you expect).