VB.NET Replace Lines & Task Killer - vb.net

i have two questions for my VB.NET Project that is codded on .netFrameWork 4.0
1:
For example i have text file "textfile1.txt" now program need to find line "//This Line" and replace next line after "//This Line"
example:
In textfile1.txt
//This Line
Some Code here
I need to replace Some Code here with text from TextBox1.text
2:
I have text file "MultiLineTextBox1" now program need to kill process by name from MultiTextBox1 line by line
example:
In MultiLineTextBox1
notepad
mspain
Notepad and MSPaint need to be killed...

Base on what I understood from your question this is what you are after. Now if there are any adjustments to make then feel free to comment.
Private Sub Question1()
Dim list = File.ReadAllLines("yourFilePath").ToList()
Dim itemCount = list.Count
For i As Integer = 0 To itemCount - 1
If list(i) = "//This Line" AndAlso Not ((i + 1) > itemCount) Then
list(i + 1) = TextBox1.Text
End If
Next
KillProcesses(list)
End Sub
Private Sub Question2()
Dim list = TextBox1.Text.Split(New String() {Environment.NewLine}, StringSplitOptions.None).ToList()
KillProcesses(list)
End Sub
Private Sub KillProcesses(items As List(Of String))
For Each item As String In items.Where(Function(listItem) listItem <> "//This Line") ' Exclude redundant text
Dim processes = Process.GetProcessesByName(item)
For Each process As Process In processes
Try
process.Kill()
Catch
' Do your error handling here
End Try
Next
Next
End Sub
UPDATE: Code below is an updated version to reflect the changes requested in the comments below
Private Sub Question1()
Dim list = File.ReadAllLines("YourFilePath").ToList()
Dim itemCount = list.Count
For i As Integer = 0 To itemCount - 1
If list(i) = "//This Line" Then
If (i + 1 > itemCount - 1) Then ' Check if the current item is the last one in the list, if it is then add the text to the list
list.Add(TextBox1.Text)
Else ' An item exists, so just update its value
list(i + 1) = TextBox1.Text
End If
End If
Next
' Write the list back to the file
File.WriteAllLines(Application.StartupPath & "\test.txt", list)
KillProcesses(list)
End Sub

Related

A Sub Procedure holds a list, but only the first item is changed through SetCursorPosition

Module Module1
Dim MenuList As New List(Of String)
Function LineCount() As Integer
Return MenuList.Count
End Function
Sub CreateNewMenu(strings() As String)
For Each s In strings
MenuList.Add(s)
Next
End Sub
Sub PrintMenu(highlight As Integer)
For I = 0 To MenuList.Count - 1
If I = highlight Then
SwapColors()
Console.WriteLine(MenuList(I))
Console.ResetColor()
Else
Console.WriteLine(MenuList(I))
End If
Next
End Sub
Sub SwapColors()
Dim temp = Console.BackgroundColor
Console.BackgroundColor = Console.ForegroundColor
Console.ForegroundColor = temp
End Sub
Sub Main()
CreateNewMenu(
{
"Option A",
"Option B",
"Option C"
})
Dim CurrentItem As Integer = 0
Dim CurrentKey As ConsoleKey
While CurrentKey <> ConsoleKey.Enter
Console.Clear()
PrintMenu(CurrentItem)
'Console.SetCursorPosition(10, 10)
'Console.SetCursorPosition(10, 11)
'Console.SetCursorPosition(10, 12)
CurrentKey = Console.ReadKey(True).Key
Select Case CurrentKey
Case ConsoleKey.DownArrow
CurrentItem += 1
Case ConsoleKey.UpArrow
CurrentItem -= 1
End Select
CurrentItem = (CurrentItem + LineCount()) Mod LineCount()
End While
End Sub
End Module
This is a Code, A changed Post written 2014. The following link should be the source. How can you detect key presses in vb console mode?
The PrintMenu Procedure spotted in the Main Sub Procedure is the line i try to Change with a SetCursorPosition command.
I am able to Change the Output to be screened on row 10 line 10. But only for the Option A.
What has to be done, to manage every item that can be listed on Screen? I want to change the row and line for every item through the PrintMenu Procedure.
The problem is that the cursor position is set for the first item in the list but when WriteLine is called, the cursor position is reset to the next line on column = 0. I would change the PrintMenu method to accept the left and top cursor positiion. Something like this (untested):
Sub PrintMenu(highlight As Integer, left As Integer, top As Integer)
For I = 0 To MenuList.Count - 1
Console.CursorLeft = left
Console.CursorTop = top + I 'Use loop variable to adjust top position
If I = highlight Then
SwapColors()
Console.Write(MenuList(I)) 'Changed to use Write instead
Console.ResetColor()
Else
Console.Write(MenuList(I))
End If
Next
End Sub

