Converting Combobox Value.Member from Sttring to Integer? - vb.net

I have 2 comboboxes which contain ID columns (SID & CID) as the valuemember and the displayMember is text.
I want to use the valueMembers to INSERT into an SQL database.
However the ValueMember property is a String and the column in the database is an Integer.
How can I get these 2 valueMembers converted into Integers.
The code for the complete form is shown below.
Imports System.Data.SqlClient
Imports My_Greeting.Add_VersesDataSetTableAdapters
Public Class frmAddRecord
Private MyDatAdp As New SqlDataAdapter
Private MyDataTbl As New DataTable
Private sql As String = Nothing
Private ds As New DataSet()
Private stepinfo As String = String.Empty
Dim E1 As String
Dim E2 As String
Dim Verse As String
Private connectionString As String = "Data Source=DESKTOP-S7FRNAL\SQLEXPRESS;Initial Catalog=Verses_Find;Integrated Security=True"
Private Sub frmAddRecord_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.TopMost = True
Me.WindowState = FormWindowState.Normal
Me.Sub_EventTableAdapter1.Fill(Me.EventSubDataSet1.Sub_Event)
Me.Event_TypeTableAdapter1.Fill(Me.PrimEventDataSet1.Event_Type)
Dim evt As String
Dim SEvt As String
Dim Verse As String
Dim sql As String = Nothing
Dim ds As New DataSet()
Dim stepinfo As String = String.Empty
Try
stepinfo = "Step: instatiate connection"
Using connection As New SqlConnection(connectionString)
stepinfo = "step: test open connection"
connection.Open()
sql = "Select SID, EVENT from Event_Type"
Using adaptor As New SqlDataAdapter(sql, connection)
adaptor.Fill(ds, "Tab_Event_Type")
End Using
stepinfo = "Load second data"
sql = "Select BID,SUBEVENT from Sub_Event"
Using adaptor As New SqlDataAdapter(sql, connection)
adaptor.Fill(ds, "Tab_Sub_Event")
End Using
End Using
stepinfo = "Step: Bind Event combobox"
cboEvent.DataSource = ds.Tables("Tab_Event_Type")
cboEvent.ValueMember = "SID"
cboEvent.DisplayMember = "Event"
stepinfo = "Bind Sub_Event combobox"
cboSEvent.DataSource = ds.Tables("Tab_Sub_Event")
cboSEvent.ValueMember = "BID"
cboSEvent.DisplayMember = "SubEvent"
Catch ex As Exception
MessageBox.Show($"Error:{stepinfo}{vbNewLine}{ex.ToString}")
End Try
evt = cboEvent.ValueMember
SEvt = cboSEvent.ValueMember
Verse = txtNewVerse.Text
E1 = CType(evt, Integer)
E2 = CType(SEvt, Integer)
End Sub
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
Dim query As String = String.Empty
query &= "INSERT INTO Verse (Event, Event_Sub, Verse)"
query &= "VALUES (#Event, #Event_Sub, #Verse)"
Using conn As New SqlConnection("Data Source=DESKTOP-S7FRNAL\SQLEXPRESS;Initial Catalog=Verses_Find;Integrated Security=True")
Using Comm As New SqlCommand()
With Comm
.Connection = conn
.CommandType = CommandType.Text
.CommandText = query
.Parameters.AddWithValue("#Event", E1)
.Parameters.AddWithValue("#Event_Sub", E2)
.Parameters.AddWithValue("#Verse", Verse)
End With
Try
conn.Open()
Comm.ExecuteNonQuery()
Catch ex As Exception
MessageBox.Show(ex.Message.ToString(), "Error Message")
End Try
End Using
End Using
End Sub
End Class
I have tried CInt and CType, but they dont work.
Conversion from string "SID" to type 'Integer' is not valid.

