DataGridView skipping lines VB.net - vb.net

I'm displaying data from a .txt file into a datagridview which works fine but once I press the button to display another line of data the datagridview row cell is skipping 7 lines. I don't know if this problem can be resolved in the datagridview properties or in the code itself. I have tried each way but have been unsuccessful in finding a solution
Private Sub btn1_Click(sender As Object, e As EventArgs) Handles btn1.Click
Dim rowvalue As String
Dim cellvalue(0) As String
Dim streamReader As IO.StreamReader = NewIO.StreamReader("button1.txt")
'Reading CSV file content
While streamReader.Peek() <> -1
rowvalue = streamReader.ReadLine()
cellvalue = rowvalue.Split(","c) 'Separating
DataGridView1.Rows.Add(cellvalue)
End While
End Sub

Related

Importing data from text file in VB.NET

So, I am trying to develop a book database. I have created a table with 11 columns which populates a DGV, where only 6 columns are showed. The full data of each book is shown in a lower part of the form, where I have textboxes, which are bounded (BindingSource) to the table, that change as I move in the DGV.
Now, what I want to do is to have the posibility to export/import data from a file.
I have accomplished the exporting part with the following code:
Private Sub BtnExport_Click(sender As Object, e As EventArgs) Handles BtnExport.Click
Dim txt As String = String.Empty
For Each row As DataGridViewRow In DbdocsDataGridView.Rows
For Each cell As DataGridViewCell In row.Cells
'Add the Data rows.
txt += CStr(cell.Value & ","c)
Next
'Add new line.
txt += vbCr & vbLf
Next
Dim folderPath As String = "C:\CSV\"
File.WriteAllText(folderPath & "DataGridViewExport.txt", txt)
End Sub
However, I can't manage to import from the txt. What I've tried is this: https://1bestcsharp.blogspot.com/2018/04/vb.net-import-txt-file-text-to-datagridview.html
It works perfectly if you code the table and it populates de DGV without problem. I can't see how should I adapt that code to my need.
Private Sub BtnImport_Click(sender As Object, e As EventArgs) Handles BtnImport.Click
DbdocsDataGridView.DataSource = table
Dim filas() As String
Dim valores() As String
filas = File.ReadAllLines("C:\CSV\DataGridViewExport.txt")
For i As Integer = 0 To filas.Length - 1 Step +1
valores = filas(i).ToString().Split(",")
Dim row(valores.Length - 1) As String
For j As Integer = 0 To valores.Length - 1 Step +1
row(j) = valores(j).Trim()
Next j
table.Rows.Add(row)
Next i
End Sub
That is what I've tried so far, but I always have an exception arising.
Thanks in advance to anyone who can give me an insight about this.
The DataTable class has built-in methods to load/save data from/to XML called ReadXml and WriteXml. Take a look at example which uses the overload to preserve the schema:
Private ReadOnly dataGridViewExportPath As String = IO.Path.Combine("C:\", "CSV", "DataGridViewExport.txt")
Private Sub BtnExport_Click(sender As Object, e As EventArgs) Handles BtnExport.Click
table.WriteXml(path, XmlWriteMode.WriteSchema)
End Sub
Private Sub BtnImport_Click(sender As Object, e As EventArgs) Handles BtnImport.Click
table.ReadXml(path)
End Sub
While users can manually edit the XML file that is generated from WriteXML, I would certainly not suggest it.
This is code which writes to a text file:
speichern means to save.
Note that I use a # in my example for formatting reasons. When reading in again, you can find the # and then you know that and that line is coming...
And I used Private ReadOnly Deu As New System.Globalization.CultureInfo("de-DE") to format the Date into German format, but you can decide yourself if you want that. 🙂
Note that I'm using a FileDialog that I downloaded from Visual Studio's own NuGet package manager.
Private Sub Button_speichern_Click(sender As Object, e As EventArgs) Handles Button_speichern.Click
speichern()
End Sub
Private Sub speichern()
'-------------------------------------------------------------------------------------------------------------
' User can choose where to save the text file and the program will save it .
'-------------------------------------------------------------------------------------------------------------
Dim Path As String
Using SFD1 As New CommonSaveFileDialog
SFD1.Title = "store data in a text file"
SFD1.Filters.Add(New CommonFileDialogFilter("Textdatei", ".txt"))
SFD1.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
If SFD1.ShowDialog() = CommonFileDialogResult.Ok Then
Path = SFD1.FileName & ".txt"
Else
Return
End If
End Using
Using textfile As System.IO.StreamWriter = My.Computer.FileSystem.OpenTextFileWriter(Path, True, System.Text.Encoding.UTF8)
textfile.WriteLine("Timestamp of this file [dd.mm.yyyy hh:mm:ss]: " & Date.Now.ToString("G", Deu) & NewLine & NewLine) 'supposed to be line break + 2 blank lines :-)
textfile.WriteLine("your text")
textfile.WriteLine("#") 'Marker
textfile.Close()
End Using
End Sub
Private Sub FormMain_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
speichern()
End Sub
And this is to read from a text file:
'read all Text
Dim RAT() As String = System.IO.File.ReadAllLines(Pfad, System.Text.Encoding.UTF8)
If RAT.Length = 0 Then Return Nothing
For i As Integer = 0 To RAT.Length - 1 Step 1
If RAT(i) = "#" OrElse RAT(i) = "" Then Continue For
'do your work here with (RAT(i))
Next

Reference Form2.DataGridView from code on Form1

I am new to this forum. This is my first post, though I have spent a lot of time here searching for answers.
I have used VBA in Excel for many years, but have recently started using VB in Visual Studio 2015. I have created Form 1 as a MDIContainer and have another form opened inside this. This form (FormXYZ) contains a DataGridView.
Form1 has a MenuStrip and a I am currently trying to write the code, when one of these menu items is selected, to populate the DGV from a CSV. At this stage I am only trying to read the data and then I will work on the code to split the strings up.
Screenshot
I have no problem with selecting a file to import and the streamreader appears to read the file, but no data makes it to the DGV.
When I tried putting the code on FormXYZ for a button click event, the DGV was populated. So I believe the error is due to the way I am referencing the DGV, as the code for the MenuStrip_Click event is on Form1, but the DGV is on FormXYZ.
I would appreciate if somebody could point out where I am going wrong. My code is shown below.
Thanks Tepede
Imports System.IO
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim FormXYZ As New FormXYZ()
FormXYZ.MdiParent = Me 'Set the Parent Form of the Child window.
FormXYZ.Show() 'Display the XYZ form.
End Sub
'-------------------------------------
'StripMenu click command to import CSV
Public Sub TSMIFileImportCSV_Click(sender As Object, e As EventArgs) Handles TSMIFileImportCSV.Click
Dim Filename As String
Dim RowValue As String
Dim OpenFile As OpenFileDialog = New OpenFileDialog()
'Open file dialog
With OpenFile
.Filter = "CSV (*.CSV)|*.csv"
.FilterIndex = 1
.InitialDirectory = "C:\"
.Title = "Open File"
.CheckFileExists = False
End With
If OpenFile.ShowDialog() = DialogResult.OK Then
Filename = OpenFile.FileName
End If
'---------
' Read CSV file content
Dim objReader As StreamReader = New StreamReader(Filename)
While objReader.Peek() <> -1
RowValue = objReader.ReadLine()
'Fist column is Boolean, the second should have the data from the CSV file
FormXYZ.DataGridView1.Rows.Add(True, RowValue, "Test", "Test")
End While
objReader.Close()
End Sub
It looks like you are losing your instance to the FormXYZ that you displayed due to it's definition being in the Form Load. Expand the scope of that variable to be at the class level.
Public Class Form1
Private FormXYZ As FormXYZ
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
FormXYZ = New FormXYZ()
FormXYZ.MdiParent = Me 'Set the Parent Form of the Child window.
FormXYZ.Show() 'Display the XYZ form.
End Sub

Getting strings from a textfile in a combobox, vb.net

Here is my code :
I'm trying to have some value out from a TXT file to a combobox or label but i feel combobox would be easier.
here's my code :
please note, some config.txt will only have 1 value while other 5-6
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim IDinFile As String
Dim ID As String
If IO.File.Exists("config.txt") Then
Using StreamReader As New IO.StreamReader("config.txt")
Do
IDinFile = StreamReader.ReadLine
If (IDinFile.IndexOf("7656")) <> -1 Then
ID = IDinFile.Substring(2)
ID = ID.Trim().Remove(ID.Length - 1)
ComboBox1.Items.Add(ID)
Exit Do
End If
Loop Until IDinFile Is Nothing
End Using
End If
End Sub
the file here in .png :
https://i.stack.imgur.com/iYaqP.png
Re-written the code for you. Problem was wrongly placed Exit Do. Also, its advisable to check the line before entering the loop rather than at the end of the loop.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim IDinFile As String
Dim ID As String
Const FILENAME As String = "config.txt"
If IO.File.Exists(FILENAME) Then
Using StreamReader As New IO.StreamReader(FILENAME)
Do While StreamReader.Peek() >= 0
IDinFile = StreamReader.ReadLine.Trim()
If (IDinFile.IndexOf("7656")) <> -1 Then
ID = IDinFile.Substring(1, IDinFile.Length - 2)
ComboBox1.Items.Add(ID)
End If
Loop
End Using
End If
End Sub
After you add the first item to the combobox you have an Exit Do statement. It no longer continues checking further lines and adding them to the combobox.
You should remove that statement.
Try this. It'll work if the values are organized line by line in the txt file.
Dim srd as New StreamReader("config.txt")
If io.file.exists("config.txt") then
Dim str() = srd.ReadToEnd.split(environment.newline)
For i = 0 to str.count-1
Combobox.item.add(str(i))
Next
srd.close

Openfile on event

I am getting my feet wet with VB .Net programming (total novice). I have a DataGridView with amongst other information, a file path to where a particular document is stored. I have added a DataGridViewButtonColumn to the DataGridView, but I cannot figure out how to get the button to open the file.
Sorry, I have no code to provide as starting point for where I get stuck.
Thanks in advance,
Sorry I didn't read the post clear enough the first time, and didn't explain my code enough so it got deleted. This uses the contentclick event.
Dim Filetext As String = "" 'At start of the class to make it available to the whole class
Private Sub DataGridView1_CellContentClick(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
Dim FilePathColumn As Integer = 0 'File path is in Column 0
Dim ButtonColumn As Integer = 1 'Column buttons are in
Dim RowClicked As Integer = e.RowIndex 'This gets the row that you clicked the button in
If e.ColumnIndex = ButtonColumn Then 'Make sure you clicked a button
Dim FILE_PATH As String = DataGridView1.Rows(RowClicked).Cells(FilePathColumn).ToString 'Get the path to the file
If System.IO.File.Exists(FILE_PATH) Then 'Make sure file exists
Filetext = System.IO.File.ReadAllText(FILE_PATH) 'Save file to a variable
'OR
Process.Start(FILE_PATH) 'To open it
End If
End If
End Sub
You can get rid of most of those lines but I wrote it like that to explain how it worked

How to filter unbound datagridview with textbox vb.net?

I'm a complete rookie. I learned so much from here but this one I can't find the answer to. I'm using Visual Studio Pro 2015.
I have a windows form application that has a single column datagridview that is populated by reading a textfile, line by line at runtime. Each time the contents of the textfile will be different.
I want the user to be able to filter the list in the datagridview by entering characters in a textbox. The data is not "bound" to the datagridview, because at this point I don't know if that is necessary, and I don't completely understand it.
This is the code that I have for loading the datagridview, and the textbox is called txtFilter.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'read all lines from the file into a string array (one line per string)
Dim lines() As String = My.Computer.FileSystem.ReadAllText("c:\list_in.txt").Replace(vbLf, "").Split(vbCr)
Dim dgrow As DataGridViewRow
Dim dgcell As DataGridViewCell
'insert each line of input into a row in the datagrid
For Each line As String In lines
dgrow = New DataGridViewRow
dgcell = New DataGridViewTextBoxCell
If line <> "" Then
dgcell.Value = line
dgrow.Cells.Add(dgcell)
DataGridView1.Rows.Add(dgrow)
End If
Next
DataGridView1.Columns("ObjectName").ReadOnly = True
DataGridView1.ClearSelection()
End Sub
Edit:
Looking at your solution, I would advise you execute Dim lines() As String = My.Computer.FileSystem.ReadAllText("c:\list_in.txt").Replace(vbLf, "").Split(vbCr) outside of the txtFilter_TextChanged sub, as otherwise you are importing the entire list every time the user enters a key, which is unnecessary. If the list may change while the user is using the program, I'd instead recommend adding a 'refresh' button, especially if your text file could be a long one.
You also added a couple lines of code to remove the sound when the user presses the Enter key. If the user is expected to press the enter key to search, then you don't need to update the DataGridView every time the user enters a new character in the textbox. This would be easier on memory, and again very beneficial if you have a large text file.
I'm sure there's an easier way, but here's my approach.
Private Sub txtFilter_TextChanged(sender As Object, e As EventArgs) Handles txtFilter.TextChanged
Dim searchedlines(-1) As String 'create an array to fill with terms that match our search
If txtFilter.Text = Nothing Then
datapopulate(lines) 'just populate the datagridview with our text file array
Else
For Each line In lines
If line Like "*" & txtFilter.Text & "*" Then 'check if anything in our search matches any of our terms
ReDim Preserve searchedlines(UBound(searchedlines) + 1) 'resize the array to fit our needs
searchedlines(UBound(searchedlines)) = line 'add the matched line to our array
End If
Next
datapopulate(searchedlines) 'populate the datagrid with our matched terms array
End If
End Sub
Private Sub datapopulate(ByVal mylist)
Dim dgrow As DataGridViewRow
Dim dgcell As DataGridViewCell
DataGridView1.Rows.Clear() 'clear the grid
For Each line As String In mylist 'do the same thing here that we did on form load
dgrow = New DataGridViewRow
dgcell = New DataGridViewTextBoxCell
dgcell.Value = line
dgrow.Cells.Add(dgcell)
DataGridView1.Rows.Add(dgrow)
Next
End Sub
What I did is created a sub that handles whenever the text in txtFilter is changed. Alternatively, you could run that code in a sub that handles a button click. Given that, from what I know, ReDim can be a costly item in terms of memory usage, if your text document was hundreds of lines long, you might want it on a button click instead. You could probably use a list, but I haven't played around enough to know how to go about doing that.
An important note: in order for the sub txtFilter_TextChanged to be able to see lines(), I defined it outside of a sub but inside of your main class, so that all subs could access it, like so:
Public Class Form1
Dim lines() As String = My.Computer.FileSystem.ReadAllText("c:\list_in.txt").Replace(vbLf, "").Split(vbCr)
'...subs here...
End Class
I hope this helps you get started!
I have a solution working. Thank you very much.
Private Sub txtFilter_TextChanged(sender As Object, e As EventArgs) Handles txtFilter.TextChanged
'read all lines from the file into a string array (one line per string)
Dim lines() As String = My.Computer.FileSystem.ReadAllText("c:\list_in.txt").Replace(vbLf, "").Split(vbCr)
Dim dgrow As DataGridViewRow
Dim dgcell As DataGridViewCell
DataGridView1.Rows.Clear()
'insert each line of input into a row in the datagrid
For Each line As String In lines
dgrow = New DataGridViewRow
dgcell = New DataGridViewTextBoxCell
If line.Contains(txtFilter.Text) Then
dgcell.Value = line
dgrow.Cells.Add(dgcell)
DataGridView1.Rows.Add(dgrow)
End If
Next
DataGridView1.Columns("ObjectName").ReadOnly = True
DataGridView1.ClearSelection()
End Sub
And I also found this to eliminate the bell from ringing when the user pressed the enter key when entering the filter text.
Private Sub txtFilter_KeyPress(sender As Object, e As KeyPressEventArgs) Handles txtFilter.KeyPress
' this keeps the bell from ringing when the user presses the 'enter' key
If Asc(e.KeyChar) = 13 Then
e.Handled = True
End If
End Sub