Converting a comma delimited string to a datatable row in VB.NET - vb.net

I am trying to convert a string with data separated by commas into the first row of a datatable. The datatable is otherwise empty.
The datatable will then need to populate into datagridview, however nothing appears in it.
Dim plt As New System.Data.DataTable
Dim rowData As String() = output.Split(New Char() {","}, StringSplitOptions.RemoveEmptyEntries)
Dim row As DataRow = PLT.NewRow()
dataGridView1.DataSource = PLT
I don't get any errors, but it's also not populating the gridview so I don't know if it's just failing to populate or if the table itself never got populated from the string.

You need to add the columns and then the row:
Dim rowData As String() = output.Split(New Char() {","c}, StringSplitOptions.RemoveEmptyEntries)
Dim plt As New System.Data.DataTable()
For i As Int32 = 1 To rowData.Length
plt.Columns.Add(String.Format("Column {0}", i))
Next
Dim newRow As DataRow = plt.Rows.Add() ' already added now '
For col As Int32 = 0 To rowData.Length - 1
newRow.SetField(col, rowData(col))
Next

DataTable need DataColumn for every item of array.
If you want add array of string to DataGridView then add it straight.
Dim rowData As String() = output.Split(New Char() {","},
StringSplitOptions.RemoveEmptyEntries)
Me.dataGridView1.Rows.Add(rowData )

Related

how to create CSV string from DataTable in VB.NET?

I'm fetching data from database as a DataTable and need to convert into CSV string in VB.NET.
Create a generic method with DataTable, CSV Headers, DataTable Columns parameters:
Private Function CSVBuilder(dt As DataTable, headers As List(Of String), columns As List(Of String)) As String
Dim sCSV = New StringBuilder(String.Join(",", headers))
sCSV.Append(Environment.NewLine)
Dim view As New DataView(dt)
Dim tDt As DataTable = view.ToTable(True, columns.ToArray)
For Each row As DataRow In tDt.Rows
'-- Handle comma
sCSV.Append(String.Join(",", (From rw In row.ItemArray Select If(rw.ToString.Trim.Contains(","), String.Format("""{0}""", rw.ToString.Trim), rw.ToString.Trim))))
sCSV.Append(Environment.NewLine)
Next
Return sCSV.ToString
End Function
And then call in your code to get CSV string:
CSVBuilder(dataTable,
New List(Of String) From {"Header Column 1", "Header Column 2", ...},
New List(Of String) From {"DataTableColumn1", "DataTableColumn2", ...})
In response to the comment, since this wouldn't fit in that space:
Private Function CSVBuilder(dt As DataTable) As String
Dim sCSV As New StringBuilder()
'Headers
Dim delimeter As String = ""
For Each col As String In dt.Columns.Select(Func(col) col.ColumnName)
If col.Contains(",") Then col = """" & col & """"
sCSV.Append(delimeter).Append(col)
delimeter = ","
Next
sCSV.AppendLine()
For Each row As DataRow In tDt.Rows
sCSV.AppendLine(String.Join(",", (From rw In row.ItemArray Select If(rw.ToString.Trim.Contains(","), String.Format("""{0}""", rw.ToString.Trim), rw.ToString.Trim))))
Next
Return sCSV.ToString
End Function
Now, I did remove this code:
Dim view As New DataView(dt)
Dim tDt As DataTable = view.ToTable(True, columns.ToArray)
But I wouldn't do this as part of the CSVBuilder() method. If you want to project a specific view of a table, I would do that separately from creating the CSV data. You could make a separate method for it:
Public Function GetProjection(dt As DataTable, columns As IEnumerable(Of String)) As DataTable
Dim view As New DataView(dt)
Return view.ToTable(True, columns.ToArray())
End Function
And then you call them together like this:
Dim dt As DataTable = '.... original table here
Dim columns() As String = '... the columns you want
Dim csv As String = CSVBuilder(GetProjection(dt, columns))
or like this:
Dim dt As DataTable = '.... original table here
Dim columns() As String = '... the columns you want
Dim dt1 = GetProjection(dt, columns)
Dim csv As String = CSVBuilder(dt1)
This is called Currying, and it's a good thing to do.
Finally, I'll repeat my suggestion to think in terms of writing to a stream. Long strings with repeated append operations can cause real problems for the .Net garbage collector. Using StringBuilder can help, but won't fully eliminate these problems. Writing to a Stream, which is often connected to a file on disk, gives you the opportunity to completely eliminate this issue. Plus, it will likely save you work later on.

