DataGridView to CSV File - vb.net

I have a VB 2010 Express Project, that has a DataGridView in it, that I am trying to write to a CSV file.
I have the write all working. But its slow. Slow = maybe 30 seconds for 6000 rows over 8 columns.
Here is my code:
Private Sub btnExportData_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExportData.Click
Dim StrExport As String = ""
For Each C As DataGridViewColumn In DataGridView1.Columns
StrExport &= """" & C.HeaderText & ""","
Next
StrExport = StrExport.Substring(0, StrExport.Length - 1)
StrExport &= Environment.NewLine
For Each R As DataGridViewRow In DataGridView1.Rows
For Each C As DataGridViewCell In R.Cells
If Not C.Value Is Nothing Then
StrExport &= """" & C.Value.ToString & ""","
Else
StrExport &= """" & "" & ""","
End If
Next
StrExport = StrExport.Substring(0, StrExport.Length - 1)
StrExport &= Environment.NewLine
Next
Dim tw As IO.TextWriter = New IO.StreamWriter("C:\Test1.CSV")
tw.Write(StrExport)
tw.Close()
End Sub
Does anyone know what I can do to speed it up?
thanks

Don't you just love it when you spend hours searching, then post a question, and a few minutes later find the answer yourself?
This did the trick for me:
Dim headers = (From header As DataGridViewColumn In DataGridView1.Columns.Cast(Of DataGridViewColumn)() _
Select header.HeaderText).ToArray
Dim rows = From row As DataGridViewRow In DataGridView1.Rows.Cast(Of DataGridViewRow)() _
Where Not row.IsNewRow _
Select Array.ConvertAll(row.Cells.Cast(Of DataGridViewCell).ToArray, Function(c) If(c.Value IsNot Nothing, c.Value.ToString, ""))
Using sw As New IO.StreamWriter("csv.txt")
sw.WriteLine(String.Join(",", headers))
For Each r In rows
sw.WriteLine(String.Join(",", r))
Next
End Using
Process.Start("csv.txt")

Related

Writing multiple selected DataGridView rows to CSV

The code below successfully allows for me to write a selected row to a .csv file.
I'm having problems where, when I select multiple rows and try and write it to the file, it puts all of the row on the same line of the .csv file.
How can I modify the code below so that it allows for multiple rows to be selected, and it writes each row to a new line of the .csv file?
Dim StrExport As String = ""
For Each C As DataGridViewColumn In dataGVGeneral.Columns
StrExport &= "" & C.HeaderText & ","
Next
StrExport = StrExport.Substring(0, StrExport.Length - 1)
StrExport &= Environment.NewLine
'Only the row which is selected will be written
For Each R As DataGridViewRow In dataGVGeneral.Rows
If R.Selected = True Then
For Each C As DataGridViewCell In R.Cells
If Not C.Value Is Nothing Then
StrExport &= "" & C.Value.ToString & ","
Else
StrExport &= "" & "" & ","
End If
Next
Else
StrExport = StrExport.Substring(0, StrExport.Length - 1)
StrExport &= Environment.NewLine
End If
Next
Dim tw As System.IO.TextWriter = New System.IO.StreamWriter("E:\SAT\Work.io\Work.io\bin\Debug\Session.csv", False)
tw.Write(StrExport)
tw.Close()
On the line StrExport = StrExport.Substring(0, StrExport.Length - 1), I think you meant to use &= instead of =.
However, you should be using a StringBuilder to create the string because it is more efficient when concatenating more than about ten pieces of string together.
To join strings together with a comma/anything else between, String.Join is useful because you don't have to worry about the final comma.
And finally, with a little bit of LINQ you can make the code quite a bit shorter but still fairly easy to understand:
Private Sub bnSaveSelected_Click(sender As Object, e As EventArgs) Handles bnSaveSelected.Click
Dim sb As New Text.StringBuilder()
sb.AppendLine(String.Join(",", dataGVGeneral.Columns.Cast(Of DataGridViewColumn).Select(Function(c) c.HeaderText)))
For Each dr As DataGridViewRow In dataGVGeneral.Rows
If dr.Selected Then
sb.AppendLine(String.Join(",", dr.Cells.Cast(Of DataGridViewCell).Select(Function(c) c.Value.ToString())))
End If
Next
IO.File.WriteAllText("C:\temp\SampleCsv.csv", sb.ToString())
End Sub

Write DataGridView to TextFile Duplicate Lines based on Grid Cell QTY