The issue lies in these lines of code:
cboEvent.ValueMember = "SID"
...
Dim evt As String
...
evt = cboEvent.ValueMember
...
Dim E1 As String
...
E1 = CType(evt, Integer)
You can simplify it into
Dim E1 As String = CType("SID", Integer)
Which is obviously not going to work. I'm not sure of your intent, but this is surely your issue.
Edit to address your comments
Here is the title of your question Converting Combobox Value.Member from Sttring [sic] to Integer?
Let's try to figure out what you are trying to do. (By the way, it is nice when we don't need to try to figure out a questioner's intent; rather it is apparent. Anyway, let's do that now)
Regarding this nugget: Combobox Value.Member, it's unclear whether you actually want the ValueMember, SelectedValue, or Text (Text being the closest proxy to Value alone).
The ValueMember tells a control which property to return via SelectedValue when the control is data-bound. For example,
Dim source = (
From i In Enumerable.Range(5, 5)
Select New With {
.Number = i,
.Square = i ^ 2
}).ToList()
ComboBox1.DataSource = source
ComboBox2.DataSource = source
ComboBox2.DisplayMember = "Number"
ComboBox2.ValueMember = "Square"
Let's see what the results of the three properties in question are, for both ComboBoxes
MessageBox.Show($"{ComboBox1.ValueMember}, {ComboBox2.ValueMember}")
, Square
MessageBox.Show($"{ComboBox1.Text}, {ComboBox2.Text}")
{ Number = 5, Square = 25}, 5
MessageBox.Show($"{ComboBox1.SelectedValue}, {ComboBox2.SelectedValue}")
{ Number = 5, Square = 25}, 25
The last one is probably what you want. ComboBox2.ValueMember has been set as the "Square" property of the anonymous type in the LINQ expression.
So in your example, the offending code is in my first code block, and it should be obvious that assigning evt = cboEvent.ValueMember is wrong and that you probably wanted the SelectedValue
evt = cboEvent.SelectedValue
which should have been clear from our comments, and answer. #jmcilhinney's comment specifically
The ValueMember is the name of the member from which the values come. It is NOT the value(s). That's what the SelectedValue property is for. The SelectedValue is where you'll find the value from the specified member of the SelectedItem. – jmcilhinney 16 hours ago
that last part again
16 hours ago
You can lead a horse to water, but you can't make him drink.

Related

Can't display Data in ComboBox Control of DropDownStyle (DropDownList)

