How to convert 2 dimensional arraylist to datatable? - vb.net

I need a function that returns a datatable, from any arraylist (2 dimensions) as arguments? Thanks for your help
Creating two dimensional Arraylist:
Public Overrides Function Find(Optional ByRef conditions As ArrayList = Nothing) As System.Collections.ArrayList
Dim collection As New ArrayList
Dim cmd ......... ' Select command based on an arraylist of conditions
Dim dr As SqlDataReader = cmd.ExecuteReader()
While dr.Read()
Dim cnt As New contact
cnt .Id() = dr("id")
cnt .Name= dr("name")
'......... other columns are imported
collection.Add(cnt )
End While
dr.Close()
Return collection
End Function

Suitable solution found:
Public Shared Function ArrayListToDataTable(ByVal arraylist1 As ArrayList) As System.Data.DataTable
Dim dt As New System.Data.DataTable()
For i As Integer = 0 To arraylist1.Count - 1
Dim GenericObject As Object = arraylist1.Item(i)
Dim NbrProp As Integer = GenericObject.GetType().GetProperties().Count
For Each item As PropertyInfo In GenericObject.GetType().GetProperties()
Try
Dim column = New DataColumn()
Dim ColName As String = item.Name.ToString
column.ColumnName = ColName
dt.Columns.Add(column)
Catch
End Try
Next
Dim row As DataRow = dt.NewRow()
Dim j As Integer = 0
For Each item As PropertyInfo In GenericObject.GetType().GetProperties()
row(j) = item.GetValue(GenericObject, Nothing)
j += 1
Next
dt.Rows.Add(row)
Next
Return dt
End Function

After 2 years, Let me answer this=>
Function ConvertArrayListToDataTable(ByVal arraylist As ArrayList) As DataTable
Dim dt As DataTable = New DataTable()
If arraylist.Count <= 0 Then
Return dt
End If
Dim propertiesinfo As PropertyInfo() = arraylist(0).GetType().GetProperties()
For Each pf As PropertyInfo In propertiesinfo
Dim dc As DataColumn = New DataColumn(pf.Name)
dc.DataType = pf.PropertyType
dt.Columns.Add(dc)
Next
For Each ar As Object In arraylist
Dim dr As DataRow = dt.NewRow
Dim pf As PropertyInfo() = ar.GetType().GetProperties()
For Each prop As PropertyInfo In pf
dr(prop.Name) = prop.GetValue(ar, Nothing)
Next
dt.Rows.Add(dr)
Next
Return dt
End Function

Related

how to add list in `DATAGRIDVIEW` with combobox on runtime

i tried the following code but it adds the list every time when we start new row so if we have two rows its add it two times if we move to three rows it adds the list for three time
Please provide me simple and easy way to add the list into the combobox of datagridview
Dim CON As New MySqlConnection("server=localhost; username=root; password=Masoom1; database=airtech_db;")
Dim cmd As New MySqlCommand("Select * from `Suppliers`;", CON)
Dim da As New MySqlDataAdapter("Select * from `Suppliers`;", CON)
Dim ds As New DataSet
Dim dr As MySqlDataReader
Dim TOTAL_SUPPLIERS As Integer
CON.Open()
da.Fill(ds)
dr = cmd.ExecuteReader
TOTAL_SUPPLIERS = ds.Tables(0).Rows.Count
Dim TOTAL_SUPPLIERS_ARRAY(TOTAL_SUPPLIERS) As String, ARRAYINDEX As Integer
ARRAYINDEX = 0
Do While dr.Read() = True
TOTAL_SUPPLIERS_ARRAY(ARRAYINDEX) = dr("Supplier_Name").ToString()
ARRAYINDEX += 1
Loop
CON.Close()
Dim cbCell As New DataGridViewComboBoxCell
For k = 0 To DataGridView1.Rows.Count - 1
cbCell = DataGridView1.Rows(k).Cells("Supplier_Name")
For iIndex = 0 To UBound(TOTAL_SUPPLIERS_ARRAY) - 1
cbCell.Items.Add(TOTAL_SUPPLIERS_ARRAY(iIndex))
Next
Next
You can set it only once for a column.
For example you can populate combobox when loading a form.
Private Sub Form_Load(sender As Object, e As EventArgs) Handles MyForm.Load
With Me.DataGridView.Columns("Supplier_Name")
.DataSource = GetSupplierNames()
End With
End Sub
Private Function GetSupplierNames() As List(Of String)
Dim query As String = "SELECT Supplier_Name FROM Suppliers"
Using connection As New MySqlConnection(connectionString)
Using command As New MySqlCommand(query, connection)
connection.Open()
Dim supplierNames = new List(Of String)()
Using reader AS MySqlDataReader = command.ExecuteReader()
While reader.Read()
Dim name As String = reader.GetString(0)
supplierNames.Add(name)
End While
End Using
Return supplierNames
End Using
End Using
End Function
well I found a simple solution to existing code to fix the problem as every time it runs clear the existing list and let the list add again so add cbCell.Items.Clear()to code helped
Dim cbCell As New DataGridViewComboBoxCell
For k = 0 To DataGridView1.Rows.Count - 1
cbCell = DataGridView1.Rows(k).Cells("Supplier_Name")
cbCell.Items.Clear()
For iIndex = 0 To UBound(TOTAL_SUPPLIERS_ARRAY)
cbCell.Items.Add(TOTAL_SUPPLIERS_ARRAY(iIndex))
Next
Next

