How to populate List using DataTable and For Each Loop? - sql

I'm trying to populate a List using a DataTable, I have a for each loop that checks every row and adds the item to the list. But the code isn't working, I keep getting the error..
System.NullReferenceException: {"Object reference not set to an
instance of an object."}
-Data: {System.Collections.ListDictionaryInternal}
-HelpLink: Nothing -Inner Exception: Nothing
-TargetSite: {System.Collections.Generic.List`1[System.String] getListOfUsers()}
This is my code...
Function getListOfUsers() As List(Of String)
'Dim i As Integer = 0
Dim lUserNames As List(Of String) = Nothing
Dim dt As DataTable = getDataTable(db_Config, "SELECT * FROM tblUsers")
If dt.Rows.Count > 0 Then
Try
For Each dRowItem As DataRow In dt.Rows
'i = i + 1
'If IsDBNull(dt.Rows(0)("fldUserName").ToString) = False Then
' lUserNames.Add(dt.Rows(0)("fldUserName").ToString)
'End If
If dRowItem.Item("fldUserName").ToString <> "" Then
lUserNames.Add(dRowItem.Item("fldUserName").ToString)
End If
Next dRowItem
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End If
Return lUserNames
End Function

Currently lUserNames has not been initialized. You need to do this:
Dim lUserNames As New List(Of String)

You have declared the List, but you haven't initialized it.
So change
Dim lUserNames As List(Of String) = Nothing
to
Dim lUserNames As List(Of String) = New List(Of String)
Of course you would also get a NullReferenceException if getDataTable returns Nothing instead of an empty DataTable if tblUsers would be empty at If dt.Rows.Count > 0.

You're not initializing your List on line 4. It should be:
Dim lUserNames As List(Of String) = New List(Of String)()
Edit: apparently this is a bit of a CSharp'ism :) This also works:
Dim lUserNames As New List(Of String)

Related

Value of type 'String' cannot be converted to 'String()'

I am trying to add a value from DataTable dtUsers into a list UserLocations however I am getting the title error.
My code is:
Public UserLocations As New List(Of String())
For Each NewRow As DataRow In dtUsers.Rows
Dim seq As String = NewRow("SEQUENCE").Value.ToString
If CandRow("SQ") = NewRow("SQ") Then
UserLocations.Add(seq)
End If
Next
I don not understand why I cannot add a string to a list of strings.
How should I go about this?
Public UserLocations As New List(Of String)
For Each NewRow As DataRow In dtUsers.Rows
Dim seq As String = NewRow("SEQUENCE").Value.ToString()
If CandRow("SQ") = NewRow("SQ") Then
UserLocations.Add(seq)
End If
Next

How to convert csv file content to DataTable?

I convert CSV file to DataTable using following code. It is working fine but sometimes it adds invalid character between the string.
Private Shared Function convertToDT(filePath As String) As DataTable
Dim detailDataTable As New DataTable()
Using csvReader As New TextFieldParser(filePath)
csvReader.SetDelimiters(New String() {","})
csvReader.HasFieldsEnclosedInQuotes = True
Dim colFields As String() = csvReader.ReadFields()
For Each column As String In colFields
Dim datecolumn As New DataColumn(column.ToLowerInvariant)
datecolumn.AllowDBNull = True
detailDataTable.Columns.Add(datecolumn)
Next
While Not csvReader.EndOfData
Dim rowData As String() = csvReader.ReadFields //sometimes rowData convert invalid name
For i As Integer = 0 To rowData.Length - 1
//perform operation
Next
If rowData IsNot Nothing AndAlso rowData(0) IsNot Nothing Then
If Not (rowData(0).StartsWith("#") Or String.IsNullOrEmpty(rowData(0))) Then
detailDataTable.Rows.Add(rowData)
End If
End If
End While
End Using
Return detailDataTable
End Function
Sometime it add invalid name. Can anybody please suggest

How to add List as value in Hashtable

In vb.net If I have HashTable,key is integer and the value is a list of integers, how to append integers to the value of a given key,
I have tried it but each time I found the integer last added only, (the list only has the last item added).
Here is my code , where dt is DataTable object
Dim dt = report.getEvaluationReportByObjectiveGroupId(29)
Dim data As New Hashtable()
Dim dataEntry As DictionaryEntry
Dim res As String
For Each row As DataRow In dt.Rows
Dim strYear = row.Item("Year")
Dim strData = row.Item("EmpCount")
If data.ContainsKey(strYear) Then
Dim newCountArr As List(Of Int32) = DirectCast(data(strYear), List(Of Int32))
' newCountArr.AddRange(data(strYear))
newCountArr.Add(strData)
' data.Remove(strYear)
' data.Add(strYear, newCountArr)
Else
Dim countArr As New List(Of Integer)
countArr.Add(strData)
data.Add(strYear, countArr)
End If
' data.Add(strYear, strData)
Next row
I would suggest to use the strongly typed Dictionary(Of Int32, List(Of Int32)) instead, it works similar. But anyway, here's the HashTable approach:
Dim table = New Hashtable
Dim list = New List(Of Int32)
For i = 1 To 999
list.Add(i)
Next
table.Add(1, list)
' somewhere else you want to read the list for a given key (here 1) '
Dim list1 As List(Of Int32) = DirectCast(table(1), List(Of Int32))
list.Add(1000) ' add another integer to the end of the list '
' note: you don't need to add the list to the HashTable again '
Edit: Since you've posted your code, here's the corrected:
For Each row As DataRow In dt.Rows
Dim strYear = row.Field(Of Int32)("Year")
Dim strData = row.Field(Of Int32)("EmpCount")
Dim list As List(Of Int32)
If data.ContainsKey(strYear) Then
list = DirectCast(data(strYear), List(Of Int32))
Else
list = New List(Of Int32)
data.Add(strYear, list)
End If
list.Add(strData)
Next row

Pass datatable as a parameter to a SQL Server stored proc from VB.net

Please suggest how to do this. Thanks.
PrivateFunction GetDataFromDb(ByVal lcSQL AsString, ByVal loCommandType As CommandType, _
ByVal lcTableName AsString, ByValParamArray loParameters() As SqlParameter) As DataSet
Dim loResult As DataSet
Dim loConnection As SqlConnection
Dim loCommand As SqlCommand
Dim loAdapter As SqlDataAdapter
Dim i As Int32
Dim loParameter As SqlParameter
Try
'Create and open connection to the Northwind database
loConnection = New SqlConnection("Persist Security Info=False;Integrated Security=SSPI;database=northwind;server=(local);Connect Timeout=30")
loConnection.Open()
'Prepare command and to select data from the database
loCommand = New SqlCommand(lcSQL, loConnection)
loCommand.CommandType = loCommandType
IfNot loParameters IsNothingThen
ForEach loParameter In loParameters
loCommand.Parameters.Add(loParameter)
Next
EndIf
loAdapter = New SqlDataAdapter(loCommand)
loResult = New DataSet
loAdapter.Fill(loResult, lcTableName)
'Return list of the customers as a DataSet
Return loResult
Catch ex As Exception
Throw ex
Finally
'Clean resources
IfNot loAdapter IsNothingThen
loAdapter.Dispose()
loAdapter = Nothing
EndIf
IfNot loCommand IsNothingThen
loCommand.Dispose()
loCommand = Nothing
EndIf
IfNot loConnection IsNothingThen
If loConnection.State = ConnectionState.Open Then
loConnection.Close()
EndIf
loConnection.Dispose()
loConnection = Nothing
EndIf
EndTry
EndFunction
Found at: http://support.microsoft.com/kb/555266
Pass it in as XML datatype, i just did this a couple months ago. so i will re edit when i find some code that handles it.
Private Function AddToList(dtData As DataTable) As List(Of [Integer])
Dim ListOfInt As New List(Of Integer)()
For Each row As DataRow In dtData.Rows
For Each Col As DataColumn In dtData.Columns
ListOfInt.Add(row(Col).ToString())
Next
Next
Return ListOfInt
End Function
Private Function DataToXML() As XDocument
Dim DataDoc As XDocument = <?xml version='1.0'?>
<Root>
<%= RenderKeys(SelectedDataValues) %>
</Root>
Return DataDoc
End Function
Private Function RenderKeys(ByVal keys As List(Of Integer)) As Collection(Of XElement)
Dim ElementCollection As New Collection(Of XElement)
For Each Key As Integer In keys
Dim XKey As XElement = <Key ID=<%= Key %>/>
ElementCollection.Add(XKey)
Next
Return ElementCollection
End Function
This just takes a list of IDs from a table that was pulled from SQL Server and add its each id to a list (of integer) Then in your sproc just add an xml data type for the data coming in.

query database with each object in Arraylist and databind to gridview?

I have a function that returns a list of account numbers as an Arraylist. I am trying to use each account as a command parameter in another sub routine to get more data about each account number. This only returns the data for the last account number in the arraylist. I need to use each account number, call the database, get the additional information and store ALL of the data into a Gridview (databind). Example: If I had 3 account numbers in my arraylist return 3 rows of data to the gridview. I am struggling with how to get ALL of the information for each value (account number) in the Arraylist. Can someone point me in the right direction?? I think this can be done but I am not certain if my approach is correct or not. Perhaps I need to create datatables that contain the additional information for each value passed via the arraylist....Any Ideas??
#jwatts1980 thanks for the comment: I will try to clarify. I have an arraylist of account numbers (and maybe this is where I am off track) I am trying to use the values in this ArrayList as command parameters in another call to a different table/file that returns more info on those accounts. I will provide a portion of the code to help clarify what it is I am attempting to do:
Private Function ReturnMultAccts(ByVal strAcct) As ArrayList
Dim acctsDetail As New ArrayList
Dim dsn As String = ConfigurationManager.ConnectionStrings.ConnectionString
Dim sql As String = "SELECT DISTINCT * FROM FILE WHERE ACCTNUM=?"
Using conn As New OdbcConnection(dsn)
Using cmd As New OdbcCommand(sql, conn)
conn.Open()
cmd.Parameters.Add("ACCTNUM", OdbcType.VarChar, 20).Value = strAcct
Dim rdrUsers As OdbcDataReader = cmd.ExecuteReader()
If rdrUsers.HasRows Then
While rdrUsers.Read()
acctsDetail.Add(Trim(rdrUsers.Item("ACCTNUM")))
End While
End If
rdrUsers.Close()
conn.Close()
End Using
End Using
This returns an Arraylist of Account Numbers (Lets say it is 3 acct numbers). I call this Function from another Sub:
Private Sub GetMoreAcctInfo(ByVal strAcct)
'Create New ArrayList
Dim MultAccts As New ArrayList
'Pass strAcct to Function to get Multiples
MultAccts = ReturnMultAccts(strAcct)
'Create the variable BachNum for the loop
Dim BachNum As String = MultAccts.Item(0)
For Each BachNum In MultAccts
'Get All of the necessary info from OtherFile based on the BachNum for BOS's
Dim dsn As String = ConfigurationManager.ConnectionStrings.ConnectionString
Dim sql As String = "SELECT ACCTNUM, BILSALCOD1, BILSALCOD2, BILSALCOD3, OTHACCTNUM FROM OtherFile WHERE OTHACCTNUM=?" 'Equal to the items in the arraylist
Using conn As New OdbcConnection(dsn)
Using cmd As New OdbcCommand(sql, conn)
conn.Open()
cmd.Parameters.Add("OTHACCTNUM", OdbcType.VarChar, 20).Value = BachNum
Using adapter = New OdbcDataAdapter(cmd)
Dim DS As New DataSet()
adapter.Fill(DS)
GridView1.DataSource = DS
GridView1.DataBind()
End Using
End Using
End Using
Next
End Sub
Hopefully this clarifies what I am attempting to do...??
To elaborate on my suggestion, you will need a list of strongly typed objects. You can add those items to the list, then bind the list to the GridView.
I'll start at the beginning. You know what kind of data is coming from your database: ACCTNUM, BILSALCOD1, BILSALCOD2, BILSALCOD3, and OTHACCTNUM. So you can use those to create an object.
Friend Class AccountClass
Private pACCTNUM As string = ""
Private pBILSALCOD1 As string = ""
Private pBILSALCOD2 As string = ""
Private pBILSALCOD3 As string = ""
Private pOTHACCTNUM As string = ""
Public Property ACCTNUM() As string
Get
Return pACCTNUM
End Get
Set(ByVal value as string)
Me.pACCTNUM = value
End Set
End Property
Public Property BILSALCOD1() As string
Get
Return pBILSALCOD1
End Get
Set(ByVal value as string)
Me.pBILSALCOD1 = value
End Set
End Property
Public Property BILSALCOD2() As string
Get
Return pBILSALCOD2
End Get
Set(ByVal value as string)
Me.pBILSALCOD2 = value
End Set
End Property
Public Property BILSALCOD3() As string
Get
Return pBILSALCOD3
End Get
Set(ByVal value as string)
Me.pBILSALCOD3 = value
End Set
End Property
Public Property OTHACCTNUM() As string
Get
Return pOTHACCTNUM
End Get
Set(ByVal value as string)
Me.pOTHACCTNUM = value
End Set
End Property
Sub New(ByVal ACCTNUM As string, ByVal BILSALCOD1 As string, ByVal BILSALCOD2 As string, ByVal BILSALCOD3 As string, ByVal OTHACCTNUM As string)
Me.ACCTNUM = ACCTNUM
Me.BILSALCOD1 = BILSALCOD1
Me.BILSALCOD2 = BILSALCOD2
Me.BILSALCOD3 = BILSALCOD3
Me.OTHACCTNUM = OTHACCTNUM
End Sub
End Class
Then you rework the GetMoreAcctInfo() routine to use it.
Private Sub GetMoreAcctInfo(ByVal strAcct)
'Create New ArrayList
Dim MultAccts As ArrayList
'Pass strAcct to Function to get Multiples
MultAccts = ReturnMultAccts(strAcct)
'Create the variable BachNum for the loop
Dim BachNum As String
'Create the list to bind to the grid
Dim AcctInfo As New Generic.List(Of AccountClass)
'create the dataset
Dim DS As DataSet
For Each BachNum In MultAccts
'Get All of the necessary info from OtherFile based on the BachNum for BOS's
Dim dsn As String = ConfigurationManager.ConnectionStrings.ConnectionString
Dim sql As String = "SELECT ACCTNUM, BILSALCOD1, BILSALCOD2, BILSALCOD3, OTHACCTNUM FROM OtherFile WHERE OTHACCTNUM=?" 'Equal to the items in the arraylist
Using conn As New OdbcConnection(dsn)
Using cmd As New OdbcCommand(sql, conn)
conn.Open()
cmd.Parameters.Add("OTHACCTNUM", OdbcType.VarChar, 20).Value = BachNum
Using adapter = New OdbcDataAdapter(cmd)
DS = New DataSet()
adapter.Fill(DS)
For Each t As DataTable In DS.Tables
For Each r As DataRow In t.Rows
AcctInfo.Add(new AccountClass(r("ACCTNUM"), r("BILSALCOD1"), r("BILSALCOD2"), r("BILSALCOD3"), r("OTHACCTNUM")))
Next
Next
End Using
End Using
End Using
Next
GridView1.DataSource = AcctInfo
GridView1.DataBind()
End Sub