How to Update CSV file not to Insert new Items using vb.net - vb.net

I want to Update row of CSV file I tried but I only found append which adds new row. where as I need to update row not to insert new row.
Here is data in my csv file
EnjoyBaseHid=hid://002AB1E3,MinID=1,MaxID=900
EnjoyBaseHid=hid://005AC1D4,MinID=1,MaxID=600
I want to update according to EnjoyBaseHid
While Not sr.EndOfStream
Dim line = sr.ReadLine()
Dim values() As String = line.Split(",")
If values(0).Equals("EnjoyBaseHid=" & portAddress) Then
Nobasefound = False
line = line.Replace(values(1), "MinID=" & minID)
line = line.Replace(values(2), "MaxID=" & maxID)
sr.Close()
Dim strWrite As New IO.StreamWriter(ExportListPathString, False)
strWrite.WriteLine(line)
strWrite.Close()
Exit While
End If
End While
This overwrites all file and the result is
EnjoyBaseHid=hid://005AC1D4,MinID=1,MaxID=1000
When I change following line
Dim strWrite As New IO.StreamWriter(ExportListPathString, False)
To this
Dim strWrite As New IO.StreamWriter(ExportListPathString, True)
It appends new line and result is following
EnjoyBaseHid=hid://002AB1E3,MinID=1,MaxID=900
EnjoyBaseHid=hid://005AC1D4,MinID=1,MaxID=600
EnjoyBaseHid=hid://005AC1D4,MinID=1,MaxID=1000
But I need this
EnjoyBaseHid=hid://002AB1E3,MinID=1,MaxID=900
EnjoyBaseHid=hid://005AC1D4,MinID=1,MaxID=1000

This is the idea I had in mind.
Private Sub fileHandler(sourceFile As String, portAddress As String, newMin As String, newMax As String)
Dim tempOutFileName As String = String.Concat(sourceFile, "_tmp")
Dim oldFileName As String = String.Concat(sourceFile, "_old")
'clear away temp file
If File.Exists(tempOutFileName) Then
File.Delete(tempOutFileName)
End If
'clear away old file
If File.Exists(oldFileName) Then
File.Delete(oldFileName)
End If
'open writer for new temp file
Using sw As StreamWriter = New StreamWriter(tempOutFileName, True)
'open reader for source file
Using sr As StreamReader = New StreamReader(sourceFile)
Do While sr.Peek <> -1
Dim line As String = sr.ReadLine
'check if the line read is the one you want to change
If line.Contains(portAddress) Then
'write your NEW line
sw.WriteLine(String.Concat(portAddress, "-", newMin, "-", newMax))
Else
'write the existing line without changes
sw.WriteLine(line)
End If
Loop
sr.Close()
End Using
sw.Close()
End Using
'backup source to old
File.Move(sourceFile, oldFileName)
'move temp to source
File.Move(tempOutFileName, sourceFile)
End Sub

Related

How to remove extra line feeds within double quoted fields