I have the following requirement,
I have a ComboBox Control (DropDownList Style) which user has to select a given value, but can not edit. Then I save it to a Database Table, and it's working fine.
(dataRow("it_discount_profile") = Trim(cmbDisProfile.Text))
But when I try to show the same Data in the same ComboBox by retrieving it from the Database, it won't show.
(cmbDisProfile.Text = Trim(tempTb.Rows(0).Item("it_discount_profile")))
When I change the ComboBox to "DropDown Style", it works. But then the User can edit it.
Am I missing something here or is it like that? Any advice will be highly appreciated.
Im filling it in runtime using a procedure.
Private Sub filldisProfiles()
Dim sqlString As String = "SELECT discount_profile FROM tb_discount_profiles"
Dim tempTb As DataTable
Dim myTbClass As myClassTableActivities = New myClassTableActivities()
tempTb = myTbClass.myFunctionFetchTbData(sqlString)
cmbDisProfile.DataSource = tempTb
cmbDisProfile.DisplayMember = "discount_profile"
End Sub
Ok. Actually, Im trying to migrate one of my old project from VB to VB.Net. VB.Net is little new to me. Im using a self built classto reduce codes in other places. Im attaching the class below.
My actual requirement is to populate the combo box from a table. I like to do it in run time. I don't want users to edit it. If they want to add a new value, they have separate place (Form) for that. I think im doing it in a wrong way. If possible please give a sample code since I'm not familiar with the proposed method.
Public Function myFunctionFetchTbData(ByVal inputSqlString As String) As DataTable
Try
Dim SqlCmd As New SqlCommand(inputSqlString, conn)
Dim dataAdapter As New SqlDataAdapter(SqlCmd)
Dim fetchedDataSet As New DataSet
fetchedDataSet.Clear()
dataAdapter.Fill(fetchedDataSet)
Dim fetchedDataTable As DataTable = fetchedDataSet.Tables(0)
Return fetchedDataTable
Catch ex As Exception
MsgBox(Err.Description)
End Try
End Function
' this sub will update a table
Public Sub MyMethodUpdateTable(ByVal sqlString As String, ByVal tbToUpdate As DataTable)
Dim SqlCmd As New SqlCommand(sqlString, conn)
Dim dataAdapter As New SqlDataAdapter(SqlCmd)
Dim objCommandBuilder As New SqlClient.SqlCommandBuilder(dataAdapter)
dataAdapter.Update(tbToUpdate)
End Sub
Public Function MyMethodfindRecord(ByVal strSearckKey As String, ByVal tableName As String, ByVal strColumnName As String) As Boolean
Try
Dim searchSql As String = "SELECT * FROM " & tableName & " WHERE " & strColumnName & "='" & strSearckKey & "'"
'Dim searchString As String = txtCategoryCode.Text
' searchOwnerCmd.Parameters.Clear()
' searchOwnerCmd.Parameters.AddWithValue("a", "%" & search & "%")
Dim tempTb As DataTable
Dim myTbClass As myClassTableActivities = New myClassTableActivities()
tempTb = myTbClass.myFunctionFetchTbData(searchSql)
If tempTb.Rows.Count = 0 Then
Return False
Else
Return True
End If
Catch ex As Exception
MsgBox(Err.Description)
End Try
End Function
Public Function myFunctionFetchSearchTB(ByVal inputSqlString As String) As DataTable
Try
Dim SqlCmd As New SqlCommand(inputSqlString, conn)
Dim dataAdapter As New SqlDataAdapter(SqlCmd)
Dim fetchedDataSet As New DataSet
fetchedDataSet.Clear()
dataAdapter.Fill(fetchedDataSet)
Dim fetchedSearchTB As DataTable = fetchedDataSet.Tables(0)
Return fetchedSearchTB
Catch ex As Exception
MsgBox(Err.Description)
End Try
End Function
OK. If I understood correctly, you have a problem in retrieving Data [String] from a Database Table into a ComboBox of DropDownStyle [DropDownList].
How do you fill/populate your ComboBox with Data From Database Table ?
In this link, Microsoft docs state, that:
Use the SelectedIndex property to programmatically determine the index
of the item selected by the user from the DropDownList control. The
index can then be used to retrieve the selected item from the Items
collection of the control.
In much more plain English
You can never SET ComboBox.Text Value while in DropDownList by code, which you already knew by testing your code, but you need to use DisplayMember and ValueMember or SelectedIndex.
ComboBox1.SelectedIndex = ComboBox1.FindStringExact(Trim(tempTb.Rows(0).Item("it_discount_profile")))
Please consider populating your ComboBox Control from Database Table using (Key,Value) Dictionary collection, here is an example
Thank you guys for all the advice's. The only way it can be done is the way u said. I thought of putting the working code and some points for the benefit of all.
proposed,
ComboBox1.SelectedIndex = comboBox1.FindStringExact(Trim(tempTb.Rows(0).Item("it_discount_profile")))"
does not work when u bind the datatable to the combobox. The values should be added to the combo box in run time if the above "SelectedIndex" method to work. The code to add items to the combobox is as follows(myClassTableActivities is a class defined by myself and its shown above),
Private Sub filldisProfiles()
Dim sqlString As String = "SELECT discount_profile FROM tb_discount_profiles"
Dim tempTb As DataTable
Dim myTbClass As myClassTableActivities = New myClassTableActivities()
tempTb = myTbClass.myFunctionFetchTbData(sqlString)
Dim i As Integer = 0
For i = 0 To tempTb.Rows.Count - 1
cmbDisProfile.Items.Add(Trim(tempTb.Rows(i).Item("discount_profile")))
Next
End Sub
After adding we can use the following code to display the data on combobox (DropDownList).
Private Sub txtItCode_TextChanged(sender As Object, e As EventArgs) Handles txtItCode.TextChanged
Try
Dim sqlString As String = "SELECT * FROM tb_items where it_code='" & Trim(txtItCode.Text) & "'"
Dim tempTb As DataTable
Dim myTbClass As myClassTableActivities = New myClassTableActivities()
tempTb = myTbClass.myFunctionFetchTbData(sqlString)
If Len(txtItCode.Text) < 4 Then
cmdAdd.Enabled = False
cmdDelete.Enabled = False
cmdSave.Enabled = False
Else
If tempTb.Rows.Count > 0 Then
With tempTb
txtItName.Text = Trim(tempTb.Rows(0).Item("it_name"))
cmbDisProfile.SelectedIndex = cmbDisProfile.FindStringExact(Trim(tempTb.Rows(0).Item("it_discount_profile")))
cmbProfitProfile.SelectedIndex = cmbProfitProfile.FindStringExact(Trim(tempTb.Rows(0).Item("it_profit_profile")))
cmbItCategory.SelectedIndex = cmbItCategory.FindStringExact(Trim(tempTb.Rows(0).Item("it_category")))
cmbFinanCategory.SelectedIndex = cmbFinanCategory.FindStringExact((tempTb.Rows(0).Item("it_finance_category")))
End With
cmdAdd.Enabled = False
cmdDelete.Enabled = True
cmdSave.Enabled = True
Else
cmdAdd.Enabled = True
cmdDelete.Enabled = False
cmdSave.Enabled = False
txtItName.Text = ""
Call fillItCategories()
Call fillProProfile()
Call filldisProfiles()
Call fillFinCat()
End If
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try

