while loop only displaying 1 item - vb.net

I am using a while loop to populate a second combo based on the value of the first combobox selection. What is happening however, is that the loop is only displaying 1 item in the second combobox instead of about 20. If I set breakpoint on the while loop I can see that all items are being calculated but just not appearing in the combobox.
I would be grateful if someone could point my basic newbie error. Many thanks
Private Sub cmbCustomer_SelectedIndexChanged(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles cmbCustomer.SelectedIndexChanged
sql = "SELECT * from Departments WHERE Customer = '" & cmbCustomer.Text & "'"
Dim cmd As New OleDb.OleDbCommand
cmd.CommandText = sql
cmd.Connection = oledbCnn
dr = cmd.ExecuteReader
While dr.Read()
If (dr.HasRows) Then
cmbDept.Text = CStr((dr("Name"))) <--- 2nd combobox
End If
End While
cmd.Dispose()
dr.Close()
End Sub

The Text property of the combo box contains only what is displayed for the selected item. You need to add the items to the Items collection:
cmbDept.Items.Add(CStr(dr("Name")))
The combo boxes, list boxes etc. display items by calling their ToString() method. Therefore calling CStr should not even be necessary:
cmbDept.Items.Add(dr("Name"))
You are inserting a value in the SQL statement by concatenating strings. If you are just using your program for yourself, this is okay; however, on productive environments this is dangerous. Someone could enter a value that terminates the SELECT statement and introduces another malicious statement. E.g. a DELETE statement that deletes a whole table. This is called a SQL injection attack.
There are two ways to deal with this:
1) Escape the string:
sql = "SELECT * FROM Dep WHERE Cust = '" & s.Replace("'", "''") & "'"
2) Use command parameters:
sql = "SELECT * from Departments WHERE Customer = ?"
Dim cmd As New OleDbCommand(sql, oledbCnn)
cmd.Parameters.AddWithValue("#p1", cmbCustomer.Text)
If you are inserting dates this also has the advantage that you don't need to bother about date formats.
You can simplify your loop to:
While dr.Read()
cmbDept.Text = CStr(dr("Name"))
End While
There is no need to test for HasRows since dr.Read() would return False anyway if no rows were available.
You can have Dispose called automatically by VB with the Using statement:
Using cmd As New OleDbCommand(sql, oledbCnn)
'TODO: Work with cmd here.
End Using
Dispose will be called at the end of the Using block, even if an error occurs within the Using block or the Using block is left by Return or another statement.

You do not need to check if the data reader has rows every iteration, just check it before you loop.
You are not adding the items to the list, but rather setting the Text property of cmbDept, instead do this:
Private Sub cmbCustomer_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbCustomer.SelectedIndexChanged
sql = "SELECT * from Departments WHERE Customer = '" & cmbCustomer.Text & "'"
Dim cmd As New OleDb.OleDbCommand
cmd.CommandText = sql
cmd.Connection = oledbCnn
dr = cmd.ExecuteReader
If (dr.HasRows) Then
While dr.Read()
cmbDept.Text = CStr((dr("Name"))) <--- 2nd combobox
End While
End If
cmd.Dispose()
dr.Close()
End Sub
Also, it is highly recommended that you use a parameterized query as to avoid a visit from Little Bobby Tables, like this:
Private Sub cmbCustomer_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbCustomer.SelectedIndexChanged
sql = "SELECT * from Departments WHERE Customer = #Customer"
Dim cmd As New OleDb.OleDbCommand
cmd.Parameters.AddWithValue("#Customer", cmbCustomer.Text)
cmd.CommandText = sql
cmd.Connection = oledbCnn
dr = cmd.ExecuteReader
If (dr.HasRows) Then
While dr.Read()
cmbDept.Text = CStr((dr("Name"))) <--- 2nd combobox
End While
End If
cmd.Dispose()
dr.Close()
End Sub

Related