VB "Index was out of range, must be non-negative and less than the size of the collection." When trying to generate a random number more than once

So I'm trying to generate a random number on button click. Now this number needs to be between two numbers that are inside my text file with various other things all separated by the "|" symbol. The number is then put into the text of a textbox which is being created after i run the form. I can get everything to work perfectly once, but as soon as i try to generate a different random number it gives me the error: "Index was out of range, must be non-negative and less than the size of the collection." Here is the main code as well as the block that generates the textbox after loading the form. As well as the contents of my text file.
Private Sub generate()
Dim newrandom As New Random
Try
Using sr As New StreamReader(itemfile) 'Create a stream reader object for the file
'While we have lines to read in
Do Until sr.EndOfStream
Dim line As String
line = sr.ReadLine() 'Read a line out one at a time
Dim tmp()
tmp = Split(line, "|")
rows(lineNum).buybutton.Text = tmp(1)
rows(lineNum).buyprice.Text = newrandom.Next(tmp(2), tmp(3)) 'Generate the random number between two values
rows(lineNum).amount.Text = tmp(4)
rows(lineNum).sellprice.Text = tmp(5)
rows(lineNum).sellbutton.Text = tmp(1)
lineNum += 1
If sr.EndOfStream = True Then
sr.Close()
End If
Loop
End Using
Catch x As Exception ' Report any errors in reading the line of code
Dim errMsg As String = "Problems: " & x.Message
MsgBox(errMsg)
End Try
End Sub
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
rows = New List(Of duplicate)
For dupnum = 0 To 11
'There are about 5 more of these above this one but they all have set values, this is the only troublesome one
Dim buyprice As System.Windows.Forms.TextBox
buyprice = New System.Windows.Forms.TextBox
buyprice.Width = textbox1.Width
buyprice.Height = textbox1.Height
buyprice.Left = textbox1.Left
buyprice.Top = textbox1.Top + 30 * dupnum
buyprice.Name = "buypricetxt" + Str(dupnum)
Me.Controls.Add(buyprice)
pair = New itemrow
pair.sellbutton = sellbutton
pair.amount = amounttxt
pair.sellprice = sellpricetxt
pair.buybutton = buybutton
pair.buyprice = buypricetxt
rows.Add(pair)
next
end sub
'textfile contents
0|Iron Sword|10|30|0|0
1|Steel Sword|20|40|0|0
2|Iron Shield|15|35|0|0
3|Steel Shield|30|50|0|0
4|Bread|5|10|0|0
5|Cloak|15|30|0|0
6|Tent|40|80|0|0
7|Leather Armour|50|70|0|0
8|Horse|100|200|0|0
9|Saddle|50|75|0|0
10|Opium|200|500|0|0
11|House|1000|5000|0|0
Not sure what else to add, if you know whats wrong please help :/ thanks
Add the following two lines to the start of generate():
Private Sub generate()
Dim lineNum
lineNum = 0
This ensures that you don't point to a value of lineNum outside of the collection.
I usually consider it a good idea to add
Option Explicit
to my code - it forces me to declare my variables, and then I think about their initialization more carefully. It helps me consider their scope, too.
Try this little modification.
I took your original Sub and changed a little bit take a try and let us know if it solve the issue
Private Sub generate()
Dim line As String
Dim lineNum As Integer = 0
Dim rn As New Random(Now.Millisecond)
Try
Using sr As New StreamReader(_path) 'Create a stream reader object for the file
'While we have lines to read in
While sr.Peek > 0
line = sr.ReadLine() 'Read a line out one at a time
If Not String.IsNullOrEmpty(line) And Not String.IsNullOrWhiteSpace(line) Then
Dim tmp()
tmp = Split(line, "|")
rows(lineNum).buybutton.Text = tmp(1)
rows(lineNum).buyprice.Text = rn.Next(CInt(tmp(2)), CInt(tmp(3))) 'Generate the random number between two values
rows(lineNum).amount.Text = tmp(4)
rows(lineNum).sellprice.Text = tmp(5)
rows(lineNum).sellbutton.Text = tmp(1)
lineNum += 1
End If
End While
End Using
Catch x As Exception ' Report any errors in reading the line of code
Dim errMsg As String = "Problems: " & x.Message
MsgBox(errMsg)
End Try
End Sub