VB: Count number of columns in csv

So, quite simple.
I am importing CSVs into a datagrid, though the csv always has to have a variable amount of columns.
For 3 Columns, I use this code:
Dim sr As New IO.StreamReader("E:\test.txt")
Dim dt As New DataTable
Dim newline() As String = sr.ReadLine.Split(";"c)
dt.Columns.AddRange({New DataColumn(newline(0)), _
New DataColumn(newline(1)), _
New DataColumn(newline(2))})
While (Not sr.EndOfStream)
newline = sr.ReadLine.Split(";"c)
Dim newrow As DataRow = dt.NewRow
newrow.ItemArray = {newline(0), newline(1), newline(2)}
dt.Rows.Add(newrow)
End While
DG1.DataSource = dt
This works perfectly. But how do I count the number of "newline"s ?
Can I issue a count on the number of newlines somehow? Any other example code doesn't issue column heads.
If my csv file has 5 columns, I would need an Addrange of 5 instead of 3 and so on..
Thanks in advance
Dim sr As New IO.StreamReader(path)
Dim dt As New DataTable
Dim newline() As String = sr.ReadLine.Split(","c)
' MsgBox(newline.Count)
' dt.Columns.AddRange({New DataColumn(newline(0)),
' New DataColumn(newline(1)),
' New DataColumn(newline(2))})
Dim i As Integer
For i = 0 To newline.Count - 1
dt.Columns.AddRange({New DataColumn(newline(i))})
Next
While (Not sr.EndOfStream)
newline = sr.ReadLine.Split(","c)
Dim newrow As DataRow = dt.NewRow
newrow.ItemArray = {newline(0), newline(1)}
dt.Rows.Add(newrow)
End While
dgv.DataSource = dt
End Sub
Columns and item values can be added to a DataTable individually, using dt.Columns.Add and newrow.Item, so that these can be done in a loop instead of hard-coding for a specific number of columns. e.g. (this code assumes Option Infer On, so adjust as needed):
Public Function CsvToDataTable(csvName As String, Optional delimiter As Char = ","c) As DataTable
Dim dt = New DataTable()
For Each line In File.ReadLines(csvName)
If dt.Columns.Count = 0 Then
For Each part In line.Split({delimiter})
dt.Columns.Add(New DataColumn(part))
Next
Else
Dim row = dt.NewRow()
Dim parts = line.Split({delimiter})
For i = 0 To parts.Length - 1
row(i) = parts(i)
Next
dt.Rows.Add(row)
End If
Next
Return dt
End Function
You could then use it like:
Dim dt = CsvToDataTable("E:\test.txt", ";"c)
DG1.DataSource = dt

Converted C# To VB.NET , But Vb.net code Not working ,Below converted code is pasted .i got the error Linq part