I have a routine that produces a text file based on the contents of a DataGridView.
the scenario is this.
Sales Order line [Item Name[ [Quantity]
the solution is to produce a text file for each quantity. currently my routine only produces a line for each order line, not each quantity.
If for example its current row, column 6.
Try
Dim StrExport As String = ""
For Each C As DataGridViewColumn In DataGridView1.Columns
StrExport &= "" & C.HeaderText & ","
Next
StrExport = StrExport.Substring(0, StrExport.Length - 1)
StrExport &= Environment.NewLine
For Each R As DataGridViewRow In DataGridView1.Rows
For Each C As DataGridViewCell In R.Cells
If Not C.Value Is Nothing Then
StrExport &= "" & C.Value.ToString & ","
Else
StrExport &= "" & "" & ","
End If
Next
StrExport = StrExport.Substring(0, StrExport.Length - 1)
StrExport &= Environment.NewLine
Next
Dim tw As IO.TextWriter = New IO.StreamWriter(SaveFileDialog1.FileName)
tw.Write(StrExport)
tw.Close()
My.Computer.FileSystem.RenameFile(SaveFileDialog1.FileName, "FRLSTicket.txt")
Catch ex As Exception
MsgBox(ex.Message)
End Try
Try
DataGridView1.Refresh()
Catch ex As Exception
End Try
a sample row might be
SalesID,QTY,CustomerName,ItemID,Name,LegColour
SO1234567,3,John Smith ,Chair,Comfortable Blue Chair,Walnut

Only column text appears when csv file is imported to datagridview vb.net

This is my first vb.net program, so please bear with me if my question is very mediocre.
Before mentioning my problem, the mechanism of my accounting program is that if the user would input data into the datagridview and export it, so that when he restarts the program, he can import the exported data.
I have imported this .csv file to my datagridview
The problem is that when I have imported it, only column texts would appear like this.
This is the export code that I have used to create the .csv file.
Private Sub ExportToExcelToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ExportToExcelToolStripMenuItem.Click
Dim msg1 = "Export Successful"
Dim title = "Excel Export"
MsgBox(msg1, , title)
Try
Dim iexport1 As String = ""
Dim eexport1 As String = ""
For Each C As DataGridViewColumn In Income.Columns
iexport1 &= """" & C.HeaderText & ""","
Next
iexport1 = iexport1.Substring(0, iexport1.Length - 1)
iexport1 &= Environment.NewLine
For Each R As DataGridViewRow In Income.Rows
For Each C As DataGridViewCell In R.Cells
If Not C.Value Is Nothing Then
iexport1 &= """" & C.Value.ToString & ""","
Else
iexport1 &= """" & "" & ""","
End If
Next
iexport1 = iexport1.Substring(0, iexport1.Length - 1)
iexport1 &= Environment.NewLine
Next
For Each C As DataGridViewColumn In Expense.Columns
eexport1 &= """" & C.HeaderText & ""","
Next
eexport1 = eexport1.Substring(0, eexport1.Length - 1)
eexport1 &= Environment.NewLine
For Each R As DataGridViewRow In Expense.Rows
For Each C As DataGridViewCell In R.Cells
If Not C.Value Is Nothing Then
eexport1 &= """" & C.Value.ToString & ""","
Else
eexport1 &= """" & "" & ""","
End If
Next
eexport1 = eexport1.Substring(0, eexport1.Length - 1)
eexport1 &= Environment.NewLine
Next
Dim tw As IO.TextWriter = New IO.StreamWriter(path:="C:\Users\S2009516\Desktop\JanuaryIncome.CSV")
tw.Write(iexport1)
tw.Close()
Dim tw2 As IO.TextWriter = New IO.StreamWriter(path:="C:\Users\S2009516\Desktop\JanuaryExpense.CSV")
tw2.Write(eexport1)
tw2.Close()
Catch ex As Exception
End Try
End Sub
And this is the one I have used for importing csv file.
Private Sub ImportFromExcelToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ImportFromExcelToolStripMenuItem.Click
Dim expenseload1 As String = "C:\Users\S2009516\Desktop\JanuaryExpense.CSV"
Dim incomeload1 As String = "C:\Users\S2009516\Desktop\JanuaryIncome.CSV"
Try
Dim expensereader1 As New StreamReader(expenseload1, Encoding.Default)
Dim incomereader1 As New StreamReader(incomeload1, Encoding.Default)
Dim eline As String = ""
Dim iline As String = ""
Do
eline = expensereader1.ReadLine
iline = incomereader1.ReadLine
If eline Is Nothing Then Exit Do
If iline Is Nothing Then Exit Do
Dim words() As String = eline.Split(",")
Dim words2() As String = iline.Split(",")
Income.Rows.Add("")
Expense.Rows.Add("")
For ix As Integer = 0 To 3
Me.Income.Rows(Income.Rows.Count - 1).Cells(ix).Value = words2(ix)
Me.Expense.Rows(Income.Rows.Count - 1).Cells(ix).Value = words(ix)
Next
Loop
expensereader1.Close()
incomereader1.Close()
Catch ex As Exception
End Try
End Sub
I have no clue on why this is happening... I have followed all the steps in the tutorial video.. Please save my soul... I have been stuck with this for 2 days already.

How can I export the datagridview to .csv without headers?

My csv file is like this
There is no blank spaces or whatsoever.
The problem as you can see is that I do not know how to export my datagridview as .csv excluding column headers.
This is how I have done my export code:
Private Sub IncomeToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles IncomeToolStripMenuItem.Click
Dim saveFileDialog1 As New SaveFileDialog()
saveFileDialog1.Filter = "CSV|*.csv"
saveFileDialog1.RestoreDirectory = True
If saveFileDialog1.ShowDialog() = DialogResult.OK Then
Dim incomefile As String = String.Empty
For Each column As DataGridViewColumn In Expense.Columns
incomefile = incomefile & column.HeaderText & ","
Next
incomefile = incomefile.TrimEnd(",")
incomefile = incomefile & vbCr & vbLf
For Each row As DataGridViewRow In Expense.Rows
For Each cell As DataGridViewCell In row.Cells
incomefile = incomefile & cell.FormattedValue.replace(",", "") & ","
Next
incomefile = incomefile.TrimEnd(",")
incomefile = incomefile & vbCr & vbLf
Next
System.IO.File.WriteAllText(saveFileDialog1.FileName, incomefile)
End If
Dim msg1 = "Export Successful"
Dim title = "Excel Export"
MsgBox(msg1, , title)
End Sub
Please advise me. Some others mentioned that I'd better off use datatable to export it, but since I started to learn computer programming 43 hours ago, I have no clue on how to declare the data i have put in my datagridview and export it as csv file.
Remove those lines
For Each column As DataGridViewColumn In Expense.Columns
incomefile = incomefile & column.HeaderText & ","
Next
Give this a try.
Private Sub BtnExport_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnExport.Click
SFD.InitialDirectory = "C:\"
SFD.Title = "Save Your File"
SFD.Filter = "Microsoft Excel(*.xls)|*.xls|Comma Delimited File(*.csv)|*.Csv"
SFD.OverwritePrompt = True
SFD.ShowDialog()
strFileName = SFD.FileName
' If SFD.ShowDialog() = DialogResult.OK Then
If SFD.FilterIndex = 1 Then
Call export()
Else
Call csv()
End If
' End If
End Sub
Also, try it this way.
Dim numCols As DataGridViewCell
Dim sw As New System.IO.StreamWriter("d:\\output.txt")
For Each numRows As DataGridViewRow In DataGridView1.Rows
Dim intCellCount As Integer = numRows .Cells.Count
Dim intCounter As Integer = 1
For Each numCols In numRows .Cells()
If intCounter <> intCellCount Then
sw.Write(numCols .Value.ToString & ",")
Else
sw.WriteLine(numCols .Value.ToString)
End If
intCounter += 1
Next
Next

How to check whether a string value is present in a DataGridView

Im working on a code that has a TextBox, A Button and a Datagrid view.
I want to Display "Data Not Exist" when a value in TextBox is not present on the DataGridView when i press the button.
This is my code so far
If DataGridView1.Rows.Contains(TextBox1.Text) = False Then
MessageBox.Show("Data Not Exist!")
End If
You need to loop through all rows and columns
Dim isFound As Boolean = False
For Each row As GridViewRow In DataGridView1.Rows
for i As Integer = 0 to DataGridView1.Columns.Count -1
If row.Cells[i].Text = TextBox1.text Then
isFound = True
exit for
End If
Next
Next
If (isFound) Then
MessageBox.Show("Data Exists!")
Else
MessageBox.Show("Data Not Exists!")
EndIf
You can do it easily with either using a LINQ or a ForLoop
This code will search all matches it will find across the DataGridView and will prompt in which Row and Column it sees the match.
With a ForLoop, you need to run a loop for Column and for the Row.
Private Sub SearchUsingForLoop()
Dim resultString As String = Nothing
For x = 0 To DataGridView1.ColumnCount - 1
For y = 0 To DataGridView1.RowCount - 1
If DataGridView1.Item(x, y).Value.ToString.ToUpper = txtSearch.Text.ToUpper Then
resultString &= " - Column " & x + 1 & " Row " & y + 1 & vbCrLf
End If
Next
Next
If resultString <> Nothing Then
resultString = txtSearch.Text & " found in : " & vbCrLf & resultString
Else
resultString = "Data does not exist."
End If
MsgBox(resultString)
End Sub
Do remember that index of DatagridViewRow and DatagridViewColumn starts with 0.
Another way of doing this is by LINQ:
Private Sub SearchUsingLINQ()
Dim resultSet = From dgRow As DataGridViewRow In Me.DataGridView1.Rows, _
dgCell As DataGridViewCell In dgRow.Cells _
Where dgCell.Value.ToString.ToUpper = txtSearch.Text.ToUpper _
Select dgCell
Dim resultString As String = Nothing
If resultSet.Count > 0 Then
resultString = txtSearch.Text & " found in :" & vbCrLf
For Each dgCells In resultSet
resultString &= " - Column " & dgCells.ColumnIndex + 1 & " Row " & dgCells.RowIndex + 1 & vbCrLf
Next
End If
If resultString <> Nothing Then
MsgBox(resultString)
Else
MsgBox("Data does not exist.")
End If
End Sub
Feel free to use any of those. But I suggest you to study iterating a DataGridView first.