How to remove vb.net Richtextbox lines that not contains specific text?

I use the next code to remove lines from Richtextboxes but that way i can only tell what line to remove. I need to remove all lines that not contains specific text, can this be done with some edits of my code?
1st piece:
Private Property lineToBeRemovedlineToBeRemoved As Integer
2nd piece:
Dim lineToBeRemoved As Integer = 0
lineToBeRemovedlineToBeRemoved = lineToBeRemoved - 0
Dim str As String = RichTextBox1.Lines(lineToBeRemoved)
RichTextBox1.Find(str & vbCr)
RichTextBox1.SelectedText = ""
This code will remove any line from a richtextbox RichTextbox1 that does not contain "Test" on it. Remember to add Imports System.Text.RegularExpressions to the top of your code.
Private Sub RemoveLines()
Dim lines As New List(Of String)
lines = RichTextBox1.Lines.ToList
Dim FilterText = "Test"
For i As Integer = lines.Count - 1 To 0 Step -1
If Not Regex.IsMatch(lines(i), FilterText) Then
lines.RemoveAt(i)
End If
Next
RichTextBox1.Lines = lines.ToArray
End Sub
You code is not close. You should start over. Use a for loop to go through the RichTextBox lines. If the text is not in a line, then delete it. Tip: It may be easier to go from the last line to the first to avoid problems when deleting.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
RTB.Select(RTB.GetFirstCharIndexFromLine(2), RTB.Lines(2).Count)
RTB.SelectionLength = RTB.Lines(2).Length + 1
RTB.SelectedText = ""
End Sub
Try this code, I applied to my prog and it work good.
When use, just ... call dels("unwanted") ==> Line which contain unwanted word will disappear.
Private Sub dels(sw As String)
Dim ud As String = "" 'for keep all we need
Dim cn As Integer = 0 'for avoid empty line
For Each line As String In RichTextBox1.Lines 'for every line in reichtextbox
If Len(line) > 5 Then 'if that line got more than 5 character
If InStr(line.ToLower, sw.ToLower) < 1 Then 'transform them to lower case for better resulted
If cn = 1 Then ud = ud + vbCrLf 'not place new-line if it is first
ud = ud + line 'keep this line if not match ne want delete
cn = 1 'turn-off first line signal
End If
End If
Next
RichTextBox1.Clear() 'empty richtextbox
RichTextBox1.AppendText(ud) 'update richtextbox with the unwanted
End Sub

Remove items from a listbox if it appears in another

