Reading Text line by line to make string manipulation - vb.net

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

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

“Input string was not in a correct format” while parsing the content of a file

I need help, I don't know why the array for the quantity in my input file strArr(1) having an error that says that the input string was not in a correct format.
Dim objReader As IO.StreamReader
Dim objWriter As New IO.StreamWriter("C:\Users\user\Desktop\StationeryFolder\output.txt")
Dim strLine As String
Dim strName As String
Dim intQuantity As Integer
Dim intTotal As Integer
Dim strArr() As String
If IO.File.Exists("C:\Users\user\Desktop\StationeryFolder\input.txt") = True Then
objReader = IO.File.OpenText("C:\Users\user\Desktop\StationeryFolder\input.txt")
Else
MsgBox("File is not exist")
Close()
End If
Do While objReader.Peek <> -1
strLine = objReader.ReadLine()
strArr = strLine.Split(" ")
strName = strArr(0)
intQuantity = Convert.ToInt32(strArr(1)) //this is where the error occurs
intTotal = intTotal + intQuantity
lstDisplay.Items.Add(strName & " " & intQuantity.ToString())
objWriter.WriteLine(strName & " " & intQuantity.ToString())
Loop
lstDisplay.Items.Add("Total Quantity of Stationeries are: " & intTotal.ToString())
objWriter.WriteLine("Total Quantity of Stationeries are: " & intTotal.ToString())
objReader.Close()
objWriter.Close()
Inside the input file:
Markers
15
Pens
25
I used the .net File class instead of streams. ReadAllLine returns an array of the lines in the file. I used a StringBuilder which is mutable (changeable) unlike a String. Saves the code from creating and throwing away several strings. I have used interpolated strings indicated by the $ before the quotes. This allows inserting variables directly into the string surrounded by braces.
Private Sub OPCode()
Dim inputPath = "C:\Users\user\Desktop\StationeryFolder\input.txt"
If Not IO.File.Exists(inputPath) Then
MsgBox("File does not exist")
Close()
End If
Dim lines = File.ReadAllLines(inputPath)
Dim total As Integer
Dim sb As New StringBuilder
For i = 0 To lines.Length - 2 Step 2
lstDisplay.Items.Add($"{lines(i)} {lines(i + 1)}")
sb.AppendLine($"{lines(i)} {lines(i + 1)}")
total += CInt(lines(i + 1))
Next
lstDisplay.Items.Add($"Total Quantity of Stationeries are: {total}")
sb.AppendLine($"Total Quantity of Stationeries are: {total}")
File.WriteAllText("C:\Users\user\Desktop\StationeryFolder\output.txt", sb.ToString)
End Sub

IDE thinks I need to close a loop but it looks fine to me