Newbie here. Code below removes ALL line feeds in my file but it also removes EOR line feeds. Can somebody please help me how to fix code below so it only removes extra line feeds within double quoted fields? Any help will be greatly appreciated. Thanks
Public Sub Main()
'
Dim objReader As IO.StreamReader
Dim contents As String
objReader = New IO.StreamReader("testfile.csv")
contents = objReader.ReadToEnd()
objReader.Close()
Dim objWriter As New System.IO.StreamWriter("testfile.csv")
MsgBox(contents)
'contents = Replace(contents, vbCr, "")
contents = Replace(contents, vbLf, "")
MsgBox(contents)
objWriter.Write(contents)
objWriter.Close()
'
Dts.TaskResult = ScriptResults.Success
End Sub
I forgot to mention that the input file name changes daily, How do I code so it doesn't care for the file name as long as it as a CSV file? So testfile name has current date and changes daily. I've tried just the file path and it errored out as well. Used the *.csv and it didnt like that either.
objReader = New IO.StreamReader("\FolderA\FolderB\TestFile09212022.csv")
If you are sure there are no double quotes text inside the double quotes you can do it like this:
Dim sNewString As String = ""
Dim s As String
Dim bFirstQuoted As Boolean = False
Dim i As Integer
Dim objWriter As New System.IO.StreamWriter("testfile.csv")
MsgBox(contents)
For i = 1 To contents.Length
s = Mid(contents, i, 1)
If s = """" Then bFirstQuoted = Not bFirstQuoted
If Not bFirstQuoted OrElse (s <> vbLf AndAlso bFirstQuoted) Then
sNewString += s
else
sNewString += " "
End If
Next
MsgBox(sNewString )
objWriter.Write(sNewString )
objWriter.Close()
Dts.TaskResult = ScriptResults.Success

An unhandled exception of type 'System.IndexOutOfRangeException' occurred in vb.net CSV program

This program is simply reading from a CSV and putting that into a DatagridView table. I am not sure what is causing the error shown below.
"An unhandled exception of type 'System.IndexOutOfRangeException' occurred in Minecraft Server Program.exe"
This error points to the line "newrow("Days_remaining") = columns(1)
Also, the CSV is formatted as such:
xX_EpicGamer_Xx,2,2/05/2021,9,6,Player was mean to others and stole lots of diamonds
pewdiepie,3,2/05/2021,4,2,Player swore
Thank you for any help
Public Sub LoadCSVFile()
'If the Input file cannot be found, then give error message And exit this Subroutine.
If Not File.Exists(BansCSVFile) Then
MsgBox("Input CSV File of Item Prices not found: " & BansCSVFile)
Exit Sub
End If
'Set up streamreader and variables for reading through file
Dim srdCSV As New IO.StreamReader("bans.csv", System.Text.Encoding.Default)
Dim sline As String = ""
Do
'Read through each line, separating with the comma and putting each entry into its respective column
sline = srdCSV.ReadLine
If sline Is Nothing Then Exit Do
Dim columns() As String = sline.Split(",")
Dim newrow As DataRow = datatable1.NewRow
newrow("Player") = columns(0)
newrow("Days_remaining") = columns(1)
newrow("Date_started") = columns(2)
newrow("Timespan") = columns(3)
newrow("Rule_broken") = columns(4)
newrow("Extra_info") = columns(5)
datatable1.Rows.Add(newrow)
Loop
srdCSV.Close()
dgvBans.DataSource = datatable1
Me.Text = datatable1.Rows.Count & "rows"
End Sub
Edit:
This new code fixed the issue.
Public Sub LoadCSVFile()
'If the Input file cannot be found, then give error message And exit this Subroutine.
If Not File.Exists(BansCSVFile) Then
MsgBox("Input CSV File of Item Prices not found: " & BansCSVFile)
Exit Sub
End If
'Set up streamreader and variables for reading through file
srdCSV = New IO.StreamReader("bans.csv")
Dim totalrec As Integer = 0
Try
Do Until srdCSV.Peek = -1
'Read through each line, separating with the comma and putting each entry into its respective column
strInputFileLine = srdCSV.ReadLine()
'Split CSV lines where commas are
Dim RecordLineColumns() As String = strInputFileLine.Split(",")
'Create a new row in data table and place data into it from array
Dim newrow As DataRow = datatable1.NewRow
newrow("Player") = RecordLineColumns(0)
newrow("Days_remaining") = RecordLineColumns(1)
newrow("Date_started") = RecordLineColumns(2)
newrow("Timespan") = RecordLineColumns(3)
newrow("Rule_broken") = RecordLineColumns(4)
newrow("Extra_info") = RecordLineColumns(5)
datatable1.Rows.Add(newrow)
totalrec = totalrec + 1
Loop
Catch ex As Exception
MsgBox("Error reading file")
Exit Sub
End Try
srdCSV.Close()
'Me.Text = datatable1.Rows.Count & "rows"
MsgBox("Total input records = " & totalrec)
End Sub
using the Try/Catch syntax
After checking which column has a problem, try verifying the csv file.
I am guessing that the Extra_Info is not necessarily present for every record. I am checking for a length less 5 and exiting but if it has at least 5 we continue but only fill in the last field if the length is 6.
Public Sub LoadCSVFile(BansCSVFile As String)
Dim datatable1 As New DataTable
With datatable1.Columns
.Add("Player")
.Add("Days_remaing")
.Add("Date_started")
.Add("Timespan")
.Add("Rule_broken")
.Add("Extra_Info")
End With
If Not File.Exists(BansCSVFile) Then
MsgBox("Input CSV File of Item Prices not found: " & BansCSVFile)
Exit Sub
End If
Dim lines = File.ReadAllLines(BansCSVFile)
For Each sline In lines
Dim columns() As String = sline.Split(","c)
If columns.Length < 5 Then
MessageBox.Show($"Incomplete data on line {sline}")
Return
End If
Dim newrow As DataRow = datatable1.NewRow
newrow("Player") = columns(0)
newrow("Days_remaining") = columns(1)
newrow("Date_started") = columns(2)
newrow("Timespan") = columns(3)
newrow("Rule_broken") = columns(4)
If columns.Length = 6 Then
newrow("Extra_info") = columns(5)
End If
datatable1.Rows.Add(newrow)
Next
dgvBans.DataSource = datatable1
Me.Text = datatable1.Rows.Count & "rows"
End Sub

Loop through the lines of a text file in VB.NET

I have a text file with some lines of text in it.
I want to loop through each line until an item that I want is found*, then display it on the screen, in the form of a label.
*I am searching for the item through a textbox.
That is, in sudo:
For i = 0 To number of lines in text file
If txtsearch.text = row(i).text Then
lbl1.text = row(i).text
Next i
You can use the File.ReadLines Method in order to iterate throughout your file, one line at a time. Here is a simple example:
Dim Term As String = "Your term"
For Each Line As String In File.ReadLines("Your file path")
If Line.Contains(Term) = True Then
' Do something...Print the line
Exit For
End If
Next
Here's a function that will spit back your string from the row that contains your search term...
Public Shared Function SearchFile(ByVal strFilePath As String, ByVal strSearchTerm As String) As String
Dim sr As StreamReader = New StreamReader(strFilePath)
Dim strLine As String = String.Empty
Try
Do While sr.Peek() >= 0
strLine = String.Empty
strLine = sr.ReadLine
If strLine.Contains(strSearchTerm) Then
sr.Close()
Exit Do
End If
Loop
Return strLine
Catch ex As Exception
Return String.Empty
End Try
End Function
To use the function you can do this...
Dim strText As String = SearchFile(FileName, SearchTerm)
If strText <> String.Empty Then
Label1.Text = strText
End If
LOOPING AND GETTING ALL XML FILES FROM DIRECTORY IF WE WANT TEXTFILES PUT "*.txt" IN THE PLACE OF "*xml"
Dim Directory As New IO.DirectoryInfo(Path)
Dim allFiles As IO.FileInfo() = Directory.GetFiles("*.xml")
allFiles = allFiles.OrderByDescending(Function(x) x.FullName).ToArray()
Dim singleFile As IO.FileInfo
For Each singleFile In allFiles
'ds.ReadXml(singleFile)
xd.Load(singleFile.FullName)
Dim nodes As XmlNodeList = xd.DocumentElement.SelectNodes("/ORDER/ORDER_HEADER")
Dim ORDER_NO As String = " "
For Each node As XmlNode In nodes
If Not node.SelectSingleNode("ORDER_NO") Is Nothing Then
ORDER_NO = node.SelectSingleNode("ORDER_NO").InnerText
End If
Next
Next

Placement of constructor

For Some reason in the following segment in my for each statment its declaring the that the csv data cant be null even though as you see their when i create the csvData Object is its created within the loop is that the correct placement.
For Each thisDocument As String In documentList
filename = Path.GetFileName(thisDocument)
SiteId = filename.Substring(0, filename.IndexOf("_"))
Dim orderNumbers As String()
Dim csvData As New DataTable
Dim importUtils As New ImportController
filename = Path.GetFileName(thisDocument)
orderNumbers = filename.Split("_")
location = filename.Substring(0, 3)
importUtils = New ImportController(cfb.TargetFolder & filename)
csvData = importUtils.ConvertCsvToDatatable(True)
ImportDataTableToSql(cfb.TargetFolder & filename, csvData, cfb.StoreCompany)
Next
edits to show convertcsvtodatatable()
Public Function ConvertCsvToDatatable(ByVal ColumnNames As Boolean) As DataTable
Try
Dim dt As New DataTable
For Each columnName In GetColumnsfromCsv(ColumnNames, ",")
dt.Columns.Add(columnName)
Next
Dim fileReader As New StreamReader(FileName)
If ColumnNames Then
fileReader.ReadLine()
End If
Dim line As String = fileReader.ReadLine
While Not IsNothing(line)
line = line.Replace(Chr(34), "")
dt.Rows.Add(line.Split(","))
line = fileReader.ReadLine
End While
fileReader.Close()
Return dt
Catch ex As Exception
'log to file
End Try
Return Nothing
End Function

Reading Text line by line to make string manipulation

So to start this is the code I have already written:
Dim MyFile As String = "Path"
Dim str_new As String
Dim str_old As String = File.ReadAllText(MyFile)
Dim sr As New StreamReader(MyFile)
Dim strLines As String() = Strings.Split(sr.ReadToEnd, Environment.NewLine)
Dim Character As Integer = 5 'Line 1 always has 5 characters
For i = 2 To strLines.Length
Dim PreviousLine As String = sr.ReadLine(i - 1)
Dim CurrentLine As String = sr.ReadLine(i)
If CurrentLine.Contains(TextBox1.Text / 100) Then
If PreviousLine.Contains("divide") Then
Exit For
End If
End If
Character = Character + CurrentLine.Length
Next
sr.Close()
str_new = Replace(str_old, (TextBox1.Text / 100), (TextBox3.Text / 100), Character, 1)
Dim objWriter3 As New System.IO.StreamWriter(MyFile, False)
objWriter3.Write(str_new)
objWriter3.Flush()
objWriter3.Close()
I am trying to figure out a way to break a long code file into lines then check each line for certain strings. If the current line contains the string then I will do additional check on above and/or below lines to make sure This is the correct instance of the string. Finally I want to replace just that instance of the string with a different string.
An example: text file
class
...
0.3
divide <-- Previous Line
0.3 <-- TextBox1.Text is 30
.5
end
I want the code to go past the first instance of 0.3
Find the second instance
Check previous line for divide
Exit Loop
Replace second instance of 0.3 to some value
I have been looking into this for a while now and any help would be greatly appreciated!
~Matt
Revised: Code
Dim MyFile As String = "Path"
Dim NewFile As String = "Temporary Path"
Dim PreviousLine As String = ""
Dim CurrentLine As String = ""
Using sr As StreamReader = New StreamReader(MyFile)
Using sw As StreamWriter = New StreamWriter(NewFile)
CurrentLine = sr.ReadLine
Do While (Not CurrentLine Is Nothing)
Dim LinetoWrite = CurrentLine
If CurrentLine.Contains(TextBox1.Text) Then
If PreviousLine.Contains("divide") Then
LinetoWrite = Replace(CurrentLine, TextBox1.Text, TextBox3.Text)
End If
End If
sw.WriteLine(LinetoWrite)
PreviousLine = CurrentLine
CurrentLine = sr.ReadLine
Loop
End Using
End Using
My.Computer.FileSystem.CopyFile(NewFile, MyFile, True)
You are facing the problem in the wrong way. You have to set both, reader and writer, and generate a new file with all the modifications. Your code has various parts which should be improved; in this answer, I am just showing how to use StreamReader/StreamWriter properly. Sample code:
Dim MyFile As String = "input path"
Dim OutputFile As String = "output path"
Dim PreviousLine As String = ""
Dim CurrentLine As String = ""
Using sr As StreamReader = New StreamReader(MyFile)
Using sw As StreamWriter = New StreamWriter(OutputFile)
CurrentLine = sr.ReadLine
Do While (Not CurrentLine Is Nothing)
Dim lineToWrite = CurrentLine
'Perform the analysis you wish by involving the current line, the previous one and as many other (previous) lines as you wish; and store the changes in lineToWrite. You should call a function here to perform this analysis
sw.WriteLine(lineToWrite) 'Writing lineToWrite to the new file
PreviousLine = CurrentLine 'Future previous line
CurrentLine = sr.ReadLine 'Reading the line for the next iteration
Loop
End Using
End Using