Defining Variables that are accessible page wide

Good morning guys,
I am working on vb.net. The aim is to make a CodeFile run some sql queries and then return the values to the webpage as an sqldatasource query parameter on page load.
I have the following vb code
Partial Class Consult
Inherits Page
Public totalCount As Integer = "0"
'*******Here i declare the variable***************
Public Property PatNo() As String
Get
Return ViewState("PatNo")
End Get
Set(ByVal value As String)
ViewState("PatNo") = value
End Set
End Property
Public PatNam As String = "abc"
Public ConID As String = "abc"
Public TreatType As String = "abc"
Public HPC As Char = "abc"
Public LvTyp As RadioButtonList
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Me.PatNo = Request.QueryString("pNo")
Session("PatientNo") = PatNo
Dim ConsultationID As String = Request.QueryString("consultID")
ConID = ConsultationID
Response.Write(PatNo)
Dim constr As String = ConfigurationManager.ConnectionStrings("DefaultConnection").ConnectionString
Using con As New SqlConnection(constr)
'**********BELOW LINE CAUSES ERROR**************
Dim query As String = "SELECT * FROM hPatients WHERE pNO=#PatNo"
query += "SELECT * FROM hPatients WHERE pNO='001/000034824'"
Using cmd As New SqlCommand(query)
cmd.Parameters.Add("#PatNo", SqlDbType.NVarChar).Value = PatNo
Using sda As New SqlDataAdapter()
cmd.Connection = con
sda.SelectCommand = cmd
Using ds As New DataSet()
sda.Fill(ds)
gvPatientInfo.DataSource = ds.Tables(0)
'Return ds.Tables(0).Rows(0).Item(2)
'Response.Write(ds.Tables(0).Rows(0).Item(2))
gvPatientInfo.DataBind()
gvClientInfo.DataSource = ds.Tables(1)
gvClientInfo.DataBind()
End Using
End Using
End Using
End Using
If Not Me.IsPostBack Then
'Dim di As DataInfo = Me.GetInfo()
'Populating a DataTable from database.
Dim dt As DataTable = Me.GetData()
'Response.Write(ConID + " " + PatNo)
'Building an HTML string.
Dim html As New StringBuilder()
'Table start.
html.Append("<table border = '1' class = 'table'>")
'Building the Header row.
html.Append("<tr>")
For Each column As DataColumn In dt.Columns
html.Append("<th>")
html.Append(column.ColumnName)
html.Append("</th>")
Next
html.Append("</tr>")
'Building the Data rows.
For Each row As DataRow In dt.Rows
html.Append("<tr>")
For Each column As DataColumn In dt.Columns
html.Append("<td>")
html.Append(row(column.ColumnName))
html.Append("</td>")
Next
html.Append("</tr>")
Next
'Table end.
html.Append("</table>")
'Append the HTML string to Placeholder.
PlaceHolder1.Controls.Add(New Literal() With { _
.Text = html.ToString() _
})
End If
End Sub
The error i get is
Must declare the scalar variable "#PatNo".
The error occurs in the first step of getting the variable to execute the query in the page_load function.
The second step would be to get the result of the query and use on the webpage.
Somebody, Anybody, Please HELP!!!.
I think the problem is with this line:
cmd.Parameters.Add("PatNo", SqlDbType.NVarChar).Value = PatNo
Change the name from "PatNo" to "#PatNo" and it should work.

