Inserting text after specific tag - vb.net

I have a text file comprised of different tags. I am able to find out if a specific tag exists within the document using the following...
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim text As String = IO.File.ReadAllText("C:\Example.xtp")
Dim index As Integer = text.IndexOf("<Tools>")
If index >= 0 Then
' String is in file, starting at character "<Tools>" insert text "TEST_HELLO"
End If
End Sub
End Class
however I want to also enter extra text after this tag when / if found
I am using VB.net

Try:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim text As String = IO.File.ReadAllText("C:\Example.xtp")
Dim index As Integer = text.IndexOf("<Tools>")
Dim countChars as integer
countChars="<Tools>".Length
If index >= 0 Then
' String is in file, starting at character "<Tools>" insert text "TEST_HELLO"
text = text.Insert(index + countChars, "TEST_HELLO")
End If
End Sub
Edit
If you want to write the final text to a/the file , there are many ways. I just suggest one, but you need to search and read and find what is suitable for you:
Dim Writer As System.IO.StreamWriter
Writer = New System.IO.StreamWriter("C:\Textfile.txt") '<-- Where to write to
Writer.Write(text)
Writer.Close()

Related

Passing data from one form to another form's textboxes

I am trying to pass the selected nodes from a treeview to another form that is displayed in the text boxes.
this is my code in TreeView1_NodeMouseDoubleClick event
the code works fine when the data from the selected treeview is shown in the same form, but the problem is when I want to pass it to the other form 4 nothing is shown and the debug shows me that if it receives the values ​​but they are not reflected, maybe my code to refer to the other form is wrong I would like a support with this case.
Private Sub TreeView1_NodeMouseDoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeNodeMouseClickEventArgs) Handles TreeView1.NodeMouseDoubleClick
Dim nodeKey As String = TryCast(e.Node.Tag, String)
Dim form4 As New Form4
' Dim nodetext As String = TryCast(e.Node.Tag, String)
'Dim nodeKey As String = DirectCast(e.Node.Tag, String)
If nodeKey IsNot Nothing AndAlso nodeKey.StartsWith("DIST") Then
'You have double clicked a district node
Dim IDDISTRITO As Integer = Integer.Parse(nodeKey.Substring(4))
form4.lblco.Text = IDDISTRITO
'Do something with the district id here
'...
form4.txtdis.Text = e.Node.Text
form4.txtpro.Text = e.Node.Parent.Text
form4.txtdepa.Text = e.Node.Parent.Parent.Text
End If
End Sub
so I call form 3 where is the treeview
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim for3 As New Form3
for3.Show()
End Sub
As you assumed, yes you are referencing the forms incorrectly. Please follow this technique. In form3 class, declare a public variable Public Dim form4 As New Form4.
Then modify the form3 calling procedure like this:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim for3 As New Form3
for3.form4 = Me
for3.Show()
End Sub
Now modify your existing code to this :
Private Sub TreeView1_NodeMouseDoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeNodeMouseClickEventArgs) Handles TreeView1.NodeMouseDoubleClick
Dim nodeKey As String = TryCast(e.Node.Tag, String)
' Dim nodetext As String = TryCast(e.Node.Tag, String)
'Dim nodeKey As String = DirectCast(e.Node.Tag, String)
If nodeKey IsNot Nothing AndAlso nodeKey.StartsWith("DIST") Then
'You have double clicked a district node
Dim IDDISTRITO As Integer = Integer.Parse(nodeKey.Substring(4))
form4.lblco.Text = IDDISTRITO
'Do something with the district id here
'...
form4.txtdis.Text = e.Node.Text
form4.txtpro.Text = e.Node.Parent.Text
form4.txtdepa.Text = e.Node.Parent.Parent.Text
End If
End Sub
I have not tested the above code, but I believe you have got the idea.
Well I managed to solve it, the simplest thing was complicated, I publish the solution.
form 4 by calling 3
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim for3 As New Form3
AddOwnedForm(for3)
for3.ShowDialog()
End Sub
just add this code and voila
Dim form4 As Form4 = CType(Owner, Form4)

Get files one at a time from a folder in VB.NET

