How to match last line of text file in treeview and display text boxes in vb.net? - vb.net

I have a problem with a sorted TreeView. I select the last line of a text file, then I extract from this text file the last child node added in the TreeView. Where the shoe pinch is that I can't do it! I have tried with the number of lines in this file, but no results. In fact, I do a bit of everything (not of course) to get the selected node to coincide in the treeview and the displays in the text boxes. Below is a screenshot and my code! I don't know if I made myself understood correctly, my English is translated English. Thank you. Claude.
Dim NbLine As Integer = 0
Dim SR As System.IO.StreamReader = New System.IO.StreamReader(OuvrirFichier)
While Not SR.EndOfStream
SR.ReadLine()
NbLine += 1
End While
SR.Close()
Dim lastLine As String = File.ReadLines(OuvrirFichier, Encoding.UTF8) _
.Where(Function(f As String) (Not String.IsNullOrEmpty(f))).Last.ToString
Dim mytext As String = lastLine.Substring(17, 90)
If NbLine > 0 Then
Dim lignesDuFichier As String() = File.ReadAllLines(OuvrirFichier, Encoding.UTF8)
Dim derniereLigne As String = lignesDuFichier(lignesDuFichier.Length - 1)
TreeView1.Focus()
TreeView1.SelectedNode = TreeView1.Nodes(0).Nodes(lignesDuFichier.Length - 1)
End If

Comments in line.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim OuvrirFichier = "C:\Users\maryo\Desktop\Code\Test Empty Line.txt" '"path to file"
'At least you will only be reading the file once
Dim AllLines = File.ReadAllLines(OuvrirFichier)
Dim LinesWithContent = AllLines.Where(Function(s) s.Trim() <> String.Empty)
Dim lastLine = LinesWithContent.Last
Dim mytext As String = lastLine.Substring(17, 90)
Debug.Print(mytext) 'Just checking that you get what was expected
Dim NbLine = AllLines.Length
Dim derniereLigne As String = AllLines(NbLine - 1) 'Another variable to hold last line???
'But this time it could be a blank line.
TreeView1.Focus()
'This makes no sense. An index of a subNode base on the number of lines in the text file
'is supposed to be the SelectedNode
'Why would this be the last node added?
TreeView1.SelectedNode = TreeView1.Nodes(0).Nodes(NbLine - 1)
'You never test the equality of the SelectedNode with mytext
End Sub

Related

exclude header from csv in vb.net

