So I have written (cobbled) together a program that takes a .CSV file and injects that into a database. The issue I'm running into is that the weekly report has a missing delimiter from the last row at the end. (This data can not be modified, except manually). I need to able to add the delimiter to the end of the last row to avoid the continual "MalformedLineException" I keep getting and the missing last row. Would love some help and advice.
Private Sub subProcessFile(ByVal strFileName As String)
'This is the file location for the CSV File
Using TextFileReader As New Microsoft.VisualBasic.FileIO.TextFieldParser(strFileName)
'removing the delimiter
TextFileReader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
TextFileReader.SetDelimiters(",")
ProgressBar1.Value = 0
Application.DoEvents()
'variables
Dim TextFileTable As DataTable = Nothing
Dim Column As DataColumn
Dim Row As DataRow
Dim UpperBound As Int32
Dim ColumnCount As Int32
Dim CurrentRow As String()
'Loop To read in data from CSV
While Not TextFileReader.EndOfData
Try
CurrentRow = TextFileReader.ReadFields()
If Not CurrentRow Is Nothing Then
''# Check if DataTable has been created
If TextFileTable Is Nothing Then
TextFileTable = New DataTable("TextFileTable")
''# Get number of columns
UpperBound = CurrentRow.GetUpperBound(0)
''# Create new DataTable
For ColumnCount = 0 To UpperBound
Column = New DataColumn()
Column.DataType = System.Type.GetType("System.String")
Column.ColumnName = "Column" & ColumnCount
Column.Caption = "Column" & ColumnCount
Column.ReadOnly = True
Column.Unique = False
TextFileTable.Columns.Add(Column)
ProgressBar1.Value = 25
Application.DoEvents()
Next
clsDeletePipeLineData.main()
End If
Row = TextFileTable.NewRow
'Dim Rownum As Double = Row
'If Rownum >= 1715 Then
' MsgBox(Row)
'End If
For ColumnCount = 0 To UpperBound
Row("Column" & ColumnCount) = CurrentRow(ColumnCount).ToString
Next
TextFileTable.Rows.Add(Row)
clsInsertPipeLineData.main(CurrentRow(0).ToString, CurrentRow(1).ToString, CurrentRow(2).ToString, CurrentRow(3).ToString, CurrentRow(4).ToString, CurrentRow(5).ToString, CurrentRow(6).ToString, CurrentRow(7).ToString, CurrentRow(9).ToString)
ProgressBar1.Value = 50
Application.DoEvents()
End If
Catch ex As _
Microsoft.VisualBasic.FileIO.MalformedLineException
MsgBox("Line " & ex.Message &
"is not valid and will be skipped.")
End Try
End While
ProgressBar1.Value = 100
Application.DoEvents()
clsMailConfirmation.main()
TextFileReader.Dispose()
MessageBox.Show("The process has been completed successfully")
End Using
A good example of data would be:
"1","£10","Joe Bloggs"
a bad example of data would be:
"2","£50","Jane Smith
Thanks in advance!
You could use File.AppendAllText(strFileName, """")
on the line before the Using ...
if it consisently lacks the closing "
, otherwise you might want to check the last character of the file first, to make it a little more robust.
While I'm looking at the code, there are perhaps some alterations that could be useful:
clsDeletePipeLineData.main()
seems to only be called for the first time round in the loop, so a "flag variable" can be used to determine if it should be called. currentRow(9).ToString()
, and give some details in the error message.subProcessFile
to give feedback to the user.The first of those changes could make it fast enough that there is no need for a progress bar - perhaps setting the cursor to a wait cursor before calling the method and resetting it afterwards would give sufficient feedback. Using Application.DoEvents can make things go wrong in unexpected ways, so if it really does need a progress report then look into using a BackgroundWorker or an Async method as shown in C# in How to do progress reporting using Async/Await .
Option Infer On
Option Strict On
Imports Microsoft.VisualBasic.FileIO
Imports System.IO
' other code...
Private Sub subProcessFile(ByVal csvFilename As String)
' The CSV files are faulty because of a missing final double-quote. Add it.
File.AppendAllText(csvFilename, """")
Dim expectedCsvColumnCount = 10
Using TextFileReader As New TextFieldParser(csvFilename) With {
.TextFieldType = FieldType.Delimited,
.Delimiters = {","},
.HasFieldsEnclosedInQuotes = True}
Dim lineNo = 0
Dim firstRow = True
While Not TextFileReader.EndOfData
Try
lineNo += 1
Dim currentRow = TextFileReader.ReadFields()
If currentRow IsNot Nothing Then
If firstRow Then
clsDeletePipeLineData.main()
firstRow = False
End If
If currentRow.Count = expectedCsvColumnCount Then
clsInsertPipeLineData.main(currentRow(0).ToString(), currentRow(1).ToString(), currentRow(2).ToString(), currentRow(3).ToString(), currentRow(4).ToString(), currentRow(5).ToString(), currentRow(6).ToString(), currentRow(7).ToString(), currentRow(9).ToString())
Else
Dim errMsg = String.Format("Wrong number of columns (expected {0}, found {1}) at line {2} in file ""{3}"".", expectedCsvColumnCount, currentRow.Count, lineNo, csvFilename)
Throw New InvalidDataException(errMsg)
End If
End If
Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
MsgBox("Line " & ex.Message & " is not valid and will be skipped.")
End Try
End While
clsMailConfirmation.main()
End Using
End Sub
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.