Splitting strings and placing it into respective columns in datagridview VB.NET

I have a List(Of String), I want to display it on my Datagridview wherein this Datagridview's column headers have been set. I want to split the one-line string from the list to the columns in the Datagridview. Here is the example of what I want to be displayed:
This is the strings on the list:
String 1|String 2|String 3
String a|String b|String c
And here is what I want it to look like on the Datagridview:
Column1 Column2 Column3
String 1 String 2 String 3
String a String b String c
This is what I have so far:
For Each mail In emailList
Dim rowStringCollection As String() = mail.Split(New String() {"|"c}, StringSplitOptions.RemoveEmptyEntries)
Dim table As New DataTable()
For Each rowString As String In rowStringCollection
Dim rowData As String() = rowString.Split(New Char() {"|"c}, StringSplitOptions.RemoveEmptyEntries)
Dim row As DataRow = table.NewRow()
'Insert the strings into the table
Next
dgvMails.DataSource = table
Next
I figured it out:
For Each mail In emailList
Dim rowStringCollection As String() = mail.Split(New String() {"|"c}, StringSplitOptions.RemoveEmptyEntries)
DataGridView.Rows.Add(New String() {rowStringCollection(0), rowStringCollection(1), rowStringCollection(2), rowStringCollection(3), rowStringCollection(4)})
Next

Stored list of array using For Each loop