I got a .csv and I want to load it into a datagridview. I have a button called button1 and I got a datagridview called datagridview1. I click the button and it appears... including the header, which I don't want.
Please:
How do I exclude the header from the .csv ?
code:
Imports System.IO
Imports System.Text
Public Class CSV_Reader
Private Sub CSV_Reader_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim filename As String = "C:\Users\Gaius\Desktop\meepmoop.csv"
Dim thereader As New StreamReader(filename, Encoding.Default)
Dim colsexpected As Integer = 7
Dim sline As String = ""
DataGridView1.Rows.Clear()
Do
sline = thereader.ReadLine
If sline Is Nothing Then Exit Do
Dim words() As String = sline.Split(";")
DataGridView1.Rows.Add("")
If words.Length = colsexpected Then
For ix As Integer = 0 To 6
DataGridView1.Rows(DataGridView1.Rows.Count - 2).Cells(ix).Value = words(ix)
Next
Else
DataGridView1.Rows(DataGridView1.Rows.Count - 2).Cells(0).Value = "ERROR"
End If
Loop
thereader.Close()
End Sub
End Class
meepmoop.csv:
alpha;bravo;charlie;delta;echo;foxtrot;golf
1;meep;moop;meep;moop;meep;moop
2;moop;meep;moop;meep;moop;meep
3;meep;moop;meep;moop;meep;moop
4;moop;meep;moop;meep;moop;meep
5;meep;moop;meep;moop;meep;moop
6;moop;meep;moop;meep;moop;meep
7;meep;moop;meep;moop;meep;moop
8;moop;meep;moop;meep;moop;meep
9;meep;moop;meep;moop;meep;moop
10;moop;meep;moop;meep;moop;meep
edit:
[...]
Dim sline As String = ""
DataGridView1.Rows.Clear()
Dim line As String = thereader.ReadLine()
If line Is Nothing Then Return
Do
sline = thereader.ReadLine
[...]
The above addition to the code works but I have no idea why. Nor do I understand why I have to -2 rather than -1. I can't rely on guesswork, I'm expected to one day do this professionally. But I just can't wrap my head around it. Explanation welcome.
edit:
Do
sline = thereader.ReadLine
If sline Is Nothing Then Exit Do
Dim words() As String = sline.Split(";")
If words.Count = 7 Then
DataGridView1.Rows.Add(words(0), words(1), words(2), words(3), words(4), words(5), words(6))
Else
MsgBox("ERROR - There are " & words.Count & " columns in this row and there must be 7!")
End If
Loop
I've shortened the Loop on the advice of a coworker, taking his word on it being 'better this way'.
Another method, using Enumerable.Select() + .Skip()
As noted in Ondřej answer, there's a specific tool for these operations: TextFieldParser
But, if there are no special requirements and the string parsing is straightforward enough, it can be done with the standard tools, as shown in Tim Schmelter answer.
This method enumerates the string arrays returned by the Split() method, and groups them in a list that can be then used in different ways. As a raw text source (as in this case) or as a DataSource.
Dim FileName As String = "C:\Users\Gaius\Desktop\meepmoop.csv"
Dim Delimiter As Char = ";"c
Dim ColsExpected As Integer = 7
If Not File.Exists(FileName) Then Return
Dim Lines As String() = File.ReadAllLines(FileName, Encoding.Default)
Dim StringColumns As List(Of String()) =
Lines.Select(Function(line) Split(line, Delimiter, ColsExpected, CompareMethod.Text)).
Skip(1).ToList()
DataGridView1.Rows.Clear()
'If the DataGridView is empty, add a `[ColsExpected]` number of `Columns`:
DataGridView1.Columns.AddRange(Enumerable.Range(0, ColsExpected).
Select(Function(col) New DataGridViewTextBoxColumn()).ToArray())
StringColumns.Select(Function(row) DataGridView1.Rows.Add(row)).ToList()
If you instead want to include and use the Header because your DataGridView is empty (it has no predefined Columns), you could use the Header line in the .csv file to create the control's Columns:
'Include the header (no .Skip())
Dim StringColumns As List(Of String()) =
Lines.Select(Function(line) Split(line, Delimiter, ColsExpected, CompareMethod.Text)).ToList()
'Insert the columns with the .csv header columns description
DataGridView1.Columns.AddRange(Enumerable.Range(0, ColsExpected).
Select(Function(col, idx) New DataGridViewTextBoxColumn() With {
.HeaderText = StringColumns(0)(idx)
}).ToArray())
'Remove the header line...
StringColumns.RemoveAt(0)
StringColumns.Select(Function(row) DataGridView1.Rows.Add(row)).ToList()
You can skip the header by calling ReadLine twice. Also use the Using-statement:
Using thereader As New StreamReader(filename, Encoding.Default)
Dim colsexpected As Integer = 7
Dim sline As String = ""
Dim line As String = thereader.ReadLine() ' header
if line is Nothing Then Return
Do
sline = thereader.ReadLine()
If sline Is Nothing Then Exit Do
Dim words() As String = sline.Split(";"c)
' ... '
Loop
End Using
You should use VB.NET class that is designed and tested for this purpose. It is Microsoft.VisualBasic.FileIO.TextFieldParser and you can skip header by calling ReadFields() once before you start parsing in loop.

Item pairing between two .txt

