i'm trying to importe a csv file after creating on the same application, the only probleme is that even if a string matchs a line from the file, comparing them on vb.net dosn't give a true boolean i know i didn't make any mistakes because of the line with the commentary 'THIS LINE , i use a pretty small list to do my test and in that loop, there is always one element that matches exactly the string, but comparing them on vb.net dosn't return a true. the result of this is that just after saving the file to my computer while still having it on my listview1 on the application, i load it to the application again and it duplicates everything
Dim open As New OpenFileDialog
open.Filter = "CSV Files (*.csv*)|*.csv"
If open.ShowDialog = Windows.Forms.DialogResult.OK Then
Dim File As String = My.Computer.FileSystem.ReadAllText(open.FileName)
Dim lines() As String = File.Split(Environment.NewLine)
For i = 1 To (lines.Count - 1)
Dim line As String = lines(i)
Dim Columns() As String = line.Split(";")
Dim addLin As New ListViewItem(Columns)
Dim Alr As Boolean = False
Dim st as string=listView1.Items.Item(k).SubItems.Item(0).Text
For k = 0 To (ListView1.Items.Count - 1)
Dim st as string=listView1.Items.Item(k).SubItems.Item(0).Text
MsgBox(Columns(0)& Environment.NewLine & st) 'THIS LINE
If ListView1.Items.Item(k).SubItems.Item(0).Text = Columns(0) Then
Alr = True
MsgBox("true") 'never showsup even when the previous one show the match
End If
next
If Alr = False Then
MsgBox("false") 'the msgbox is only to check
ListView1.Items.Add(addLin)
End If
next
end if
Related
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
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.
EDIT: How would I go about retrieving the filename of the files that meet said conditions?
How I can check if a string contains "value1" but doesn't have "value2"? I tried this:
While Not sr.EndOfStream
Dim sLine As String = sr.ReadLine
If sLine.Contains("value1") Then
If Not sLine.Contains("value2") Then
sw.WriteLine("write name of file that meets conditions to txt file")
End While
Not sure how to go about searching for the missing value.
You could load the whole file in a string and do the check
If wholeFileData.Contains("value1") AndAlso Not wholeFileData.Contains("value2") Then
sw.WriteLine("write name of file that meets conditions to txt file")
End If
If you are need to loop each line, then you'll need to store in a variable and show the message at the end.
Dim containsValue1, containsValue2 As Boolean
containsValue1 = False
containsValue2 = False
While Not sr.EndOfStream
Dim sLine As String = sr.ReadLine
If sLine.Contains("value1") Then
containsValue1 = True
End If
If sLine.Contains("value2") Then
containsValue2 = True
End If
End While
If containsValue1 AndAlso Not containsValue2 Then
sw.WriteLine("write name of file that meets conditions to txt file")
End If
If sLine.Contains("value1") = True and sLine.Contains("value2") = False Then
Msgbox("sLine contains value1, but does not contain value2")
End If
I am saving a .csv file in my directory by giving the path with StreamWriter. Now i want to give the option to user to save that file desired path. how can it. help me somebody.
Dim objStreamWriter = New IO.StreamWriter("c:\FaultTypesByMonth.csv")
Dim Str As String
Dim i As Integer
Dim j As Integer
Dim headertext1(rsTerms.Columns.Count) As String
Dim k As Integer = 0
Dim arrcols As String = Nothing
For Each column As DataColumn In TempTab.Columns
headertext1(k) = column.ColumnName
arrcols += column.ColumnName.ToString() + ","c
k += 1
Next
objStreamWriter.WriteLine(arrcols)
For i = 0 To (TempTab.Rows.Count - 1)
For j = 0 To (TempTab.Columns.Count - 1)
'this IF statement stops it from adding a comma after the last field
If j = (TempTab.Columns.Count - 1) Then
Str = (TempTab.Rows(i)(j).ToString)
Else
Str = (TempTab.Rows(i)(j).ToString & ",")
End If
objStreamWriter.Write(Str)
Next
objStreamWriter.WriteLine()
Next
objStreamWriter.Close()
' After save the file in C:/ I want to save the same file in any other Path for my convenience.
'------------------------------------------------------------------------------------------------
Dim sd As New SaveFileDialog
sd.Filter = "CSV Files (*.csv)|*.csv"
sd.FileName = "FaultTypesByMonth"
If sd.ShowDialog = Windows.Forms.DialogResult.OK Then
'save the file here
Debug.WriteLine("Save file location:" + sd.FileName)
End If
If it's a console application you could read a path argument from the command line.
If it's a GUI application you can show a save file dialog box, in WinForms use the SaveFileDialog class.
To save a file to different locations put the writer code in a function which takes the file path as an argument:
Sub SaveFile(filePath As String)
Dim objStreamWriter = New IO.StreamWriter(filePath)
' ... your code here
End Sub
Sub ButtonClick
SaveFile("c:\FaultTypesByMonth.csv")
' ... SaveFileDialog code
SaveFile(sd.Filename)
End Sub
To copy a file use File.Copy:
' ... SaveFileDialog code
File.Copy("c:\FaultTypesByMonth.csv", sd.Filename)
Use the SaveFileDialog class
Simple example:
Private Sub SaveFile()
Dim sd As New SaveFileDialog
sd.Filter = "CSV Files (*.csv)|*.csv"
If sd.ShowDialog = Windows.Forms.DialogResult.OK Then
'save the file here
Debug.WriteLine("Save file location:" + sd.FileName)
End If
End Sub
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)