I have 2 listbox's on my form. The first populates from an array and displays files names that relate to the value of a Date Time picker. When that item is double clicked it moves over to the 2nd list box, clears from the 1st and the relevant files are transferred from one directory to another. The problem I have is that as the population is part of the load event once the application is closed and then re-opened the files names appear in both listbox's.
Is there a way to say if the object appears in 1 textbox then it shouldn't appear in the other?
I've tried the following but re-opening still displays the object in both
Dim item As Object
For Each item In lstPlanned.Items
If lstProgress.Contains(item) Then
lstPlanned.Items.Remove(item)
End If
Next
For the 2nd listbox I'm using the following to populate it
For Each Dir As String In System.IO.Directory.GetDirectories(aMailbox)
Dim dirInfo As New System.IO.DirectoryInfo(Dir)
lstProgress.Items.Add(dirInfo.Name)
Full Load code as follows
Private Sub Main_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim loaddate As String = Calendar.Value.ToString("dd/MM/yy")
ReDim AllDetail(0 To 0)
numfiles = 0
lstPlanned.Items.Clear()
Dim allfiles = lynxin.GetFiles("*.txt")
ReDim AllDetails(allfiles.Count)
lstProgress.Items.Clear()
lstPlanned.Items.Add("No Jobs Planned Today!")
lstPlanned.Enabled = False
For Each txtfi In (allfiles)
Dim allLines() As String = File.ReadAllLines(txtfi.FullName)
AllDetails(numfiles) = New FileDetail()
AllDetails(numfiles).uPath = Microsoft.VisualBasic.Left((txtfi.FullName), Len(txtfi.FullName) - 4)
AllDetails(numfiles).uFile = Path.GetFileNameWithoutExtension(txtfi.Name)
Dim line = allLines.Where(Function(x) (x.StartsWith("unitname="))).SingleOrDefault()
If line IsNot Nothing Then
AllDetails(numfiles).uName = line.Split("="c)(1)
End If
line = allLines.Where(Function(x) (x.StartsWith("unitcode="))).SingleOrDefault()
If line IsNot Nothing Then
AllDetails(numfiles).uCode = line.Split("="c)(1)
End If
line = allLines.Where(Function(x) (x.StartsWith("opername="))).SingleOrDefault()
If line IsNot Nothing Then
AllDetails(numfiles).uOps = line.Split("="c)(1)
End If
line = allLines.Where(Function(x) (x.StartsWith("plandate="))).SingleOrDefault()
If line IsNot Nothing Then
AllDetails(numfiles).uPlan = line.Split("="c)(1)
End If
line = allLines.Where(Function(x) (x.StartsWith("cliecode="))).SingleOrDefault()
If line IsNot Nothing Then
AllDetails(numfiles).uClient = line.Split("="c)(1)
End If
If AllDetails(numfiles).uPlan = loaddate Then
lstPlanned.Items.Remove("No Jobs Planned Today!")
lstPlanned.Enabled = True
lstPlanned.Items.Insert(0, AllDetails(numfiles).uName & " - " & AllDetails(numfiles).uCode & " - " & AllDetails(numfiles).uOps)
numfiles = numfiles + 1
End If
Next
For Each Dir As String In System.IO.Directory.GetDirectories(aMailbox)
Dim dirInfo As New System.IO.DirectoryInfo(Dir)
lstProgress.Items.Add(dirInfo.Name)
Dim item As Object
For Each item In lstPlanned.Items
If lstProgress.Contains(item) Then
lstPlanned.Items.Remove(item)
End If
Next
Next
End Sub
The Contains method of a listbox checks the controls collections not the items collection. It should have been lstProgress.Items.Contains(item). Also you can use GetDirectories of the DirectoryInfo class to get the directoryinfo objects directly.
Checking to see if lstPlanned contains each item as you add it to lstProgress will eliminate the extra loop, which wouldn't work right anyway, because you're not allowed to modify the iterated collection in a For Each loop.
I was looking over your code and noticed an improvement that could be made. Using the LINQ extension methods each you want to add a property value means a lot of extra iterating through each file line collection. Using select means you only iterate through the collection once.
For Each txtfi In (allfiles)
Dim allLines() As String = File.ReadAllLines(txtfi.FullName)
AllDetails(numfiles) = New FileDetail()
AllDetails(numfiles).uPath = Microsoft.VisualBasic.Left((txtfi.FullName), Len(txtfi.FullName) - 4)
AllDetails(numfiles).uFile = Path.GetFileNameWithoutExtension(txtfi.Name)
AllDetails(numfiles).uPlan = allLines.Where(Function(x) (x.StartsWith("plandate="))).SingleOrDefault().Split("="c)(1)
If AllDetails(numfiles).uPlan = loaddate Then
For Each line In allLines
If line Is Not Nothing Then
Dim fields As String() = line.Split("="c)
Select Case fields(0)
Case "unitname"
AllDetails(numfiles).uName = fields(1)
Case "unitcode"
AllDetails(numfiles).uCode = fields(1)
Case "opername"
AllDetails(numfiles).uOps = fields(1)
Case "plandate"
AllDetails(numfiles).uPlan = fields(1)
Case "cliecode"
AllDetails(numfiles).uClient = fields(1)
End Select
End If
Next
lstPlanned.Items.Remove("No Jobs Planned Today!")
lstPlanned.Enabled = True
lstPlanned.Items.Insert(0, AllDetails(numfiles).uName & " - " & AllDetails(numfiles).uCode & " - " & AllDetails(numfiles).uOps)
numfiles = numfiles + 1
End If
Next
Dim RootDir As New System.IO.DirectoryInfo(aMailbox)
For Each Dir As IO.DirectoryInfo In RootDir.GetDirectories
Dim item = Dir.Name
lstProgress.Items.Add(item)
If lstPlanned.Items.Contains(item) Then
lstPlanned.Items.Remove(item)
End If
Next
Thanks Tinstaafl
Your answer works a treat.
I also adapted your first edit to
Dim RootDir As New System.IO.DirectoryInfo(aMailbox)
For Each Dir As IO.DirectoryInfo In RootDir.GetDirectories
lstProgress.Items.Add(Dir.Name)
'item defaults to object, no need to explicitly declare it
For Each item In New System.Collections.ArrayList(lstPlanned.Items)
If lstProgress.Items.Contains(item) Then
lstPlanned.Items.Remove(item)
End If
Next
Next
amending the following line
For Each item In New System.Collections.ArrayList(lstPlanned.Items)
Thanks again