I have been trying to combine or pair two text files.
One file contains User:Key
The other file contains Key:Pass
I want a 3rd text file created containing the corresponding pairs of User:Pass based on the key matching.
Here is what Ive tried most recently
Private Sub Rotate()
Dim Cracked() As String = IO.File.ReadAllLines(TextBox1.Text)
For Each lineA In Cracked
TextBox5.Text = lineA
check()
Next
End Sub
Private Sub check()
Dim toCheck() As String = TextBox5.Text.Split(":")
Dim tHash As String = toCheck(0)
Dim tPass As String = toCheck(1)
Dim lines1() As String = IO.File.ReadAllLines(TextBox2.Text)
For Each line In lines1
If lines1.Contains(tHash) Then
Dim toAdd() As String = line.Split(":")
Dim uHash As String = toCheck(0)
Dim uUser As String = toCheck(1)
ListBox1.Items.Add(uUser + ":" + tPass)
End If
Next
End Sub
Public Sub CopyListBoxToClipboard(ByVal ListBox2 As ListBox)
Dim buffer As New StringBuilder
For i As Integer = 0 To ListBox1.Items.Count - 1
buffer.Append(ListBox1.Items(i).ToString)
buffer.Append(vbCrLf)
Next
My.Computer.Clipboard.SetText(buffer.ToString)
End Sub
Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click
CopyListBoxToClipboard(ListBox1)
End Sub
The delimiter changes but for now the : works.
I tried splitting and matching but either the textbox5 does not rotate or it rotates through the list and thats all.
Something like this?
Dim KeyPassFile As String = "..."
Dim UserKeyFile As String = "..."
Dim UserPassFile As String = "..."
Dim KeyPass As New Hashtable
' Read Key:Pass file
For Each Line In IO.File.ReadAllLines(KeyPassFile)
Dim iStart = Line.IndexOf(":")
Dim Key = Line.Substring(0, iStart)
Dim Pass = Line.Substring(iStart + 1)
KeyPass.Add(Key, Pass)
Next
' Create User:Pass file
Dim OutFile = IO.File.CreateText(UserPassFile)
' Read User:Key file
For Each Line In IO.File.ReadAllLines(UserKeyFile)
Dim iStart = Line.IndexOf(":")
Dim User = Line.Substring(0, iStart)
Dim Key = Line.Substring(iStart + 1)
If KeyPass.ContainsKey(Key) Then
' We have a match for the key, write it to the file
OutFile.WriteLine(User & ":" & KeyPass(Key))
End If
Next
OutFile.Close()
This will probably not work for very large files that doesn't fit in memory, and there is no duplicate check for the key insertion in the hashtable, but I'll leave something for you to do.. :)
Also, in your code, you read the file specified in the TextBox2.Text as many times as there are lines in the TextBox1.Text file..

English sentence as input and translates it into Textese

working on a project where I input a text file and write a sentence in an "English" text box and with a click of a button the program translates it into "textese" type of language. It will only change words listed in the text file and ignore everything else. Below is the code I have, and wondering what is going wrong, it fails to run and highlights my If Then statement, so I think my issue is there but not sure what. A few examples of what is in the text file and how they are ordered / separated by a comma.
anyone,ne1
are,r
ate,8
band,b&
be,b
before,b4
busy,bz
computer,puter
Public Class frmTextese
Private Sub btnTranslate_Click(sender As Object, e As EventArgs) Handles btnTranslate.Click
Dim inputData() As String = IO.File.ReadAllLines("Textese.txt")
Dim english As Integer = 0
Dim englishSentence As String = txtEnglish.Text
Dim result() As String = englishSentence.Split(" "c)
Do While english < (result.Length - 1)
Dim line As String
Dim data() As String
Dim englishArray As String
Dim texteseArray As String
For i As Integer = 0 To (inputData.Length - 1)
line = inputData(i)
data = line.Split(","c)
englishArray = line.Split(","c)(0)
texteseArray = line.Split(","c)(1)
If result(i).StartsWith(englishArray(i)) Then
If englishArray(i).Equals(texteseArray(i)) Then
result(i) = texteseArray(i)
End If
End If
txtTextese.Text = result(i)
Next
Loop
End Sub
End Class
You only need to compare result(i) against englishArray. Also, your while loop was an endless loop. When searching the textese array, once you find a match, you can quit searching and go on to the next english word. Finally, you should take care to use variable names that describe their purpose.
Look at this code (untested). I made the string comparison case insensitive, but that is not required.
Private Sub btnTranslate_Click(sender As Object, e As EventArgs) Handles btnTranslate.Click
'Get all the textese definitions
Dim inputData() As String = IO.File.ReadAllLines("Textese.txt")
Dim english As Integer = 0
Dim englishSentence As String = txtEnglish.Text
Dim result() As String = englishSentence.Split(" "c)
Do While english < (result.Length - 1)
Dim line As String
Dim data() As String
Dim englishArray As String
Dim texteseArray As String
For i As Integer = 0 To (inputData.Length - 1)
'Split the textese entry into two parts
line = inputData(i)
data = line.Split(","c)
englishArray = data(0)
texteseArray = data(1)
'Compare the word in the english sentence against the word in the textese array
'using a case insensitive comparison (not required)
If result(i).Equals(englishArray, StringComparison.CurrentCultureIgnoreCase) Then
'Replace the word in the sentence with its textese version
result(i) = texteseArray
'If we found the word, there is no need to continue searching, so
'skip to the next word in the english sentence
Exit For
End If
Next
'Increment the loop counter to avoid an endless loop
english = english + 1
Loop
'Take the elements of the result array and join them together, separated by spaces
txtTextese.Text = String.Join(" ", result)
End Sub