I am trying to read some text files path in a folder sequentially. However, I get only the first file.
I need to get the first file, execute a timer, get the next file path, execute a timer right up to the last file in the folder, and stop. How can I get around this?
Private zMailbox As String = "c:\Fold\"
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles Button1.Click
Timer1.Start()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles Timer1.Tick
Dim finfo As New IO.DirectoryInfo(zMailbox)
For Each fi In finfo.GetFiles("*.txt")
TextBox1.Text = fi.FullName
Next
End Sub
Thanks to the contributions below I got the code to work with the text box value. However, it gives the index count instead of the path which I want to retrieve.
Private zMailbox As String = "c:\Fold\"
Dim files As FileInfo()
Dim index As Integer = 0
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) _
Handles Button1.Click
Dim finfo As New IO.DirectoryInfo(zMailbox)
files = finfo.GetFiles("*.txt")
Timer1.Start()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles Timer1.Tick
If index >= files.Length Then
index = 0
End If
TextBox1.Text = (ListBox1.Items.Add(files(index)))
index += 1
End Sub
Your code loads all the files in the Timer event and assign them to the TextBox1.Text property inside the loop. Every loop overwrites the data that has been written in the previous loop.
At the end of the loop you see only the last value.
To show sequentially the files inside the Timer Tick event, you need to read the directory content before starting the Timer in a global FileInfo array. Another global variable will be used as indexer to show a particular file from this FileInfo array in your Timer.Tick event.
The index will be incremented and, at the next Tick, you could show the next file
Dim files as FileInfo()
Dim index As Integer = 0
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
Dim finfo As New IO.DirectoryInfo(zMailbox)
files = finfo.GetFiles("*.txt")
Timer1.Start()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
if index >= files.Length Then
index = 0
End If
TextBox1.Text = files(index)
index += 1
End Sub
EDIT
According to your comment, you need to set the MultiLine property of the TextBox to true (using the form designer) and then, at every Tick, instead of replacing the Text property, append to it
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
if index >= files.Length Then
return ' Reached the end of the array. Stop the Timer???
End If
TextBox1.AppendText(files(index) & Environment.NewLine)
index += 1
End Sub
As a side note, if you want to show all file names together then it is not clear why you need a timer at all.
You could get the same result with code like this
Dim finfo As New IO.DirectoryInfo(zMailbox)
Dim files = finfo.EnumerateFiles("*.txt")
TextBox1.Text = string.Join(Environment.NewLine, files.Select(Function(x) x.FullName).ToArray())
On the original code you posted you where getting all files in the for loop each time the timer clicks.
After reading steve answer, and your comments, probably you always got all the files, but you override the textbox.text value.
TextBox1.Text += < String > & vbNewLine
Where < String >, of course, is the string returned by DirectoryInfo.GetFiles()
I think steve answer works just fine, but you are not implementing it well.
I would try and make this as easy as possible for you. You Microsoft's Reactive Framework for this. Just NuGet "Rx-Main".
Here's what you can then do:
finfo.GetFiles("*.txt").ToObservable() _
.Zip(Observable.Interval(TimeSpan.FromSeconds(1.0)), Function(f, _) f.Name) _
.ObserveOn(TextBox1) _
.Subscribe(Function(n) textbox_text += n + Environment.NewLine)
That's it. No timers. No separate methods. No need for module-level variables. Just one line of code and you're done.
It's processed on a background thread and then marshalled back to the UI via the .ObserveOn(TextBox1) call.
You can even keep a reference to the IDisposable returned by the .Subscribe(...) call to terminate the observable (timer) early.
Simple.
This seems a bit Rube Goldberg-ish. Just get all the files and loop through them in your Button_Click method:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim finfo As New IO.DirectoryInfo(zMailbox)
For Each fi In finfo.GetFiles("*.txt")
TextBox1.Text = fi.FullName
Next
End Sub

extract parts of a text line into multiple variables in vb.net

