1

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!

ErocM
  • 4,505
  • 24
  • 94
  • 161
  • fwiw, even if the data loaded I would expect the `report.AppendLine($"[{currentrow}]")` code to always result in `System.String[]`, since arrays always fall back to the basic `Object.ToString()` overload. – Joel Coehoorn Aug 20 '19 at 19:04
  • From the documentation for [TextFieldParser.ErrorLine Property](https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.fileio.textfieldparser.errorline?view=netframework-4.8), "Returns the line that caused the most recent MalformedLineException exception.". – TnTinMn Aug 21 '19 at 02:33

2 Answers2

0

I did not get a compile error on MyReader.SetDelimiters(",") but I changed it to an array anyway. The report.AppendLine($"[{currentrow}]") line probably doesn't expect an array. That line I altered to provide a string.

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim currentRow As String() = Nothing
    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($"[{String.Join(",", currentRow)}]")
                report.AppendLine("- record is malformed and will be skipped. ")
                Continue While
            End Try
        End While
    End Using
End Sub

EDIT

As per comments by @ Joel Coehoorn and @ ErocM if the row is null you could provide the content of the previous row so they errant row could be located.

        Dim LastGoodRow As String()
        While Not MyReader.EndOfData
            Try
                currentRow = MyReader.ReadFields()
                ImportLine(currentRow)
                LastGoodRow = currentRow
            Catch ex As FileIO.MalformedLineException
                report.AppendLine()
                report.AppendLine($"[{String.Join(",", LastGoodRow)}]")
                report.AppendLine("- record following this row is malformed and will be skipped. ")
                Continue While
            End Try
        End While
Mary
  • 14,926
  • 3
  • 18
  • 27
  • I think this misses the point of the question. The `AppendLine()` code is in the exception handler, meaning something went wrong and the data in `currentRow` variable is not correct. – Joel Coehoorn Aug 20 '19 at 19:07
  • @JoelCoehoorn I thought the question was about the Exception handler. "How do I output this record if it failed to parse the record?" – Mary Aug 20 '19 at 19:10
  • @JoelCoehoorn what Joel said. The currentRow is null at the exception point and I have no row to display to the customer. – ErocM Aug 20 '19 at 19:10
0

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).

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794