Flesch Readability Index in Visual Basic

I'm working on a program that is supposed to perform the calculations for the Flesch Readability Index. The program is supposed to read in a text file "Project7.txt", it's then supposed to display the text in a multi-line text box and perform the following calculations:
Count the number of words in the file.
Count the number of syllables in the file.
Count the number of sentences in the file (a sentence can be ended by a ".", "?", "!", or ":"
The program is then supposed to plug the values into the following formula and display the result in a label (label1).
206.835-85.6*(Number of syllables/Number of words) - 1.015*(Number of words/Number of sentences)
Here is the code I have written so far.
Option Strict On
Imports System.IO
Public Class Form1
Private Sub ExitToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ExitToolStripMenuItem.Click
Me.Close()
End Sub
Private Sub OpenToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles OpenToolStripMenuItem.Click
Dim open As New OpenFileDialog
open.Filter = "text files |project7.txt|All file |*.*"
open.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)
If open.ShowDialog() = Windows.Forms.DialogResult.OK Then
Dim selectedFileName As String = System.IO.Path.GetFileName(open.FileName)
If selectedFileName.ToLower = "project7.txt" Then
Dim doc As String = ""
Dim line As String
Using reader As New StreamReader(open.OpenFile)
While Not reader.EndOfStream
doc += reader.ReadLine
Console.WriteLine(line)
End While
Dim text = File.ReadAllText("Project7.txt")
Dim words = text.Split(" "c)
Dim wordCount = words.Length
Dim separators As Char() = {"."c, "!"c, "?"c, ":"c}
Dim sentences = text.Split(separators, StringSplitOptions.RemoveEmptyEntries)
Dim sentenceCount = sentences.Length
End Using
Else
MessageBox.Show("You cannot use that file!")
End If
End If
End Sub
Function CountSyllables(word As String) As Integer
word = word.ToLower()
Dim dipthongs = {"oo", "ou", "ie", "oi", "ea", "ee", _
"eu", "ai", "ua", "ue", "au", "io"}
For Each dipthong In dipthongs
word = word.Replace(dipthong, dipthong(0))
Next
Dim vowels = "aeiou"
Dim vowelCount = 0
For Each c In word
If vowels.IndexOf(c) >= 0 Then vowelCount += 1
Next
Return vowelCount
End Function
End Class
Any suggestions are appreciated. Thanks in advance for the help.
Is the code always reporting one more sentence than there actually is?
If so take a look at this from the String.Split method MSDN docs:
When the Split function encounters two delimiters in a row, or a
delimiter at the beginning or end of the string, it interprets them as
surrounding an empty string ("")...
I'm sure your last sentence ends with your sentence delimiter so what's happening is your assignment to sentences is getting an extra, empty array element. See for yourself by breakpointing the line after your assignment and hovering your mouse over sentences. Examine the contents of the array.
The fix is to call Split with the option to remove empty array values. To do that though you'll need to call the Split overload that takes an array of Char for the delimiters:
Replace this line:
Dim sentences = text.Split("."c, "!"c, "?"c, ":"c)
With this:
Dim separators As Char() = {"."c, "!"c, "?"c, ":"c}
Dim sentences = text.Split(separators, StringSplitOptions.RemoveEmptyEntries)
And you should be good.