How to color multiple text from richtextbox in vb.net

So I made a chat in vb.net (using FTP server) and I want to color each name from my chat
so the file with messages is something like the following:
#2George: HI
#2George: Hi geoo
and using RichTextBox1 textchanged event I add:
For Each line In RichTextBox1.Lines
If Not line Is Nothing Then
If line.ToString.Trim.Contains("#2") Then
Dim s$ = line.Trim
RichTextBox1.Select(s.IndexOf("#") + 1, s.IndexOf(":", s.IndexOf("#")) - s.IndexOf("#") - 1)
MsgBox(RichTextBox1.SelectedText)
RichTextBox1.SelectionColor = Color.DeepSkyBlue
End If
End If
Next
the first name (George) changed his color but the second one didn't.
Any ideas why this is happening?
The main problem is that your IndexOf calculations are using the index of the current line, but you are not translating that index to where that line is being used in the RichTextBox. That is, your second line of #2George: Hi geoo is finding an index of 0 for the # sign, but index 0 in the RichTextBox is referring to the line #2George: HI, so you keep redrawing the first line every time.
To fix the immediate problem:
For i As Integer = 0 To RichTextBox1.Lines.Count - 1
Dim startIndex As Integer = RichTextBox1.Text.IndexOf("#", _
RichTextBox1.GetFirstCharIndexFromLine(i))
If startIndex > -1 Then
Dim endIndex As Integer = RichTextBox1.Text.IndexOf(":", startIndex)
If endIndex > -1 Then
RichTextBox1.Select(startIndex, endIndex - startIndex)
RichTextBox1.SelectionColor = Color.DeepSkyBlue
End If
End If
Next
The next problem is that doing this in the TextChanged event re-draws all the lines all the time. That won't scale too well. Consider drawing the text before you add it to the control by using a preformatted RTF line. Something like this:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
AddRTFLine("#2George", "Hi")
AddRTFLine("#2George", "Hi geoo")
End Sub
Private Sub AddRTFLine(userName As String, userMessage As String)
Using box As New RichTextBox
box.SelectionColor = Color.DeepSkyBlue
box.AppendText(userName)
box.SelectionColor = Color.Black
box.AppendText(": " & userMessage)
box.AppendText(Environment.NewLine)
box.SelectAll()
RichTextBox1.Select(RichTextBox1.TextLength, 0)
RichTextBox1.SelectedRtf = box.SelectedRtf
End Using
End Sub