Filling a combobox using a query with a where command (VB.NET) - vb.net

I have problems with filling a combobox.
I'm able to fill one whith a simple select query.
Now I want to fill a combobox with a query that inculdes a where command. I tried several solutions but none of them worked.
How can I fill a combobox with a query with a where statement?
My code so far is:
Public Function vulComboboxTesten(box As ComboBox, naam As String) As ComboBox
box.Items.Clear()
box.Items.Add(" ")
Dim query As String
query = "Select Sector from Onderaannemers where Naam_firma = #naam "
Debug.WriteLine(query)
Dim command As OleDbCommand
command = New OleDbCommand(query, connectie)
command.Connection.Open()
Dim datareader As OleDbDataReader
datareader = command.ExecuteReader
While datareader.Read
Dim item As New ComboBoxItem
item.Content = datareader("Sector")
box.Items.Add(item)
End While
command.Connection.Close()
Return box
End Function

Try this sir. i dont know how to translate my code into your type of coding. But just read the explanations.
Private Sub StoringDatainCombobox()
Try
Dim comboSource As New Dictionary(Of String, String)()
mkcon() 'this is just my sqlCon.Open
Dim cmd As New SqlCommand
Dim rd As SqlDataReader
cmd.Connection = sqlCon
cmd.CommandText = "data_get" 'my query stored procedure.
'cotains something like this select * from tb1 where isactive = true
cmd.CommandType = CommandType.StoredProcedure
comboSource.Add(0, "") ' for blank item in the 1st value of combobox
ComboBox1.DataSource = New BindingSource(comboSource, Nothing)
ComboBox1.DisplayMember = "Value"
ComboBox1.ValueMember = "key"
ComboBox1.Text = ""
rd = cmd.ExecuteReader
While (rd.Read)
comboSource.Add(rd("dataId"), rd("dataName"))
ComboBox1.DataSource = New BindingSource(comboSource, Nothing)
ComboBox1.DisplayMember = "Value"
ComboBox1.ValueMember = "key"
ComboBox1.Text = ""
End While
sqlCon.Close()
Catch ex As Exception
MessageBox.Show("Failed." & ex.Message, "Failed", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
You can now display the data result of your query also with an id.
if you need how to get the id when user select an item in combobox just inform me.
Hope this will help you.

Related

VB.NET How to correctly loop through a result set

I have looked at many different code snippets on this site looking that would show me how to do something that should be fairly simple once I have the knowledge.
I want to query a database table for an array of values and then populate a combobox with those results.
Here is what I have so far:
Public Sub getMachines()
Try
Dim SQL As String = "SELECT MachineName from machine"
Form1.machineName.DisplayMember = "Text"
Dim tb As New DataTable
tb.Columns.Add("Text", GetType(String))
Using cn As New MySqlConnection(ConnectionString)
Using cmd As New MySqlCommand(SQL, cn)
For Each cmd As String In cmd
'I want to add each value found in the database to "tb.Rows.Add"
'tb.Rows.Add(???)
Next
Form1.machineName.DataSource = tb
cn.Open()
cmd.ExecuteNonQuery()
End Using
cn.Close()
End Using
Catch ex As MySqlException
MsgBox(ex.Message)
End Try
End Sub
I proceeded much like you did. I used the Load method of the DataTable. It is not necessary to set the column name and type. The name of the column is taken from the Select statement and the datatype is inferred by ADO.net from the first few records.
Luckily a DataTable can be an Enumerable using the .AsEnumnerable method. Then we can use Linq to get all the values from the MachineName column. Calling .ToArray causes the Linq to execute. If you hold your cursor over names on this line you will see that the datatype is String(). Just what we need to fill a combo box.
Code for a class called DataAccess
Private ConnectionString As String = "Your Connection String"
Public Function GetMachineNames() As String()
Dim tb As New DataTable
Dim SQL As String = "SELECT MachineName from machine;"
Using cn As New MySqlConnection(ConnectionString)
Using cmd As New MySqlCommand(SQL, cn)
cn.Open()
dt.Load(cmd.ExecuteReader)
End Using
End Using
Dim names = dt.AsEnumerable().Select(Function(x) x.Field(Of String)("MachineName")).ToArray()
Return names
End Function
In the form load you combo box like this.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim DatAcc As New DataAccess()
Dim arr = DatAcc.GetMachineNames()
machineName.DataSource = arr
End Sub
If you just want the MachineName to be displayed in the ComboBox, then just use that as the DisplayMember; don't bother creating another column called Text.
Public Sub getMachines()
Try
Dim cmd As String = "SELECT MachineName from machine"
Dim ds As New DataSet()
Using con As New MySqlConnection(ConnectionString)
Using da As New MySqlDataAdapter(cmd, con)
da.Fill(ds)
With Form1.machineName
.DisplayMember = "MachineName"
.ValueMember = "MachineName"
.DataSource = ds
End With
End Using
End Using
Catch ex As MySqlException
MsgBox(ex.Message)
End Try
End Sub
I'll show a few examples, including using parameters, since that is important.
First up, a quick translation to run the existing query and loop through the results:
Public Sub getMachines()
Try
Dim SQL As String = "SELECT MachineName from machine"
Using cn As New MySqlConnection(ConnectionString), _
cmd As New MySqlCommand(SQL, cn)
cn.Open()
Using rdr As MySqlDatareader = cmd.ExecuteReader
While rdr.Read()
Form1.machineName.Items.Add(rdr("MachineName"))
End While
End Using
End Using
Catch ex As MySqlException
MsgBox(ex.Message)
End Try
End Sub
But better practice for a method like this is to isolate data access for the UI. This method should return results to the caller, which can decide what do with them. So I'll show two methods: one to get the data, and the other to loop through it and set up the combobox:
Private Function GetMachines() As DataTable
'No try/catch needed here. Handle it in the UI level, instead
Dim SQL As String = "SELECT MachineName from machine"
Dim result As New DataTable
Using cn As New MySqlConnection(ConnectionString), _
cmd As New MySqlCommand(SQL, cn),
da As New MySqlDataAdapter(cmd)
da.Fill(result)
End Using
Return result
End Function
Public Sub LoadMachines()
Try
For Each item As DataRow in getMachines().Rows
Form1.machineName.Items.Add(item("MachineName"))
Next
Catch ex As MySqlException
MsgBox(ex.Message)
End Try
End Sub
Or, we can use DataBinding:
Private Function GetMachines() As DataTable
Dim SQL As String = "SELECT MachineName from machine"
Dim result As New DataTable
Using cn As New MySqlConnection(ConnectionString), _
cmd As New MySqlCommand(SQL, cn),
da As New MySqlDataAdapter(cmd)
da.Fill(result)
End Using
Return result
End Function
Public Sub LoadMachines()
Try
Form1.machineName.DisplayMember = "FirstName";
Form1.machineName.ValueMember = "City"
Form1.machineName.DataSource = GetMachines()
Catch ex As MySqlException
MsgBox(ex.Message)
End Try
End Sub
If you ever want to use a filter, you might do this (notice the overloading):
Private Function GetMachines(ByVal machineFilter As String) As DataTable
Dim SQL As String = "SELECT MachineName from machine WHERE MachineName LIKE #Filter"
Dim result As New DataTable
Using cn As New MySqlConnection(ConnectionString), _
cmd As New MySqlCommand(SQL, cn),
da As New MySqlDataAdapter(cmd)
'Match the MySqlDbType to your actual database column type and length
cmd.Parameters.Add("#Filter", MySqlDbType.VarString, 30).Value = machineFilter
da.Fill(result)
End Using
Return result
End Function
Private Function GetMachines(ByVal machineFilter As String) As DataTable
Return GetMachines("%")
End Function
Query parameters like that are very important, and if you were doing string concatenation to accomplish this kind of thing on your old platform, you were doing very bad things there, too.
Finally, let's get fancy. A lot of the time, you really don't want to load an entire result set into RAM, as is done with a DataTable. That can be bad. Instead, you'd like be able to stream results into memory and only work with one at a time, minimizing RAM use. In these cases, you get to play with a DataReader... but returning a DataReader object from within a Using block (which is important) doesn't work that well. To get around this, we can use functional programming concepts and advanced language features:
Private Iterator Function GetMachines(ByVal machineFilter As String) As IEnumerable(Of String)
Dim SQL As String = "SELECT MachineName from machine WHERE MachineName LIKE #Filter"
Using cn As New MySqlConnection(ConnectionString), _
cmd As New MySqlCommand(SQL, cn)
'Match the MySqlDbType to your actual database column type and length
cmd.Parameters.Add("#Filter", MySqlDbType.VarString, 30).Value = machineFilter
cn.Open()
Using rdr As MySqlDatareader = cmd.ExecuteReader
While rdr.Read()
Dim result As String = rdr("MachineName")
Yield Return result
End While
End Using
End Using
Return result
End Function
Private Function GetMachines() As IEnumerable(Of String)
Return GetMachines("%")
End Function

Displaying SQLite Data In DataGridView VB.net

I am using sqlite database and using vb.net i am trying to print some rows in datagridview. I use the following code:
Public Sub LoadUsername()
Dim ConnectionString As String = "Data Source=info.sqlite"
Dim nSQL As String = "SELECT Name From employee"
Dim dt As DataTable = Nothing
Dim ds As New DataSet
Try
Using con As New SQLiteConnection(ConnectionString)
Using cmd As New SQLiteCommand(nSQL, con)
con.Open()
Using da As New SQLiteDataAdapter(cmd)
Console.WriteLine(da)
da.Fill(ds)
dt = ds.Tables(0)
End Using
End Using
End Using
ListBox1.ValueMember = "Name"
ListBox1.DisplayMember = "FullName"
ListBox1.DataSource = dt
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
but when i execute or compile this program, it shows me System.Data.DataRowView in the field where name should be. please check the image. Thanks!
There is no FullName column in your datatable yet that's what you're trying to bind the display to. Change the DisplayMember to Name as it should work correctly.
System.Data.DataRow is just the default ToString implementation as it cant find your fullname property.

How to refresh form after selecting value from combobox

I would like to know if it is possible to refresh the current windows form I am at after selecting another value from the combo box in order to display the details of that item onto several other textboxes?
So my table looks like
table name : program
program_id program_name program_desc
1 T1 desc1
This is the code i am using atm
Dim connection As New SqlClient.SqlConnection
connection.ConnectionString = "pathway"
Dim dr As SqlDataReader
Dim prognamedesc As String
Dim filetypetxt As String
Dim prognamecombo As String
Dim filetypecombo1 As String
Dim command As New SqlCommand
Dim querycommand As New SqlCommand
connection.Open()
'THIS SECTION LOADS DATA FROM THE TABLES'
Try
command.Connection = connection
command.CommandType = CommandType.Text
command.CommandText = "select program_name,filetype from program order by program_name; select * from filetype"
querycommand.Connection = connection
querycommand.CommandType = CommandType.Text
querycommand.CommandText = "select program_name,program_desc , filetype from program where program_name like" & FiletypeComboBox1.SelectedItem & ""
dr = command.ExecuteReader
While dr.Read()
prognamecombo = dr(0)
Program_nameComboBox.Items.Add(prognamecombo)
End While
dr.NextResult()
While dr.Read()
filetypecombo1 = dr(0)
FiletypeComboBox1.Items.Add(filetypecombo1)
FiletypeComboBox1.SelectedItem = filetypecombo1
End While
dr.NextResult()
While dr.Read()
filetypetxt = dr(0)
FiletypeLabel1.Text = filetypetxt
End While
dr.NextResult()
While dr.Read()
prognamedesc = dr(0)
Program_descTextBox.Text = prognamedesc
End While
Catch ex As Exception
MsgBox(ex.Message)
End Try
connection.Close()
I was wondering if this is doable using the current code?
To implement this you have to do two things, First put all your code inside a method and call it something like RefreshForm()
public void RefreshForm()
{
// your code and binding goes here
}
The second step is by using selected index changed event over combobox you just call the method that includes all your binding code.

taking the data from database showing to combo box but the value member is different

i am taking the data from database and showing to combo box , i want to see the name but the original value is id.. i have one code here, please review it what i did the wrong here.
Public Sub nameshow()
Try
'declare variables
Dim objDataAdapter As New SqlDataAdapter
Dim objDataAdapter1 As New SqlDataAdapter
Dim objDataSet As New DataSet()
Dim objDataSet1 As New DataSet()
'//state dataset of combo box
' Set the SelectCommand properties...
objDataAdapter.SelectCommand = New SqlCommand()
objDataAdapter.SelectCommand.Connection = sql.SqlConn
objDataAdapter.SelectCommand.CommandText = "select * from tblBrand"
objDataAdapter.SelectCommand.CommandType = CommandType.Text
'//mention the second data
objdataadapter1.SelectCommand = New SqlCommand()
objDataAdapter1.SelectCommand.Connection = sql.SqlConn
objDataAdapter1.SelectCommand.CommandText = "select * from tblModel"
objDataAdapter1.SelectCommand.CommandType = CommandType.Text
' Open the database connection...
sql.SqlConn.Open()
' Fill the DataSet object with data...
objDataAdapter.Fill(objDataSet, "tblBrand")
objDataAdapter1.Fill(objDataSet1, "tblModel")
' Close the database connection...
sql.SqlConn.Close()
With (cboxBrandName)
.DataSource = objDataSet
.ValueMember = "tblBrand.BandID"
.DisplayMember = "tblBrand.BrandName"
End With
With (cboxModel)
.DataSource = objDataSet1
.ValueMember = "tblModel.ModelID"
.DisplayMember = "tblModel.ModelName"
End With
Catch ex As Exception
End Try
End Sub
after run the program nothing showing into the combo box. i dont understand why, and there is no error too.
i am calling this function in form load.
thanks....
Here is what I think happens after studying it a bit more:
You are getting an error. Most likely "Connection is already open." Then this error is swallowed by you try catch statement. Thus never reaching the adding of the datasource to the combobox. Try this instead:
Public Function SelectRows( _
ByVal dataSet As DataSet, ByVal connectionString As String, _
ByVal queryString As String) As DataSet
Using connection As New SqlConnection(connectionString)
Dim adapter As New SqlDataAdapter()
adapter.SelectCommand = New SqlCommand( _
queryString, connection)
adapter.Fill(dataSet)
Return dataSet
End Using
End Function
Call it with this:
objDataSet = SelectRows(objDataSet, "ConnectionString","select * from tblBrand")
With (cboxBrandName)
.DataSource = objDataSet
.ValueMember = "tblBrand.BandID"
.DisplayMember = "tblBrand.BrandName"
End With
I do believe this will work.

fetching single value form database in vb.net

this my database table
id name
1   abc
2    xyz
it i enter 1 then respective value "abc" display in different text box???
Private Sub butsea_Click(sender As Object, e As EventArgs) Handles butsea.Click
Dim dset As New DataSet
Dim da As SqlDataAdapter
Dim myCmd As New SqlCommand
Try
myConn.ConnectionString = "Data Source=THEONE\PARTH;Initial Catalog=testdatabase;Integrated Security=True;"
myConn.Open()
Dim avalue As String = (InputBox("Input Student Id", "Search Student")).ToString
txt_id.Text = avalue
da = New SqlDataAdapter("SELECT * FROM studentdetails where student_id= '" & txt_id.Text & "", myConn)
If dset.Tables(0).Rows.Count > 0 Then
'what should i write here
Else
MsgBox("No Record Found")
End If
Catch ex As Exception
MsgBox(ex.Message)
Finally
myConn.Close()
End Try
End Sub
If you need to fetch just a single value - using DataAdapter and DataSet is overkill. Use SqlCommand.ExecuteScalar method and in your query instead of "SELECT * ..." do a "SELECT YOURFIELD ... ".
this way you don't have to jump thru hoops building a dataset, checking number of rows etc. and just check returned value for Nothing instead.
UPDATE Here is your code modified to use ExecuteScalar
Private Sub butsea_Click(sender As Object, e As EventArgs) Handles butsea.Click
Dim myCmd As SqlCommand
Dim myConn As New SqlConnection
Dim oResult As Object
Try
myConn.ConnectionString = "Data Source=THEONE\PARTH;Initial Catalog=testdatabase;Integrated Security=True;"
myConn.Open()
Dim avalue As String = (InputBox("Input Student Id", "Search Student")).ToString
txt_id.Text = avalue
myCmd = New SqlCommand("SELECT student_name FROM studentdetails where student_id= '" & txt_id.Text & "'", myConn)
oResult = myCmd.ExecuteScalar()
If oResult IsNot Nothing Then
txt_name.text = oResult.ToString
Else
MsgBox("No Record Found")
End If
Catch ex As Exception
MsgBox(ex.Message)
Finally
myConn.Close()
End Try
End Sub
This code assumes that database field that u need to display is called student_name and that you added TextBox called txt_name to your form.
You need to add other textboxes for every field you want to show.
(For example a textbox called txtStudentName could be used for the name, and so on for other fields present in the table studentdetails).
The correct way to query your database (leaving out other methods like using a SqlDataReader) should be the following
Dim dset As New DataSet
Dim da As SqlDataAdapter
Try
myConn.ConnectionString = "Data Source=THEONE\PARTH;Initial Catalog=testdatabase;Integrated Security=True;"
myConn.Open()
Dim avalue As String = (InputBox("Input Student Id", "Search Student")).ToString
txt_id.Text = avalue
' prepare the adapter with a commandtext. Do not use string concatenation from user input'
da = New SqlDataAdapter("SELECT * FROM studentdetails where student_id=#id", myConn)
da.SelectCommand.Parameters.AddWithValue("#id", txt_id.Text)
' Fill the dataset'
da.Fill(dset)
If dset.Tables(0).Rows.Count > 0 Then
' Supposing you have a field for the studentname in the first column of the returned
' datatable rows(rowindex)(columnindex)
txtStudentName.Txt = dset.Tables(0).Rows(0)(0).ToString()
.....
' Set the text property of other textboxes for other fields to show'
Else
MsgBox("No Record Found")
End If