Dim dt As New DataTable("MyTable")
dt.Columns.Add(New DataColumn("Name"))
dt.Columns.Add(New DataColumn("Place"))
dt.Columns.Add(New DataColumn("date", Type.[GetType]("System.String")))
create the data table
Dim dr As DataRow = dt.NewRow()
dr("Name") = "500"
dr("Place") = "Chennai"
dr("date") = "10-May-2014"
dt.Rows.Add(dr)
Dim dr1 As DataRow = dt.NewRow()
dr1("Name") = "600"
dr1("Place") = "Chennai"
dr1("date") = "11-May-2014"
dt.Rows.Add(dr1)
added the row
Dim dr2 As DataRow = dt.NewRow()
dr2("Name") = "200"
dr2("Place") = "Bangalore"
dr2("date") = "12-Aug-2014"
dt.Rows.Add(dr2)
Dim dr3 As DataRow = dt.NewRow()
dr3("Name") = "40"
dr3("Place") = "Chennai"
dr3("date") = "14-May-2014"
dt.Rows.Add(dr3)
Dim dr5 As DataRow = dt.NewRow()
dr5("Name") = "9000"
dr5("Place") = "Bangalore"
dr5("date") = "15-Aug-2014"
dt.Rows.Add(dr5)
added the row to datatable
Dim dr4 As DataRow = dt.NewRow()
dr4("Name") = "9000"
dr4("Place") = "Bangalore"
dr4("date") = "1-Aug-2014"
dt.Rows.Add(dr4)
This below part get error
Dim grouped = From groupbyUD In From userdefinedtable In dt.AsEnumerable()Group userdefinedtable By New With { _
Key .placeCol = userdefinedtable("Place") _
}New With { _
Key .ValueUD = groupbyUD.Key, _
Key .ColumnValuesUD = groupbyUD _
}
Dim place As String = ""
Dim [date] As String = ""
Dim tempTable As New DataTable()
Dim slectedFieldsTable As New DataTable()
Dim newRow As DataRow
Dim list As New List(Of Object)()
create the data table
slectedFieldsTable = New DataTable()
slectedFieldsTable.Columns.Add("place")
slectedFieldsTable.Columns.Add("date")
Also below var get the error and grouped also get the error.
For Each keyUD As var In grouped
Console.WriteLine(keyUD.ValueUD.placeCol)
place = DirectCast(keyUD.ValueUD.placeCol, String)
Dim lst As New List(Of DateTime)()
For Each columnValue As var In keyUD.ColumnValuesUD
lst.Add(Convert.ToDateTime(columnValue("date")))
Next
Console.WriteLine(lst.Min())
[date] = DirectCast(Convert.ToString(lst.Min()), String)
slectedFieldsTable.Rows.Add(place, [date])
Next
bind the value data set to list
For Each drin As DataRow In slectedFieldsTable.Rows
list.Add(drin)
Next
tempTable.Columns.Add("place", GetType(String))
tempTable.Columns.Add("date", GetType(String))
For Each drlst As DataRow In list
newRow = tempTable.NewRow()
newRow("place") = drlst.ItemArray(0).ToString()
newRow("date") = drlst.ItemArray(1).ToString()
tempTable.Rows.Add(newRow)
tempTable.AcceptChanges()
Next
Console.ReadLine()
End Sub
End Class
End Namespace
I think following code solve your problem. Replace code with yours.
Dim grouped = From userdefinedtable In dt.AsEnumerable() _
Group userdefinedtable By Key = userdefinedtable("Place") Into Group _
Select ValueUD = Key, ColumnValuesUD = Group
Replace as Var with as Object
For Each keyUD As Object In grouped
Console.WriteLine(keyUD.ValueUD.placeCol)
place = DirectCast(keyUD.ValueUD.placeCol, String)
Dim lst As New List(Of DateTime)()
For Each columnValue As Object In keyUD.ColumnValuesUD
lst.Add(Convert.ToDateTime(columnValue("date")))
Next
Console.WriteLine(lst.Min())
[date] = DirectCast(Convert.ToString(lst.Min()), String)
slectedFieldsTable.Rows.Add(place, [date])
Next

Updating only Last row of datatable to all index of List<T>. Need to convert datatable to List

