I have a text file with the format:
(title,price,id#)
CD1,11.00,111111
CD2,12.00,222222
CD3,13.00,333333
CD4,14.00,444444
CD5,15.00,555555
CD6,16.00,666666
What is the best way to go change the price of the appropriate CD if I'm given the id# and new price?
I'm sure it has something do to with getting the line and splitting it, but I'm not sure how I edit just one line and not mess up the whole file.
You can't rewrite a line without rewriting the entire file (unless the lines happen to be the same length). For such a small file it's probably the easiest to change the line in memory and then rewrite all to the file:
Dim idToFind = "444444"
Dim newPrice = "100"
Dim lines = IO.File.ReadAllLines(path)
For i = 0 To lines.Length - 1
Dim line = lines(i)
Dim fields = line.Split(","c)
If fields.Length > 2 Then
Dim id = fields(2)
If id = idToFind Then
Dim title = fields(0)
lines(i) = String.Format("{0},{1},{2}", title, newPrice, id)
Exit For
End If
End If
Next
IO.File.WriteAllLInes(path, lines)
Okay, now we know it's a short file, life becomes much easier:
Load the file into an array of lines using File.ReadAllLines
Find the right line using string.Split to split each line into the constituent parts, and check the ID.
When you've found the right line, replace it with the complete new line
Write the file back with File.WriteAllLines
That should be enough to get you going.
If its just a file with like 25 lines, you could do a simple input-transform-output routine and update the price per line.
Something like this (Using Streamreader / writer ).
Sub UpdatePrice(ByVal pricesToUpdate As Dictionary(Of Integer, String), ByVal inputPath As String)
If Not IO.File.Exists(inputPath) Then Return
Try
Using inputStream = New IO.StreamReader(inputPath, System.Text.Encoding.UTF8, True)
Using outputStream = New IO.StreamWriter(inputPath + ".tmp", False, System.Text.Encoding.UTF8)
While Not inputStream.EndOfStream
Dim inputLine = inputStream.ReadLine
Dim content = inputLine.Split(","c)
If Not content.Length >= 3 Then
outputStream.WriteLine(inputLine)
Continue While
End If
Dim id As Integer
If Not Integer.TryParse(content(2), id) Then
outputStream.WriteLine(inputLine)
Continue While
End If
If Not pricesToUpdate.ContainsKey(id) Then
outputStream.WriteLine(inputLine)
Continue While
End If
content(1) = pricesToUpdate(id)
outputStream.WriteLine(String.Join(",", {content(0), content(1), content(2)}))
End While
End Using
End Using
If IO.File.Exists(inputPath + ".tmp") Then
IO.File.Delete(inputPath)
IO.File.Move(inputPath + ".tmp", inputPath)
End If
Catch ex As IO.IOException
If IO.File.Exists(inputPath + ".tmp") Then IO.File.Delete(inputPath + ".tmp")
End Try
End Sub
Related
I am reading a txt file line by line in VB to look for the word "unable". That much works. The code is here:
Imports System
Imports System.IO
Imports PartMountCollector.HandMount_WebReference
Imports System.Threadingtime
Imports eCenter.Motor.VBConnect
Module Program
Sub Main(args As String())
Dim unUpdate As String = "Unable"
Dim time = DateTime.Now
Dim yesterday = time.AddDays(-1)
Dim format As String = "yyyyMMdd"
Dim words As String()
For Each Line As String In File.ReadLines("C:\Users\te-smtinternal\Desktop\ReStockLog\" + time.ToString(format) + ".txt")
words = Split(Line)
If Line.Contains(unUpdate) = True Then
Console.WriteLine("Exist")
'Read previous line looking for "Success"'
End If
Console.WriteLine("not found")
Next
End Sub
End Module
Now I need be able to identify this line and read the previous line, looking for the word "success".
Any help would be appreciated
Instead of trying to handle each line one at a time, you could read all the lines and then iterate through them which would give you access to the previous line, like:
Dim lines = IO.File.ReadAllLines(file_name)
dim previous_line as string = ""
for x as integer = 0 to lines.count-1
if lines(x).ToString.Contains("unable") then previous_line = lines(x-1).ToString
next
of course you would need to handle the exception of finding a hit on the first line which would throw an out of index error. So you would simply need to add a check to make sure x > 0.
You just need to declare a variable outside of the loop to store the previous line. Here I've named it previousLine...
Const unUpdate As String = "Unable"
Dim time = DateTime.Now
Const format As String = "yyyyMMdd"
Dim previousLine as String = Nothing
For Each currentLine As String In File.ReadLines("C:\Users\te-smtinternal\Desktop\ReStockLog\" + time.ToString(format) + ".txt")
If currentLine.Contains(unUpdate) Then
Console.WriteLine("Exist")
If previousLine Is Nothing Then
' The very first line of input contains unUpdate
Else If previousLine.Contains("Success")
' A line after the first line of input contains unUpdate
End If
Else
Console.WriteLine("not found")
End If
previousLine = currentLine
Next
At the end of each loop iteration the currentLine becomes the previousLine and, if there is another iteration, it will read a new value for currentLine.
Also note that in...
If Line.Contains(unUpdate) = True Then
...you don't need the = True comparison because Contains() already returns a Boolean.
I want to read and write the same file with StreamReader and StreamWriter. I know that in my code I am trying to open the file twice and that is the problem. Could anyone give me another way to do this? I got confused a bit.
As for the program, I wanted to create a program where I create a text if it doesnt exist. If it exists then it compares each line with a Listbox and see if the value from the Listbox appears there. If it doesnt then it will add to the text.
Dim SR As System.IO.StreamReader
Dim SW As System.IO.StreamWriter
SR = New System.IO.StreamReader("D:\temp\" & Cerberus.TextBox1.Text & "_deleted.txt", True)
SW = New System.IO.StreamWriter("D:\temp\" & Cerberus.TextBox1.Text & "_deleted.txt", True)
Dim strLine As String
Do While SR.Peek <> -1
strLine = SR.ReadLine()
For i = 0 To Cerberus.ListBox2.Items.Count - 1
If Cerberus.ListBox2.Items.Item(i).Contains(strLine) = False Then
SW.WriteLine(Cerberus.ListBox2.Items.Item(i))
End If
Next
Loop
SR.Close()
SW.Close()
SR.Dispose()
SW.Dispose()
MsgBox("Duplicates Removed!")
If your file is not that large, consider using File.ReadAllLines and File.WriteAllLines.
Dim path = "D:\temp\" & Cerberus.TextBox1.Text & "_deleted.txt"
Dim lines = File.ReadAllLines(path) 'String() -- holds all the lines in memory
Dim linesToWrite = Cerberus.ListBox2.Items.Cast(Of String).Except(lines)
File.AppendAllLines(path, linesToWrite)
If the file is large, but you only have to write a few lines, then you can use File.ReadLines:
Dim lines = File.ReadLines(path) 'IEnumerable(Of String)\
'holds only a single line in memory at a time
'but the file remains open until the iteration is finished
Dim linesToWrite = Cerberus.ListBox2.Items.Cast(Of String).Except(lines).ToList
File.AppendAllLines(path, linesToWrite)
If there are a large number of lines to write, then use the answers from this question.
I have this code but it have errors , what should i do ?
Dim lines As New List(Of String)
lines = RichTextBox1.Lines.ToList
'Dim FilterText = "#"
For i As Integer = lines.Count - 1 To 0 Step -1
'If (lines(i).Contains(FilterText)) Then
RichTextBox1.Lines(i) = RichTextBox1.Lines(i).Replace("#", "#sometext")
'End If
Next
RichTextBox1.Lines = lines.ToArray
Update: while the following "works" it does only modify the array which was returned from the Lines-property. If you change that array you don't change the text of the TextBox. So you need to re-assign the whole array to the Lines-property if you want to change the text(as shown below). So i keep the first part of my answer only because it fixes the syntax not the real issue.
It's not
RichTextBox1.Lines(i).Replace = "#sometext"
but
RichTextBox1.Lines(i) = "#sometext"
You can loop the Lines forward, the reverse loop is not needed here.
Maybe you want to replace all "#" with "#sometext" instead:
RichTextBox1.Lines(i) = RichTextBox1.Lines(i).Replace("#","#sometext")
So here the full code necessary (since it still seems to be a problem):
Dim newLines As New List(Of String)
For i As Integer = 0 To RichTextBox1.Lines.Length - 1
newLines.Add(RichTextBox1.Lines(i).Replace("#", "#sometext"))
Next
RichTextBox1.Lines = newLines.ToArray()
But maybe you could even use:
RichTextBox1.Text = RichTextBox1.Text.Replace("#","#sometext")`
because if we have # abcd this code change it to # sometextabcd ! I
Want a code to replace for example line 1 completely to # sometext
Please provide all relevant informations in the first place next time:
Dim newLines As New List(Of String)
For Each line As String In RichTextBox1.Lines
Dim newLine = If(line.Contains("#"), "#sometext", line)
newLines.Add(newLine)
Next
RichTextBox1.Lines = newLines.ToArray()
I'm a bit of a newbie so any advice would be great. I have a program
that opens a CSV, and then saves it as a csv with a different name. there will be a set of rules to change fields but haven't got that far yet.
when I run this on a small csv file (about 4 columns and rows) it works fine, but with a larger file, it fails with the error above. i'm sure its something daft but I I'm at a loss.
Thanks,
Dean
Dim FileName = tbOpen.Text
Dim fileout = tbSave.Text
Dim lines = File.ReadAllLines(FileName)
Dim output As New List(Of String)
For Each line In lines
Dim fields = line.Split(","c)
If fields(1) = "" Then 'This is where the error is triggered
fields(1) = "Norman"
End If
If fields(3) = "" Then
fields(3) = "Blue Leather"
End If
If fields(4) = "" Then
fields(3) = "Interlined"
End If
output.Add(String.Join(","c, fields))
Next
File.WriteAllLines(fileout, output)
Try
Dim a As String = My.Computer.FileSystem.ReadAllText(tbSave.Text)
Dim b As String() = a.Split(vbNewLine)
ListBox2.Items.AddRange(b)
Catch ex As Exception
MsgBox("error")
End Try
Keep in mind that arrays start a index 0. VB is notorious for stretching this concept. Normally, when you declare an array with 10 elements the indexes would be from 0 - 9. With VB, on the other hand, the indexes will be from 0 - 10 which will actually give you 11 elements.
Hi i am new to VB and in the process of learning. This error occur sometimes and doesn't occur sometimes which i find it weird.
I receive the error Index was outside the bounds of the array, that points to Button30.Text = Split(newestversion, vbCrLf)(**1**)
My motive is to read line by line from a online hosted text file.
For example,
label1.text = line 1 of the text file
label2.text = line 2 of the text file
This is very much what i want.
Here is my current code (EDITED):
Dim request As System.Net.HttpWebRequest = System.Net.HttpWebRequest.Create("direct link to my online txt file")
Dim response As System.Net.HttpWebResponse = request.GetResponse
Dim sr As System.IO.StreamReader = New System.IO.StreamReader(response.GetResponseStream)
Dim stringReader As String
stringReader = sr.ReadLine()
Button10.Text = stringReader
Dim newestversion As String = sr.ReadToEnd
Dim currentversion As String = Application.ProductVersion
Dim part() As String = Split(newestversion, vbCrLf)
If part.Length < 10 Then
' not enough items in the array. You could also throw and exception or do some other stuff here
Label10.Text = "beta"
Exit Sub
End If
'updates new episode numbers on buttons
Button20.Text = part(0)
Button30.Text = part(1)
Button40.Text = part(2)
Button50.Text = part(3)
Button60.Text = part(4)
Button70.Text = part(5)
Button80.Text = part(6)
Button90.Text = part(7)
Button100.Text = part(8)
Button110.Text = part(9)
End If
Thank You!!
You split your String for line breaks. This gives you an array, having one entry for each line in the String. However, you do not check if this array holds the amount of items you expect. You could do:
Dim newestversion As String = sr.ReadToEnd
Dim currentversion As String = Application.ProductVersion
Dim part() As String = Split(newestversion, vbCrLf)
If part.Length < 10 Then
' not enough items in the array. You could also throw and exception or do some other stuff here
MsgBox(String.Format("Array only has {0} items", part.Length))
Exit Sub
End If
'updates new episode numbers on buttons
Button20.Text = part(0)
Button30.Text = part(1)
Button40.Text = part(2)
...
Edit for the updated question
If you do have a problem like this, just approach it systematically and get as much information as you can. First you have to check if you really get the data you want from the remote source. To do that, add some logging (e.g. a MsgBox(newestversion) or a real log file). Check if the data you get is what you expect. If not, there's already a problem with your request/response code, which is a completely different problem than what I provided a solution for. If newestversion is OK, check if the splitting works by printing out the part() array. Maybe the server uses a different operating system or just uses vbCr as newline and not vbCrlf. If the splitting also works, you are done.