I have created a program that uses the dictionary object to read a line for a TXT file and populate 2 listboxes. It is a bilingual dictionary.
In the file the lines have the structure:
key^value (word in 1st language and word in 2nd language divided by the ^ separator)
e.g.
before^prima
later^dopo
hello^ciao
and the code works just fine...
the problem is that i now need to transform it in a multilingual dictionary so the structure would be
key^value1^value2^value3 (words in 4 languages all divided by the separator)
but i am not able to adapt the dictionary object to it.
How would you solve this?
Basically i have a bunch of lines that are formed by 4 parts with separator and i want to store all the 4 parts in 4 variables:
- definition
- 1stlang
- 2ndlang
- 3rdlang
The code i am using so far for the bilingual is this:
Public Class aero_dictionary
Dim dict As New Dictionary(Of String, String)
Private Sub Form1_Deactivate(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Me.Deactivate
Me.Opacity = 0.6
End Sub
Private Sub Form1_Activated(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Me.Activated
Me.Opacity = 1
End Sub
Private Sub button1_Click(sender As System.Object, _
e As System.EventArgs) _
Handles Button1.Click
Using OFD As New OpenFileDialog
With OFD
.Filter = "Dict files (*.dict)|*.dict"
If .ShowDialog = Windows.Forms.DialogResult.OK Then
LeggiDizionario(.FileName)
End If
End With
End Using
End Sub
Private Sub LeggiDizionario(FullPathFileName As String)
Dim lines As String() = IO.File.ReadAllLines(FullPathFileName)
For Each line As String In lines
Dim kv As KeyValuePair(Of String, String) = ToKeyValuePair(line)
dict.Add(kv.Key, kv.Value)
ListBox1.Items.Add(kv.Key)
Next
End Sub
Public Function ToKeyValuePair(pair As String) _
As KeyValuePair(Of String, String)
Dim two As String() = pair.Split("^")
Return New KeyValuePair(Of String, String)(two(0), two(1))
End Function
Private Sub listbox1_Click(sender As Object, _
e As System.EventArgs) _
Handles ListBox1.Click
Dim lst As ListBox = DirectCast(ListBox1, ListBox)
TextBox2.Clear()
TextBox2.SelectedText = dict(lst.SelectedItem)
End Sub
End Class
You can define the dictionary to use an array of strings, then add the array of 3 elements (less the key) when you the dict.Add.
Dim dict As New Dictionary(Of String, String())

Extract a single line from a webpage VB2008

I'm looking to extract only the line that starts "A SUNOT..." from this website. https://pilotweb.nas.faa.gov/common/nat.html
I then want to paste that line into a text box in VB2008.
I tried using:
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim TrackA As System.Net.HttpWebRequest = System.Net.HttpWebRequest.Create("https://pilotweb.nas.faa.gov/common/nat.html")
Dim gather As System.Net.HttpWebResponse = TrackA.GetResponse
Dim write As System.IO.StreamReader = New System.IO.StreamReader(gather.GetResponseStream)
RawData.Text = write.ReadLine(?)
End Sub
End Class
I got it to write the entire page but I wanted just that line.
The '?' is to show if that ReadLine command is the right thing to be using there.
Thanks, James
Try the following code
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim TrackA As System.Net.HttpWebRequest = System.Net.HttpWebRequest.Create("https://pilotweb.nas.faa.gov/common/nat.html")
Dim gather As System.Net.HttpWebResponse = TrackA.GetResponse
Dim write As System.IO.StreamReader = New System.IO.StreamReader(gather.GetResponseStream)
Dim ContentStr As String = write.ReadToEnd
Dim StartIndex As Integer = ContentStr.IndexOf("A SUNOT")
Dim StrLength As Integer = ContentStr.IndexOf(vbLf, StartIndex) - StartIndex
RawData.Text = ContentStr.Substring(StartIndex, StrLength)
End Sub

Converting drag and drop application that shows directory into showing hash

I am having trouble converting this code into allowing me to drop files into my application and my application create a message box saying its md5 hash code. Currently, I have the code to give the directory of the file I dropped in.
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.AllowDrop = True
End Sub
Private Sub Form1_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Me.DragDrop
Dim files() As String = e.Data.GetData(DataFormats.FileDrop)
For Each path In files
MsgBox(path)
Next
End Sub
Private Sub Form1_DragEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Me.DragEnter
If e.Data.GetDataPresent(DataFormats.FileDrop) Then
e.Effect = DragDropEffects.Copy
End If
End Sub
End Class
Seems like you have most of the code you need, only needs a function to calculate the md5, and then you can plug that into your message box:
MsgBox(ComputeMD5Hash(path))
Here is the function, taken mostly from this Microsoft Support Article
Private Function ComputeMD5Hash(ByVal path As String) As String
Dim tmpSource() As Byte
Dim tmpHash() As Byte
'Create a byte array from source data.
tmpSource = My.Computer.FileSystem.ReadAllBytes(path)
'Compute hash based on source data.
tmpHash = New Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(tmpSource)
Dim i As Integer
Dim sOutput As New System.Text.StringBuilder(tmpHash.Length)
For i = 0 To tmpHash.Length - 1
sOutput.Append(tmpHash(i).ToString("X2"))
Next
Return sOutput.ToString()
End Function
In-case you want to drop a directory and get all the hashes of the files inside you first need to check if you're dealing with a file or a folder, if its a folder you loop over all the files inside and call the function for each one, which would make your DragDrop event handler look something like this, and have the added benefit both files and folders can be taken care of.
Private Sub Form1_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Me.DragDrop
Dim files() As String = e.Data.GetData(DataFormats.FileDrop)
For Each path In files
If IO.File.GetAttributes(path) = FileAttribute.Directory Then
'Dealing with a Directory
Dim di As New IO.DirectoryInfo(path)
Dim fiArr As IO.FileInfo() = di.GetFiles()
Dim fri As IO.FileInfo
For Each fri In fiArr
MessageBox.Show(fri.FullName & " " & ComputeMD5Hash(fri.FullName))
Next fri
Else
'Dealing with a File
MessageBox.Show(path & " " & ComputeMD5Hash(path))
End If
Next
End Sub