Failed to convert parameter value from a List`1 to a String

I am getting the error message:
"Failed to convert parameter value from a List`1 to a String"
and I am not sure how to correct the issue. It happens when I attempt to save a cleaningList to a Cleaner object in a database.
I am very new to visual basic and appreciate any feedback to help make this program work.
Public Class FrmMain
Dim currentRoom As String
Dim lastId As Integer
Dim cleaners As New BindingList(Of Cleaner)
'new instance of cleaner and storing it in a reference variable
Dim currentCleaner As New Cleaner()
'-------------Functions----------------
Private Function connectWithDb() As SqlConnection
'create a connection string
Dim connectionString As String = "Server=(LocalDB)\MSSQLLocalDB;Integrated Security=true;AttachDbFileName=C:\Users\Julia\Desktop\JklimeckFinalProject\JklimeckFinalProject\cleanerLists.mdf;"
'create connection object and tell it how to connect using connectionString
Dim dbConnection As New SqlConnection(connectionString)
'open the connection
dbConnection.Open()
'return the connection
Return dbConnection
End Function
'function to change the list to a string seperated by commas
Public Function changeToString() As String
'turn the list of strings into a single string for the database
'trim the leading white space so it won't show up when the list is
'converted back later
currentCleaner.CleaningList = LTrim(String.Join(",", currentCleaner.ItemList.ToArray()))
Return currentCleaner.CleaningList
End Function
'public function to get index of items that are selected
Public Function GetAllItems(index As Integer) As CheckState
End Function
'function to generate a cleaning list
Public Function getCleanList() As List(Of String)
'if statement to display tasks in lbxTasks
Dim indexChecked As Integer
'variable to hold the tasks that are listed depending on the room
'selected ' for current cleaner
Dim itemList As New List(Of String)
'determine the room and create the list of tasks depending on the checked boxes
If currentRoom = "Living Room" Then
itemList.AddRange(currentCleaner.LivRoomTasks)
ElseIf currentRoom = "Kitchen" Then
itemList.AddRange(currentCleaner.KitchenTasks)
ElseIf currentRoom = "Bathroom" Then
itemList.AddRange(currentCleaner.BathroomTasks)
ElseIf currentRoom = "Bedroom" Then
itemList.AddRange(currentCleaner.BedroomTasks)
ElseIf currentRoom = "Dining Room" Then
itemList.AddRange(currentCleaner.DinRoomTasks)
ElseIf currentRoom = "Office" Then
itemList.AddRange(currentCleaner.OfficeTasks)
ElseIf currentRoom = "Laundry Room" Then
itemList.AddRange(currentCleaner.LauRoomTasks)
ElseIf currentRoom = "General" Then
itemList.AddRange(currentCleaner.GeneralTasks)
End If
For Each indexChecked In cbxRoomItems.CheckedIndices
lbxTasks.Items.Add(itemList.Item(indexChecked).ToString)
Next
Return itemList
End Function
'function to seperated the string version of the list
Public Function changeToList() As List(Of String)
'change the comma separated sting back to a list by spliting it at the commas
lbxTasks.Items.AddRange(currentCleaner.CleaningList.Split(New Char() {","c}))
Return currentCleaner.ItemList
End Function
Private Sub FrmMain_Load(sender As Object, e As EventArgs) Handles Me.Load
'when the application loads, show list of cleaners and display by name
lbxNames.DataSource = cleaners
lbxNames.DisplayMember = "Name"
Dim dbConnection As SqlConnection = connectWithDb()
'string of sql
Dim sqlString As String = "SELECT * FROM Cleaner"
'command object pass in what to run and the object
Dim selectCommand As New SqlCommand(sqlString, dbConnection)
'place in a try catch block to keep exceptions from crashing application
Try
'variable to hold the sqlDataReader object
Dim reader As SqlDataReader = selectCommand.ExecuteReader()
If reader.HasRows Then
'read is boolean
While reader.Read
'call the sub
populateCleaners(reader)
End While
End If
reader.Close()
'determine the highest ID number in the database
'and store it in a class level variable so we can access it
'where ever it is needed
Dim identSql As String = "SELECT IDENT_CURRENT('Cleaner') as lastID"
Dim identCom As New SqlCommand(identSql, dbConnection)
Dim identReader As SqlDataReader = identCom.ExecuteReader
If identReader.HasRows Then
identReader.Read()
lastId = CInt(identReader.Item("lastId"))
End If
Catch ex As Exception
End Try
'close and dispose the connection to the db
dbConnection.Close()
dbConnection.Dispose()
End Sub
'Sub to populate the database with a new character
Private Sub populateCleaners(reader As SqlDataReader)
Dim dbCleaner As New Cleaner()
changeToString()
'get info from reader and store into new object
dbCleaner.Id = CInt(reader.Item("Id"))
dbCleaner.Name = reader.Item("Name").ToString
dbCleaner.CleaningList = reader.Item("CleaningList").ToString
'add to binding list
cleaners.Add(dbCleaner)
End Sub
'----------------Butttons------------------
'add to list button
Private Sub btnClean_Click(sender As Object, e As EventArgs) Handles btnClean.Click
'label to show the correct list is being displayed
lblCurrentCleaner.Text = currentCleaner.Name
getCleanList()
End Sub
'save cleaning list
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
Dim newCleaner As New Cleaner()
'referencing object and assigning it to the Name property for the new cleaner
newCleaner.Name = txtName.Text
'exception if the user does not enter a name
Try
newCleaner.Name = txtName.Text
Catch ex As Exception
MessageBox.Show("a cleaner has no name")
End Try
For ctr = 0 To lbxTasks.Items.Count - 1
newCleaner.ItemList.Add(lbxTasks.Items(ctr).ToString)
'change this list to a string
changeToString()
Next
newCleaner.CleaningList = changeToString()
lbxTasks.Items.Clear()
cleaners.Add(newCleaner)
currentCleaner = newCleaner
'update a cleaning list if the Id is already in the database, or create a new object
Dim dbConnection As SqlConnection = connectWithDb()
Dim sqlString As String
If currentCleaner.Id > 0 Then
sqlString = "UPDATE Cleaner SET Name = #name, CleaningList = #cleaningList WHERE Id = #id"
Else
sqlString = "INSERT INTO Cleaner (Name, CleaningList) VALUES(#name, #cleaningList)"
'increment the last Id and save that id number to the new entry in the db
lastId += 1
currentCleaner.Id = lastId
End If
Dim com As New SqlCommand(sqlString, dbConnection)
'set the values of current cleaner in the database
com.Parameters.Add("#id", SqlDbType.Int).Value = currentCleaner.Id
com.Parameters.Add("#name", SqlDbType.VarChar).Value = currentCleaner.Name
com.Parameters.Add("#cleaningList", SqlDbType.NVarChar).Value = currentCleaner.ItemList
Try
Dim result = com.ExecuteNonQuery()
MessageBox.Show(result.ToString)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
I have a Cleaner class that stores the public properties.
In the program the user clicks on different buttons that populate a checklistbox with different items found in that room, by selecting the items and clicking btnClean it populates a listbox with a list of tasks associated with the items the user selected. My problem seems to be centered around that list; it is stored in a list(of String), but I made a function to turn that list into a single string separated by commas so it can be stored in a database and another function to separated that list so it can be displayed back in the listbox when the user's name is selected.
I am not sure where it is I am going wrong.
The exception is being thrown in:
'save cleaning list
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
Dim newCleaner As New Cleaner()
'referencing object and assigning it to the Name property for the new cleaner
newCleaner.Name = txtName.Text
'exception if the user does not enter a name
Try
newCleaner.Name = txtName.Text
Catch ex As Exception
MessageBox.Show("a cleaner has no name")
End Try
For ctr = 0 To lbxTasks.Items.Count - 1
newCleaner.ItemList.Add(lbxTasks.Items(ctr).ToString)
'change this list to a string
changeToString()
Next
lbxTasks.Items.Clear()
cleaners.Add(newCleaner)
currentCleaner = newCleaner
'update a cleaning list if the Id is already in the database, or create a new object
Dim dbConnection As SqlConnection = connectWithDb()
Dim sqlString As String
If currentCleaner.Id > 0 Then
sqlString = "UPDATE Cleaner SET Name = #name, CleaningList = #cleaningList WHERE Id = #id"
Else
sqlString = "INSERT INTO Cleaner (Name, CleaningList) VALUES(#name, #cleaningList)"
'increment the last Id and save that id number to the new entry in the db
lastId += 1
currentCleaner.Id = lastId
End If
Dim com As New SqlCommand(sqlString, dbConnection)
com.Parameters.Add("#name", SqlDbType.VarChar).Value = currentCleaner.Name
com.Parameters.Add("#cleaningList", SqlDbType.NVarChar).Value = currentCleaner.ItemList
Try
Dim result = com.ExecuteNonQuery()
MessageBox.Show(result.ToString)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Again thank you for any suggestions/help!