Search line in text file and return value from a set starting point vb.net

I'm currently using the following to read the contents of all text files in a directory into an array
Dim allLines() As String = File.ReadAllLines(txtfi.FullName)
Within the text files are only 6 lines that all follow the same format and will read something like
forecolour=black
I'm trying to then search for the word "forecolour" and retrieve the information after the "=" sign (black) so i can then populate the below code
AllDetail(numfiles).uPath = ' this needs to be the above result
I've only posted parts of the code but if it helps i can post the rest. I just need a little guidance if possible
Thanks
This is the full code
Dim numfiles As Integer
ReDim AllDetail(0 To 0)
numfiles = 0
lb1.Items.Clear()
Dim lynxin As New IO.DirectoryInfo(zMailbox)
lb1.Items.Clear()
For Each txtfi In lynxin.GetFiles("*.txt")
Dim allLines() As String = File.ReadAllLines(txtfi.FullName)
ReDim Preserve AllDetail(0 To numfiles)
AllDetail(numfiles).uPath = 'Needs to be populated
AllDetail(numfiles).uName = 'Needs to be populated
AllDetail(numfiles).uCode = 'Needs to be populated
AllDetail(numfiles).uOps = 'Needs to be populated
lb1.Items.Add(IO.Path.GetFileNameWithoutExtension(txtfi.Name))
numfiles = numfiles + 1
Next
End Sub
AllDetail(numfiles).uPath = Would be the actual file path
AllDetail(numfiles).uName = Would be the detail after “unitname=”
AllDetail(numfiles).uCode = Would be the detail after “unitcode=”
AllDetail(numfiles).uOps = Would be the detail after “operation=”
Within the text files that are being read there will be the following lines
Unitname=
Unitcode=
Operation=
Requirements=
Dateplanned=
For the purpose of this array I just need the unitname, unitcode & operation. Going forward I will need the dateplanned as when this is working I want to try and work out how to only display the information if the dateplanned matches the date from a datepicker. Hope that helps and any guidance or tips are gratefully received
If your file is not very big you could simply
Dim allLines() As String = File.ReadAllLines(txtfi.FullName)
For each line in allLines
Dim parts = line.Split("="c)
if parts.Length = 2 andalso parts(0) = "unitname" Then
AllDetails(numFiles).uName = parts(1)
Exit For
End If
Next
If you are absolutely sure of the format of your input file, you could also use Linq to remove the explict for each
Dim line = allLines.Where(Function(x) (x.StartsWith("unitname"))).SingleOrDefault()
if line IsNot Nothing then
AllDetails(numFiles).uName = line.Split("="c)(1)
End If
EDIT
Looking at the last details added to your question I think you could rewrite your code in this way, but still a critical piece of info is missing.
What kind of object is supposed to be stored in the array AllDetails?
I suppose you have a class named FileDetail as this
Public class FileDetail
Public Dim uName As String
Public Dim uCode As String
Public Dim uCode As String
End Class
....
numfiles = 0
lb1.Items.Clear()
Dim lynxin As New IO.DirectoryInfo(zMailbox)
' Get the FileInfo array here and dimension the array for the size required
Dim allfiles = lynxin.GetFiles("*.txt")
' The array should contains elements of a class that have the appropriate properties
Dim AllDetails(allfiles.Count) as FileDetail
lb1.Items.Clear()
For Each txtfi In allfiles)
Dim allLines() As String = File.ReadAllLines(txtfi.FullName)
AllDetails(numFiles) = new FileDetail()
AllDetails(numFiles).uPath = txtfi.FullName
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).uName = line.Split("="c)(1)
End If
line = allLines.Where(Function(x) (x.StartsWith("operation="))).SingleOrDefault()
if line IsNot Nothing then
AllDetails(numFiles).uOps = line.Split("="c)(1)
End If
lb1.Items.Add(IO.Path.GetFileNameWithoutExtension(txtfi.Name))
numfiles = numfiles + 1
Next
Keep in mind that this code could be really simplified if you start using a List(Of FileDetails)