error regular comes Invalid SQL statement; expected 'DELETE', 'INSERT', 'PROCEDURE', 'SELECT', or 'UPDATE'

Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged, MyBase.Activated
con.Close()
con.Open()
str = "select * from customer where CustomerID='" & ComboBox1.Text & "'"
cmd = New OleDbCommand(str, con)
da.SelectCommand = cmd
If IsNumeric(ComboBox1.Text) Then
cmd.CommandText = str = "select * from customer where CustomerID=#cid"
cmd.Prepare()
cmd.Parameters.AddWithValue("cid", ComboBox1.Text)
Dim dr As OleDbDataReader = cmd.ExecuteReader()
Try
If dr.Read() Then
TextBox1.Text = dr.GetValue(1)
TextBox2.Text = dr.GetValue(2)
TextBox3.Text = dr.GetValue(3)
TextBox4.Text = dr.GetValue(4)
TextBox5.Text = dr.GetValue(5)
dr.Close()
End If
Catch ex As Exception
MsgBox("", ex.Message)
dr.Close()
Finally
con.Close()
End Try
End If
Your code has several issues.
You did not provide your complete Combobox1_SelectedIndexChanged method. At least the last line that ends the method is missing.
You are reusing a connection. It is better practice to create a new connection (and dispose it afterwards) each time you need it. (Connection pooling might already reuse connections in the background.)
You have an exception handling mechanism that doesn't cover all your logic that can throw exceptions.
You are using two approaches to pass the SQL command text to the command object. One approach should suffice.
You call the Prepare method before you add your parameters to the command object. Apart from the fact that calling Prepare probably is not explicitly needed, I guess it should be called after you have added your parameters to the command object.
You are using the AddWithValue method to add parameters to your command object. That is evil.
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged, MyBase.Activated
'Better to use explicit column names instead of * here, especially if you use `GetValue` with a numeric index when mapping the query results to your textboxes.
Dim str As String = "select * from customer where CustomerID=#cid"
Try
Using con As New OleDbConnection("<connection string here>"), cmd As New OleDbCommand(str, con)
con.Open()
'Assuming here that CustomerID in the customer table is of type integer
cmd.Parameters.Add("#cid", OleDbType.Integer).Value = Integer.Parse(ComboBox1.Text)
Using dr As OleDbDataReader = cmd.ExecuteReader()
If dr.Read() Then
'Instead of using magical (ordinal) numbers, it would be better to use GetOrdinal as well: dr.GetValue(dr.GetOrdinal("fieldName"))
TextBox1.Text = dr.GetValue(1)
TextBox2.Text = dr.GetValue(2)
TextBox3.Text = dr.GetValue(3)
TextBox4.Text = dr.GetValue(4)
TextBox5.Text = dr.GetValue(5)
End If
'Perhaps you also want to include an Else block (in which case the database query did not return any results) to clear the textboxes?
End Using
End Using
Catch ex As Exception
MsgBox("", ex.Message)
'Closing any ADO.NET objects will be done automatically when they are disposed (when the Using block goes out of scope).
End Try
End Sub
Obviously, I have not tested the code above, since I do not have a fitting test environment for it. Please let me know if this code causes any issues you cannot solve yourself.
You have two Sql statements in your code.
1:
str = "select * from customer where CustomerID='" & ComboBox1.Text & "'"
2:
cmd.CommandText = str = "select * from customer where CustomerID=#cid"
You should get rid of #1 - delete that line of code and change #2 to be:
cmd.CommandText = "select * from customer where CustomerID=#cid"

how to display data in text box in vb.net using sql