letting user type and add value to an already bound combobox

I have one combobox in my app that gets populated with a dozen or so items from SQL SERVER. I am currently trying to allow user to be able to type in a new value into the combobox and save it to a table in SQL SERVER. I'm looking for something along the lines of a DropDownStyle of DropDown and DropDownList. Basically I'm hoping to let the user type in the combobox, however if the value is not there, i want to be able to give them an option of saving it (probably on lost focus). I'm wondering what would be a good way of doing something like that.
On lost focus should I basically go through each item that is currently in the drop down and check it against the value entered?
EDIT:
Sql="SELECT IDvalue, TextName from TblReference"
Dim objconn As New SqlConnection
objconn = New SqlConnection(conn)
objconn.Open()
Dim da As New SqlDataAdapter(sql, objconn)
Dim ds As New DataSet
da.Fill(ds, "Name")
If ds.Tables("Name").Rows.Count > 0 Then
Dim dr As DataRow = ds.Tables("Name ").NewRow
ds.Tables("Name").Rows.InsertAt(dr, 0)
With c
.DataSource = ds.Tables("Name")
.ValueMember = " IDvalue "
.DisplayMember = " TextName "
End With
End If
You are already adding a fake/blank row to a table, you can do the same thing for a new item.
' form level datatable var
Private cboeDT As DataTable
Initializing:
cboeDT = New DataTable
Dim sql = "SELECT Id, Descr FROM TABLENAME ORDER BY Descr"
Using dbcon As New MySqlConnection(MySQLConnStr)
Using cmd As New MySqlCommand(sql, dbcon)
dbcon.Open()
cboeDT.Load(cmd.ExecuteReader())
' probably always need this even
' when there are no table rows (???)
Dim dr = cboeDT.NewRow
dr("Id") = -1 ' need a way to identify it
dr("Descr") = ""
cboeDT.Rows.InsertAt(dr, 0)
End Using
End Using
cboeDT.DefaultView.Sort = "Descr ASC"
cboE.DataSource = cboeDT
cboE.DisplayMember = "Descr"
cboE.ValueMember = "Id"
Note Users tend to have a preference as to the order of these things. The simple creatures tend to prefer alphabetical over a DB Id they may never see. To accommodate them, the DefaultView is sorted so that any new rows added will display in the correct order.
Add new items in the Leave event (much like Steve's):
Private Sub cboE_Leave(sender ...
' if it is new, there will be no value
If cboE.SelectedValue Is Nothing Then
' alternatively, search for the text:
'Dim item = cboeDT.AsEnumerable().
' FirstOrDefault(Function(q) String.Compare(q.Field(Of String)("Descr"),
' cboE.Text, True) = 0)
'If item Is Nothing Then
' ' its new...
Dim newid = AddNewItem(cboE.Text)
Dim dr = cboeDT.NewRow
dr("Id") = newid
dr("Descr") = cboE.Text
cboeDT.Rows.Add(dr)
' fiddling with the DS looses the selection,
' put it back
cboE.SelectedValue = newid
End If
End Sub
If you want to search by text:
Dim item = cboeDT.AsEnumerable().
FirstOrDefault(Function(q) String.Compare(q.Field(Of String)("Descr"),
cboE.Text, True) = 0)
If item Is Nothing Then
' its new...
...
Inserting will vary a little depending on the actual db. A key step though is to capture and return the ID of the new item since it is needed for the CBO:
Private Function AddNewItem(newItem As String) As Int32
Dim sql = "INSERT INTO MY_TABLE (Descr) VALUES (#v); SELECT LAST_INSERT_ID();"
Dim newId = -1
Using dbcon As New MySqlConnection(MySQLConnStr)
Using cmd As New MySqlCommand(sql, dbcon)
dbcon.Open()
cmd.Parameters.Add("#v", MySqlDbType.String).Value = newItem
' MySql provides it in the command object
If cmd.ExecuteNonQuery() = 1 Then
newId = Convert.ToInt32(cmd.LastInsertedId)
End If
End Using
End Using
Return newId
End Function
As noted MySql provides the LastInsertedID as a command object property. In SQL SERVER, tack ...";SELECT LAST_INSERT_ID();" to the end of your SQL and then:
newId = Convert.ToInt32(cmd.ExecuteScalar())
This is not conceptually very different from Steve's answer, except it uses the DataTable you build rather than collections which makes it (very) slightly simpler.
The way I do this, is on window load I perform a new SQL query to get the list of values in the table, and load them into a combobox.
Then once focus is lost, it then checks what's currently typed into the combobox against the current values already loaded. If it doesn't exist, then it's not in SQL. Something like the following...
Dim found As Boolean = False
For i As Integer = 0 To comboBox.Items.Count - 1
Dim value As String = comboBox.Items(i).ToString()
If comboBox.Text = value Then
found = True
End If
Next
If found = False Then
'the item doesn't exist.. add it to SQL
Else
'the item exists.. no need to touch SQL
End If
First thing I would do is to build a simple class to hold your values through a List of this class
Public Class DataItem
Public Property IDValue As Integer
Public Property TextName as String
End Class
Now, instead of building an SqlDataAdapter and fill a dataset, work with an SqlDataReader and build a List(Of DataItem)
' Class global...
Dim allItems = new List(Of DataItem)()
Sql="SELECT IDvalue, TextName from TblReference"
' Using to avoid leaks on disposable objects
Using objconn As New SqlConnection(conn)
Using cmd As New SqlCommand(Sql, objconn)
objconn.Open()
Using reader = cmd.ExecuteReader()
While reader.Read()
Dim item = new DataItem() With { .IDValue = reader.GetInt32(0), .TextName = reader.GetString(1)}
allItems.Add(item)
End While
End Using
if allItems.Count > 0 Then
allItems.Insert(0, new DataItem() With {.IDValue = -1, .TextValue = ""}
Dim bs = new BindingList(Of DataItem)(allItems)
c.DataSource = bs
c.ValueMember = "IDvalue"
c.DisplayMember = "TextName"
End If
End Using
End Using
Now the code that you want to add to your Leave event for the combobox
Sub c_Leave(sender As Object, e As EventArgs) Handles c.Leave
If Not String.IsNullOrEmpty(c.Text) Then
Dim bs = DirectCast(c.DataSource, BindingList(Of DataItem))
if bs.FirstOrDefault(Function(x) x.TextName = c.Text) Is Nothing Then
Dim item = new DataItem() With { .IDValue = -1, .TextName = c.Text}
bs.Add(item)
' here add the code to insert in the database
End If
End If
End Sub

Combobox selected Item does not match with its selected

I faced with that issue which appears with spaces after letters finished more than Combobox.SelectedItem's length. Why? How can I fix this issue?
Below is showing my issue as visual its a very short and small video.
Here is a small video
Imports System.Data.SqlClient
Public Class Main
WithEvents bsData As New BindingSource
Dim sConn As New SqlConnection
Dim dt As New DataTable
Dim ds As New DataSet
Private Sub Main_Load(sender As Object, e As EventArgs) Handles MyBase.Load
sConn.ConnectionString = "Data Source=PC-N39;Initial Catalog=Esi01;Persist Security Info=True;User ID=sa;Password=sas"
sConn.Open()
Try
Dim myTable As DataTable = New DataTable("MyTable")
myTable.Columns.Add(New DataColumn("Group Code"))
myTable.Columns.Add(New DataColumn("Description"))
myTable.Columns.Add(New DataColumn("NothingSerious"))
Dim cmd As New SqlCommand("Select * from tbUnit", sConn)
Dim dr As SqlDataReader = cmd.ExecuteReader(CommandBehavior.Default)
Dim myRow As DataRow
While dr.Read()
myRow = myTable.NewRow
myRow.Item(0) = dr(0)
myRow.Item(1) = dr(1)
myRow.Item(2) = dr(2)
myTable.Rows.Add(myRow)
End While
dr.Close()
Dim myData4 As DataTable = myTable
ds = New DataSet()
ds.Tables.Add(myData4)
MultiColumnCombo1.DisplayMember = "Group Code"
MultiColumnCombo1.DrawMode = DrawMode.OwnerDrawVariable
MultiColumnCombo1.ColumnWidths = "50;150"
MultiColumnCombo1.DataSource = myData4
MultiColumnCombo1.Text = String.Empty
Catch ex As Exception
MsgBox(ex.ToString)
End Try
sConn.Close()
End Sub
End Class
What type is MultiColumnCombo1 ? I suppose it's a third party component.
As far as I can see in your video, it seems that it takes the biggest element in your data, take it's length and add spaces to other elements to make them the same size.
You probably won't be able to change the component's behavior, but you can apply the same logic to what you enter in your TextBox : adding spaces to make them match. Or if you simply need to make a condition that test if they are equal, you can do as follow :
if(YourComboboxSelectedItem.Trim() == StringYourAreComparingItTo)
See String.Trim(), that will discard the extra whitespaces.