I want to store the "zone_check_value" to a array of string then while inserting into array i will check the array of string if the next value is repeated or have duplicate.
Example.
1st Example
1st loop = zone_check_value = ZD1/01/2014
2nd loop = zone_check_value = ZD1/01/2014
2nd Example
1st loop = zone_check_value = ZD1/01/2014
2nd loop = zone_check_value = ZD2/02/2014
3rd loop = zone_check_value = ZD1/01/2014
Code:
For Each dt As DataTable In xls.Tables
Dim array_of_string as String() 'i want to put the value in here
For Each dr As DataRow In dt.Rows
Dim zone_destination As String = dr(2).ToString
Dim affected_date As String = dr(7).ToString
Dim zone_check_value = zone_destination + affected_date
''''''How can i store zone_check_value in a string array?
Next
Next
EDIT
What if i add select case in my loop? the array_of_string value become NULL. I need to check the value of the current value in array_of_string .
Example Code
For Each dt As DataTable In xls.Tables
Dim array_of_string as String() 'i want to put the value in here
select Case dt.tablename
case "Sheet1"
For Each dr As DataRow In dt.Rows
Dim zone_destination As String = dr(2).ToString
Dim affected_date As String = dr(7).ToString
Dim zone_check_value = zone_destination + affected_date
''''''How can i store zone_check_value in a string array?
Next
case "Sheet 2"
For Each dr As DataRow In dt.Rows
Dim check_value as Boolean = array_of_string.Contains(dr(0).ToString)
'but when i got in sheet 2 the array_of_string is null
Next
Next
The easiest way is to use a List(Of String).
For Each dt As DataTable In xls.Tables
Dim array_of_string as List(Of String) = New List(Of String) 'i want to put the value in here
For Each dr As DataRow In dt.Rows
Dim zone_destination As String = dr(2).ToString
Dim affected_date As String = dr(7).ToString
Dim zone_check_value = zone_destination & affected_date
''''''How can i store zone_check_value in a string array?
array_of_string.Add(zone_check_value)
Next
''' Now if you really need it in array form you can cast it via:
''' Dim values() As String = array_of_string.ToArray()
Next
You might even consider:
For Each dt As DataTable In xls.Tables
Dim values As List(Of String) = New List(Of String)
dt.Rows.ForEach( Sub(item) values.Add(item(2).ToString & item(7).ToString) )
''' Now do something with values.
Next
Either way, make sure you always use the string concatenation operator & to concatenate strings. The arithmetic addition operator + will cause you problems from time to time if you use it on strings.

Getting GridViewRow data into DataRow in Visual Basic

Below is a loop I am trying to use to get the values from a GridViewRow into a DataRow object (using the godforsaken language of Visual Basic). However, on this line:
dr(i) = r.Cells(i).Text
I keep getting the following error message:
the value of type string cannot be converted to system.data.datarow
Can someone point me in the right direction on how to do this?
Dim rows As New List(Of GridViewRow)()
For Each item As GridViewRow In grdExpProd.Rows
rows.Add(item)
Next
Dim value As Integer = rows.Count
Dim dt As New DataTable()
For index As Integer = value - 1 To 0 Step -1
Dim dr As DataRow()
Dim r As GridViewRow = rows(index)
For i As Integer = 0 To r.Cells.Count - 1
dr(i) = r.Cells(i).Text
Next
dt.Rows.Add(dr)
Next
I believe you need to be adding your text to the DataRows Item Property which will allow you access to the individual cells of the DataRow. You are also going to need to add the columns that exist in your GridRowView to your new DataTable.
For i = 1 To rows(0).Cells.Count
dt.Columns.Add("Header" & i)
Next
For index As Integer = value - 1 To 0 Step -1
Dim dr As DataRow = dt.NewRow()
Dim r As GridViewRow = rows(index)
For i As Integer = 0 To r.Cells.Count
dr.Item(i) = r.Cells(i).Text
Next
dt.Rows.Add(dr)
Next
You accidentally created dr as an array of DataRow objects, not as a single DataRow object. Try replacing
Dim dr As DataRow()
with
Dim dr As New DataRow()
Try replacing
Dim dr As DataRow()
with
Dim dr As DataRow = dt.NewRow()
Also, as another poster pointed out, you need to create columns in your data table before attempting to add rows to it.

trouble returning datatable within a try statement

I have the following piece of code that I am using to try and rip a csv file and turn it into a datatable. My problem is that the debugger never makes it to the return statement. Everything is appending to the datatable correctly, so I know that part works. Any idea's on what I can do to trouble shoot this further. Also, if you know of a simpler way to turn a import a csv file to a datatable I'd be very interested in learning about it.
Thanks!
Public Function loadCSVTableII() As DataTable
Dim dt As New DataTable("TableII")
Dim line As String = String.Empty
Dim counter As Integer = 0
Dim reader As New StreamReader(pathTableTwo)
Try
While Not IsNothing(line)
line = reader.ReadLine()
Dim lineSep As String() = line.Split(New Char() {","c})
If Not counter = 0 Then
dt.Rows.Add(lineSep)
counter += 1
Else
For Each value As String In lineSep
dt.Columns.Add(value)
Next
counter += 1
End If
End While
'cursor never gets to this code block...
Dim primarykey(0) As DataColumn
primarykey(0) = dt.Columns("Ages")
dt.PrimaryKey = primarykey
Return dt
Catch ex As Exception
Throw
End Try
End Function
Update: It is erroring out on this line in the code.
Dim lineSep As String() = line.Split(New Char() {","c})
It say that the Object reference is not set to an instance of an object. What's weird though is that it works through the whole data table fine. Could it be that the while loop is not terminating at the end of the file?
Try changing your While loop to handle the end of stream condition. It's not very clear what the IsNothing function is doing in your code.
While Not reader.EndOfStream
line = reader.ReadLine
'// Dim lineSep As String() = line.Split(New Char() {","c})
For your line split, in VB.Net, it's simple to just do this:
Dim lineSep As String() = line.Split(",")
You can use OLEDB provider for this.
string query = "SELECT Symbol, [Name of Company], FROM [just file name with extension]";
string connStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + [csv file path without file name] + ";" + "Extended Properties=’text;HDR=YES;’";
//create dataadapter object
OleDbDataAdapter adapter = new OleDbDataAdapter(query, connStr);
// create table
DataTable dtSymbolDetails = new DataTable("ScriptDetails");
dtSymbolDetails.Columns.Add("Symbol");
dtSymbolDetails.Columns.Add("Name of Company");
// fill the table with data using adapter
adapter.Fill(dtDetails);