IDE says the Next for the
for i
right below the "Loop through folders commentis missing.
Here is my code.
Dim strVal As String
'Loop through Folders
For i As Integer = 0 To lbFolder.Items.Count - 1
Dim iText As String = CStr(lbFolder.Items(i))
Dim partPath As String = lblPath.Text + "\" + iText
Dim pathNum As String = partPath + "\1900\"
Dim directory As New DirectoryInfo(pathNum)
Dim fileArr As FileInfo() = directory.GetFiles() ' Get a reference to each file in that directory.
' Display the names of the files.
Dim xItem As FileInfo
'loop through files
For Each xItem In fileArr ' add to listbox
lblFname.Text = xItem.ToString
strVal = pathNum & xItem.ToString
lbFiles.Items.Add(strVal)
Next
For j = 0 To lbFiles.Items.Count - 1 'read through files listbox
Dim FileID, Sequence, Time, Lat, Longitude, Average, Channel As String
'declaration of filestream to open file
Dim sr As StreamReader
'filestream object to open and read file
Dim fs As FileStream
Try
'clearing listbox data toavoid confusion
ListView1.Items.Clear()
fs = New FileStream((lbFiles.Items.Item(j)), FileMode.OpenOrCreate)
'stream reader object to read streamed input
sr = New StreamReader(fs)
Dim itm As Object
'reading line by line
itm = sr.ReadLine
While Not itm = Nothing
Dim split As String() = itm.Split(New [Char]() {","})
FileID = split(0)
Sequence = split(1)
Time = split(2)
Lat = split(3)
Longitude = split(4)
Average = split(5)
Channel = split(6)
With ListView1
.Items.Add(FileID)
.Items(ListView1.Items.Count - 1).SubItems.Add(Sequence)
.Items(ListView1.Items.Count - 1).SubItems.Add(Time)
.Items(ListView1.Items.Count - 1).SubItems.Add(Lat)
.Items(ListView1.Items.Count - 1).SubItems.Add(Longitude)
.Items(ListView1.Items.Count - 1).SubItems.Add(Average)
.Items(ListView1.Items.Count - 1).SubItems.Add(Channel)
End With
itm = sr.ReadLine
End While
'close stream reader and filestrema object
sr.Close()
fs.Close()
Catch ex As System.Exception
System.Windows.Forms.MessageBox.Show(ex.Message, "Load Tool Data Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Next j
lbFiles.Items.Clear()
Next i
End Sub
I am using visual studio, when I click on the for i it shows the closing next but when I run I get an error.
What am I missing?
Add **xItem** after the Next
For Each xItem In fileArr ' add to listbox
lblFname.Text = xItem.ToString
strVal = pathNum & xItem.ToString
lbFiles.Items.Add(strVal)
Next xItem
Restarted the IDE and everything ran with no errors.
Thanks all who responded

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

How to select a value from a comma delimited string?

I have a string that contains comma delimited text. The comma delimited text comes from an excel .csv file so there are hundreds of rows of data that are seven columns wide. An example of a row from this file is:
2012-10-01,759.05,765,756.21,761.78,3168000,761.78
I want to search through the hundreds of rows by the date in the first column. Once I find the correct row I want to extract the number in the first position of the comma delimited string so in this case I want to extract the number 759.05 and assign it to variable "Open".
My code so far is:
strURL = "http://ichart.yahoo.com/table.csv?s=" & tickerValue
strBuffer = RequestWebData(strURL)
Dim Year As String = 2012
Dim Quarter As String = Q4
If Quarter = "Q4" Then
Dim Open As Integer =
End If
Once I can narrow it down to the right row I think something like row.Split(",")(1).Trim) might work.
I've done quite a bit of research but I can't solve this on my own. Any suggestions!?!
ADDITIONAL INFORMATION:
Private Function RequestWebData(ByVal pstrURL As String) As String
Dim objWReq As WebRequest
Dim objWResp As WebResponse
Dim strBuffer As String
'Contact the website
objWReq = HttpWebRequest.Create(pstrURL)
objWResp = objWReq.GetResponse()
'Read the answer from the Web site and store it into a stream
Dim objSR As StreamReader
objSR = New StreamReader(objWResp.GetResponseStream)
strBuffer = objSR.ReadToEnd
objSR.Close()
objWResp.Close()
Return strBuffer
End Function
MORE ADDITIONAL INFORMATION:
A more complete picture of my code
Dim tickerArray() As String = {"GOOG", "V", "AAPL", "BBBY", "AMZN"}
For Each tickerValue In Form1.tickerArray
Dim strURL As String
Dim strBuffer As String
'Creates the request URL for Yahoo
strURL = "http://ichart.yahoo.com/table.csv?s=" & tickerValue
strBuffer = RequestWebData(strURL)
'Create Array
Dim lines As Array = strBuffer.Split(New String() {Environment.NewLine}, StringSplitOptions.None)
'Add Rows to DataTable
dr = dt.NewRow()
dr("Ticker") = tickerValue
For Each columnQuarter As DataColumn In dt.Columns
Dim s As String = columnQuarter.ColumnName
If s.Contains("-") Then
Dim words As String() = s.Split("-")
Dim Year As String = words(0)
Dim Quarter As String = words(1)
Dim MyValue As String
Dim Open As Integer
If Quarter = "Q1" Then MyValue = Year & "-01-01"
If Quarter = "Q2" Then MyValue = Year & "-04-01"
If Quarter = "Q3" Then MyValue = Year & "-07-01"
If Quarter = "Q4" Then MyValue = Year & "-10-01"
For Each line In lines
Debug.WriteLine(line)
If line.Split(",")(0).Trim = MyValue Then Open = line.Split(",")(1).Trim
dr(columnQuarter) = Open
Next
End If
Next
dt.Rows.Add(dr)
Next
Right now in the For Each line in lines loop, Debug.WriteLine(line) outputs 2,131 lines:
From
Date,Open,High,Low,Close,Volume,Adj Close
2013-02-05,761.13,771.11,759.47,765.74,1870700,765.74
2013-02-04,767.69,770.47,758.27,759.02,3040500,759.02
2013-02-01,758.20,776.60,758.10,775.60,3746100,775.60
All the way to...
2004-08-19,100.00,104.06,95.96,100.34,22351900,100.34
But, what I expect is for Debug.WriteLine(line) to output one line at a time in the For Each line in lines loop. So I would expect the first output to be Date,Open,High,Low,Close,Volume,Adj Close and the next output to be 2013-02-05,761.13,771.11,759.47,765.74,1870700,765.74. I expect this to happen 2,131 times until the last output is 2004-08-19,100.00,104.06,95.96,100.34,22351900,100.34
You could loop through the lines and call String.Split to parse the columns in each line, for instance:
Dim lines() As String = strBuffer.Split(New String() {Environment.NewLine}, StringSplitOptions.None)
For Each line As String In lines
Dim columns() As String = line.Split(","c)
Dim Year As String = columns(0)
Dim Quarter As String = columns(1)
Next
However, sometimes CSV isn't that simple. For instance, a cell in a spreadsheet could contain a comma character, in which case it would be represented in CSV like this:
example cell 1,"example, with comma",example cell 3
To make sure you're properly handling all possibilities, I'd recommend using the TextFieldParser class. For instance:
Using parser As New TextFieldParser(New StringReader(strBuffer))
parser.TextFieldType = FieldType.Delimited
parser.SetDelimiters(",")
While Not parser.EndOfData
Try
Dim columns As String() = parser.ReadFields()
Dim Year As String = columns(0)
Dim Quarter As String = columns(1)
Catch ex As MalformedLineException
' Handle the invalid formatting error
End Try
End While
End Using
I would break it up into a List(of string()) - Each row being a new entry in the list.
Then loop through the list and look at Value(0).
If Value(0) = MyValue, then Open = Value(1)
You can use String.Split and this linq query:
Dim Year As Int32 = 2012
Dim Month As Int32 = 10
Dim searchMonth = New Date(Year, Month, 1)
Dim lines = strBuffer.Split({Environment.NewLine}, StringSplitOptions.None)
Dim dt As Date
Dim open As Double
Dim opens = From line In lines
Let tokens = line.Split({","c}, StringSplitOptions.RemoveEmptyEntries)
Where Date.TryParse(tokens(0), dt) AndAlso dt.Date = searchMonth AndAlso Double.TryParse(tokens(1), open)
If opens.Any() Then
open = Double.Parse(opens.First().tokens(1))
End If