Private Sub BtnReturn_Click(sender As Object, e As EventArgs) Handles btnReturn.Click
If BorrowAccession.Text = "" Or txtBorrowerstype.Text = "" Then
MsgBox("All fields are required.", MsgBoxStyle.Exclamation)
ElseIf txtremarks.Text = "Over Due" Then
sql = "Select * From `maintenance` fine ='" & txtfine.Text & "' "
reloadtxt(sql)
End sub
how will i display the fine in txtfine.text from my maintenance database after it satisfy the condition from txtremarks. i tried some youtube tutorials but only displaying it from data grid .. want i basically want is directly display it from database to textbox. btw im newbie in vb programming thank you in advance
for my reloadtxt this is the code.
Public Sub reloadtxt(ByVal sql As String)
Try
con.Open()
With cmd
.Connection = con
.CommandText = sql
End With
dt = New DataTable
da = New MySqlDataAdapter(sql, con)
da.Fill(dt)
Catch ex As Exception
' MsgBox(ex.Message & "reloadtxt")
Finally
con.Close()
da.Dispose()
End Try
End Sub
To populate an object with data from a database you need to access the objects text property.
Textbox1.Text = "Some Text, static or dynamic"
Since you are pulling the data from a datatable you would access the column named "fine" and put that value in the textbox.text property.
Textbox1.Text = dt.row(0).item("fine").tostring
Changed Or to OrElse because it short circuits the If and doesn't have to check the second condition if the first condition is True.
In the reloadtxt method you filled a DataTable and did nothing with it. I changed it to a Function that returns the DataTable. The connection and command are now included in a Using...End Using block so they are closed and disposed even if there is an error.
Never concatenate strings to build an sql statement. Always used parameters.
Private Sub BtnReturn_Click(sender As Object, e As EventArgs) Handles btnReturn.Click
If BorrowAccession.Text = "" OrElse txtBorrowerstype.Text = "" Then
MsgBox("All fields are required.", MsgBoxStyle.Exclamation)
ElseIf txtremarks.Text = "Over Due" Then
Dim dt = reloadtxt()
DataGridView1.DataSource = dt
End If
End Sub
Public Function reloadtxt() As DataTable
Dim dt As New DataTable
Using con As New MySqlConnection("Your connection string"),
cmd As New MySqlCommand("Select * From maintenance Where fine = #Fine", con)
cmd.Parameters.Add(#Fine, MySqlDbType.VarChar, 50).Value = txtfine.Text
Try
con.Open()
dt.Load(cmd.ExecuteReader)
Catch ex As Exception
MsgBox(ex.Message & "reloadtxt")
End Try
End Using
Return dt
End Function

Compare db value with textbox value VB

My Table
I load the windows user name to textbox1.text using 'System.Environment'
After that I query this and compare the textbox value to the PersonName in db
if it matches, I want to get the relevant Department name ie if it's 'manager'
then I want to display a form from menuitem_click event. My code is below
it dosent work can some one please help with this.
Private Sub MySamplesToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles MySamplesToolStripMenuItem.Click
Dim cn As New SqlClient.SqlConnection("Data Source=ffff;Initial Catalog=ffff;User ID=****;Password=****;")
Dim cmd As New SqlClient.SqlCommand
Dim tbl As New DataTable
Dim da As New SqlClient.SqlDataAdapter
Dim reader As SqlClient.SqlDataReader
Dim ta As String
Try
cn.Open()
Dim sql As String
sql = "select * from dbo.Person where [PersonName] ='" + TextBox1.Text + "'"
cmd = New SqlClient.SqlCommand(sql, cn)
reader = cmd.ExecuteReader
While reader.Read
ta = reader.Item("Department")
If ta = 'Maneger' Then
Form2.Show()
End If
' TextBox2.Text = reader.Item("Department")
'TextBox2.Text = reader.Item("dob")
End While
cn.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
No matter how you spell it, Manager or Maneger, just make sure what is in the database matches what is in your If statement. I think I would use a drop down box for you to select the Department wherever you are inserting the Person so the Department name would match.
The Using...End Using blocks ensure that you database objects are closed and disposed even if there is an error.
You can pass your Sql statement and the connection directly to the constructor of the command. If all you need is the Department then don't drag down all the date with "*".
Never concatenate strings to build Sql statements. A hacker could type in TextBox1 "Joe; Drop Table dbo.Person;" Using parameters stops this hole because the .Value of the parameter is treated as only a value not executable code.
You are only expecting one value in return so you can use .ExecuteScalar which returns the first column of the first row in the result set.
Your code is very fragile because I suspect you could have duplicate names unless you require unique user names.
Private Sub MySamplesToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles MySamplesToolStripMenuItem.Click
Try
Using cn As New SqlClient.SqlConnection("Data Source=ffff;Initial Catalog=ffff;User ID=****;Password=****;")
Using cmd As New SqlClient.SqlCommand("Select Department From dbo.Person Where PersonName = #Name;", cn)
cmd.Parameters.Add("#Name", SqlDbType.VarChar).Value = TextBox1.Text
cn.Open()
Dim ta As String = cmd.ExecuteScalar.ToString
If ta = "Maneger" Then
Form2.Show()
End If
TextBox2.Text = ta
End Using
End Using
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub

Error on Search Button

I searched on some codes on how to do a Search Button in VB.net. But somehow, it won't work because of an error. And simply because, I cannot understand its algorithm and function. Newbie here. Anyway, here is the code for the search button:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
myConnection.Open()
crd.Clear()
fn.Clear()
ln.Clear()
Dim str As String
str = "SELECT * FROM tblReg WHERE (Code = '" & src.Text & "')"
Dim cmd As OleDbCommand = New OleDbCommand(str, myConnection)
dr = cmd.ExecuteReader
While dr.Read()
crd.Text = dr("crd").ToString
fn.Text = dr("fName").ToString
ln.Text = dr("lName").ToString
End While
myConnection.Close()
End Sub
And the error was on:
dr = cmd.ExecuteReader
And VB said:
An unhandled exception of type 'System.Data.OleDb.OleDbException' occurred in System.Data.dll
Additional information: No value given for one or more required parameters.
One should not follow online tutorials that teach very bad code. That code is very bad because it contains SQL injection and leaves database objects opened.
You should rewrite your code as follows:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
myConnection.Open()
crd.Clear()
fn.Clear()
ln.Clear()
Using cmd = New OleDbCommand("SELECT * FROM tblReg WHERE Code = ?", myConnection)
cmd.CommandType = CommandType.Text
With cmd.Parameters.Add(Nothing, OleDbType.VarChar, 50)
.Direction = ParameterDirection.Input
.Value = src.Text
End With
Using dr = cmd.ExecuteReader()
While dr.Read()
crd.Text = dr("crd").ToString
fn.Text = dr("fName").ToString
ln.Text = dr("lName").ToString
End While
End Using
End Using
myConnection.Close()
End Sub
You have to use question marks in place of parameters because you are using OleDbCommand that does not support named parameters.
Change OleDbType.VarChar to your actual column type.
Is this the link where you get the code?
http://www.visual-basic-tutorials.com/ReadFromAccess.htm
Kindly do not get the code read each data on the output shows and also check this part of the code.
crd.Text = dr("crd").ToString
fn.Text = dr("fName").ToString
ln.Text = dr("lName").ToString
are you sure crd,fname,lname are the name of your fields in your table? pls check it and also what is the field type of code? is it a text or INT that is Auto Increment? or just an INT? no matter what it is change your code.
from
str = "SELECT * FROM tblReg WHERE (Code = '" & src.Text & "')"
to
str = "SELECT * FROM tblReg WHERE Code =" & src.Text
Updated
I suggest better read or follow the whole instruction based on link where you get your code. I suggest do the same as what the link said create the same and when the program runs with no error then incorporate it with your program beacuse I tried it using VB.NET and Access and it worked Im sure you dont read it. Do this and Im sure you will not just get the code you need you will also learn.

combobox doesn't return any text in vb.net

I have a function that get 3 argument , a textbox and 2 combobox and use them in the code as temp of a OleDbDataReader but I have a problem and take runtime
error: No value given for one or more required parameters.
Sub load_txt_code(ByVal nkala As ComboBox, ByVal ckala As ComboBox, ByVal ghyemat As TextBox)
dr.Close()
cmd.Connection = con
cmd.CommandText = "select name_jens from ajnas where id = " & nkala.Text & ""
dr = cmd.ExecuteReader()
While dr.Read
nkala.Text = dr.Item(0)
End While
'por kardane combobox e gheymat
dr.Close()
cmd.CommandText = "select gheymate_forush from ajnas where id = " & ckala.Text & ""
dr = cmd.ExecuteReader()
While dr.Read
If Not IsDBNull(dr.Item(0)) Then
ghyemat.Text = dr.Item(0)
Else
ghyemat.Text = Nothing
End If
End While
End Sub
add a breakpoint in the gheymat.text = dr.item(0) to see if it ever goes there.
Your code makes it possible that your text is overwritten if field 0 has a value and field 1 has none.
It will read field (1) and then overwrite the text you set wiht dr.item(0) before. So you should add an "end while" behind gheymat.text = dr.item(0) - if your code ever goes there. If this is not enough to tackle it, add an early breakpoint and F10 trough it all, then you can see if your query generates any data in the first place.