Dim dt As DataTable = catheter.FetchCatheter()
Dim ct As New EntityObjects.CatheterTypeBO
Dim cList As New List(Of EntityObjects.CatheterTypeBO)
For i As Integer = 0 To dt.Rows.Count - 1
ct.ID = dt.Rows(i)("ID")
ct.Type = dt.Rows(i)("CTYPE")
ct.Active = dt.Rows(i)("ACTIVE").ToString()
cList.Add(ct)
Next
updating all index of cList by last row of dt. Need to convert datatable to List
Try to use AsEnumerable then Last() like:
Dim dt As DataTable = catheter.FetchCatheter()
Dim ct As New EntityObjects.CatheterTypeBO
Dim cList As New List(Of EntityObjects.CatheterTypeBO)
Dim dr as DataRow = dt.AsEnumerable().Last()
ct.ID = dr("ID")
ct.Type = dr("CTYPE")
ct.Active = dr("ACTIVE").ToString()
cList.Add(ct)

Only return the latest 'x' files

I have the following code
Public Function ListDirLatest(ByVal Dir As String, ByVal Amount As Integer) As DataTable
Dim dt As DataTable = ListDir(Dir)
If (dt Is Nothing) Then
Return Nothing
Else
Return dt ' This is where i would like to implement the latest x-files logic
End If
End Function
Private Function ListDir(ByVal Dir As String) As DataTable
If Directory.Exists(Dir) Then
Dim dt As DataTable = GetDT()
Dim dirinfo As New DirectoryInfo(Dir)
For Each fsi As FileSystemInfo In dirinfo.GetFileSystemInfos(".txt")
Dim dr As DataRow = dt.NewRow()
dr("FileName") = fsi.Name()
dr("FileDate") = fsi.CreationTime()
Next
Return dt
Else
Return Nothing
End If
End Function
Private Function GetDT() As DataTable
'Create DataTable to hold results
Dim dt As New DataTable("DirList")
Dim st As System.Type = System.Type.GetType("System.String")
dt.Columns.Add("FileName", st)
dt.Columns.Add("FileDate", st)
Return dt
End Function
At the moment the ListDirLatest Function will return all the files the in the directory.
How do I change the code so that it only returns the latest 'x' files, as specified by the Amount argument.
To Clarify I want to return the LATEST 'x' files in the directory.
You can solve your problem with a little of Linq and a the reference to System.Data.DataSetExtensions
( http://msdn.microsoft.com/en-us/library/system.data.datatableextensions(v=vs.100).aspx )
Public Function ListDirLatest(ByVal Dir As String, ByVal Amount As Integer) As DataTable
Dim dt As DataTable = ListDir(Dir)
If (dt Is Nothing) Then
Return Nothing
Else
Dim r = from myRow in dt.AsEnumerable()
Order By("FileDate DESC")
Take(Amount)
dt = r.CopyToDataTable()
return dt
End If
End Function
Also, the ListDir function has a couple of errors
Add the row information to the DataTable returned
Use a correct pattern for GetFileSystemInfos
Function ListDir(ByVal Dir As String) As DataTable
If Directory.Exists(Dir) Then
Dim dt As DataTable = GetDT()
Dim dirinfo As New DirectoryInfo(Dir)
For Each fsi As FileSystemInfo In dirinfo.GetFileSystemInfos("*.txt")
Dim dr As DataRow = dt.NewRow()
dr("FileName") = fsi.Name()
dr("FileDate") = fsi.CreationTime()
dt.Rows.Add(dr)
Next
Return dt
Else
Return Nothing
End If
End Function
If you mean by Amount the number of files to be returned, then here is what you need to do:
First Change the header of ListDir function to accept a parameter to allow counting the number of files to be returned, and pass that parameter from the first function,
Public Function ListDirLatest(ByVal Dir As String, ByVal Amount As Integer) As DataTable
Dim dt As DataTable = ListDir(Dir, Amount)
If (dt Is Nothing) Then
Return Nothing
Else
Return dt ' This is where i would like to implement the latest x-files logic
End If
End Function
Private Function ListDir(ByVal Dir As String, ByVal Amount As Integer) As DataTable
If Directory.Exists(Dir) Then
Dim dt As DataTable = GetDT()
Dim dirinfo As New DirectoryInfo(Dir)
Dim cnt as Integer = 0
For Each fsi As FileSystemInfo In dirinfo.GetFileSystemInfos(".txt")
Dim dr As DataRow = dt.NewRow()
dr("FileName") = fsi.Name()
dr("FileDate") = fsi.CreationTime()
cnt += 1
if cnt >= Amount Then Exit For
Next
Return dt
Else
Return Nothing
End If
End Function