Automatically update an ID label - vb.net

I am working on making a label inside my Windows Form to display new ID automatically. My label was connected to an access database and I want to make the label to display new ID after the last record of ID inside my database. For example, the last record is 'tt0005061' from Movie table. The label should display a new ID, 'tt0005062'.
Public Class Movies_Registration_Form
Dim index As Integer = 0
Private Sub Movies_Registration_Form_Load(sender As Object, e As EventArgs) Handles MyBase.Load
showData(index)
End Sub
Public Sub showData(position As Integer)
conn = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=1MDb.accdb;Persist Security Info=False;")
strSQL = "SELECT RIGHT(tconst,7) From Movie ORDER BY tconst DESC"
cmd = New OleDbCommand(strSQL, conn)
da = New OleDbDataAdapter(cmd)
da.Fill(table)
lblMovieID.Text = "tt" & table.Rows(0)(0).ToString()
End Sub
The output of the label should be in an increment form, meaning that it should be +1 from the last record inside my database.

Try with:
lblMovieID.Text = (Integer.Parse(table.Rows(0)(0)) + 1).ToString("tt0000000")

Related

How do relationships work and how can I implement it in my project?

I have a User table and Institutions table. I have put made a relationship with those two in access. Inst id is now in user table as a foreign key.
In my vb form, i populate a combobox with the institution names from inst table. When I select a username from a list box, his/hers relevant details are captured into textboxes on the form. But I dont know how to capture the Institution name using the foreign key.
'actions when listbox selection is changed
Private Sub listbox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
cbInst_putData()
cbAccountType_putData()
If gbEditUser.Visible = True Then
Dim selected_item As String = ListBox1.SelectedItem
qr = "Select * FROM [User] WHERE Username = '" & selected_item & "'"
Using cn As New OleDbConnection(cnString)
cn.Open()
Using cmd As New OleDbCommand(qr, cn)
Dim reader As OleDbDataReader = cmd.ExecuteReader
While reader.Read
txtFirstname_edit.Text = reader.Item("Firstname").ToString
txtLastname_edit.Text = reader.Item("Lastname").ToString
txtAddress_edit.Text = reader.Item("Address").ToString
txtPhone_edit.Text = reader.Item("Phone").ToString
Dim dt As Date = Date.Parse(reader.Item("DateofBirth").ToString)
txtdob_edit.Text = dt
txtUsername_edit.Text = reader.Item("Username").ToString
txtPassword_edit.Text = reader.Item("Password").ToString
cbAccountType_edit.SelectedItem = reader.Item("AccountType").ToString
cbInst_edit.Text = reader.Item("InstitutionIDFK").ToString ' this is the combobox for institution list.
txtDesc.Text = reader.Item("Description").ToString
Dim checkActive As String
checkActive = reader.Item("Active").ToString
End While
End Using
cn.Close()
End Using
End If
End Sub
I want to store the institution name in the user table and also be able to capture it again. I did it without making a relationship before. By just having a institution field separately in the user table.
Im very new to vb. And completely new to posting on here even though ive been looking at other questions on this site. So please excuse me if my codes are bad and if im not posting properly.
Pretend that my Roasters are institutions and my Coffees are Users.
I bind the list box and the combo box to the data in the Form.Load.
When the selection in the ListBox is changed we get the RoasterId (the Foreign Key) associated with the selection. Next we loop through the items in the combo box Primary Key in the ID field. When we get a match, select that item and exit the loop.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim RoastersSql = "Select * From Roasters;"
Dim CoffeesSql = "Select Top 10 * From Coffees;"
Dim RoastersDT As New DataTable
Dim CoffeeDT As New DataTable
Using cn As New SqlConnection(ConGD)
Using cmd As New SqlCommand(RoastersSql, cn)
cn.Open()
Using reader = cmd.ExecuteReader
RoastersDT.Load(reader)
End Using
End Using
Using cmd As New SqlCommand(CoffeesSql, cn)
Using reader = cmd.ExecuteReader
CoffeeDT.Load(reader)
End Using
End Using
End Using
ListBox1.DisplayMember = "Name"
ListBox1.ValueMember = "ID" 'NOT the RoasterID, this is th PK of the Coffees table
ListBox1.DataSource = CoffeeDT
ComboBox1.DisplayMember = "Name"
ComboBox1.ValueMember = "ID"
ComboBox1.DataSource = RoastersDT
UpdateUI(ListBox1.SelectedItem)
End Sub
Private Sub FillTextBoxes(item As Object)
Dim drv = DirectCast(item, DataRowView)
TextBox1.Text = drv("Name").ToString
TextBox2.Text = drv("Type").ToString
End Sub
Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
UpdateUI(ListBox1.SelectedItem)
End Sub
Private Sub UpdateUI(item As Object)
Dim RoasterID = CInt(DirectCast(ListBox1.SelectedItem, DataRowView)("RoasterID"))
For Each item In ComboBox1.Items
Dim ID = CInt(DirectCast(item, DataRowView)("ID"))
If RoasterID = ID Then
ComboBox1.SelectedItem = item
Exit For
End If
Next
FillTextBoxes(ListBox1.SelectedItem)
End Sub
Do the following:
Make sure that you created a relationship (one-to-many).
Create a new query and add both tables.
Add all the fields from both tables in the query (except for the foreign key).
Make the query the data source of your Form.

How to populate master detail combobox in VB?

I have two Comboboxes with Master Detail Relationship Table Bank and Branch
My VB code behind:-
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Using con As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\New\Test.accdb")
Using cmd As New OleDbCommand("Select Bank, ID from Bank", con)
Dim da As New OleDbDataAdapter(cmd)
Dim dt As New DataTable
da.Fill(dt)
ComboBox1.DataSource = dt
ComboBox1.DisplayMember = "Bank"
ComboBox1.ValueMember = "ID"
ComboBox1.Text = "Select"
End Using
End Using
End Sub
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
Dim bankId = ComboBox1.SelectedValue.ToString
Using con As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\New\Test.accdb")
Using branch_cmd As New OleDbCommand("Select Branch from Branch where Bank_id ='" & bankId & "'", con)
Dim da As New OleDbDataAdapter(branch_cmd)
Dim dt As New DataTable
da.Fill(dt)
ComboBox2.DataSource = dt
ComboBox2.DisplayMember = "Bank"
ComboBox2.ValueMember = "ID"
End Using
End Using
End Sub
End Class
I want to populate in second combo box based on first combobox selected value, but the code got error on
ComboBox1_SelectedIndexChanged function:
And, from debugging the branch_cmd sql is:
Select Branch from Branch where Bank_id ='System.Data.DataRowView'
EDIT:
I was about to add a note and then I realised that this note is actually the solution to your actual problem. You are setting the DataSource first and then the DisplayMember and ValueMember afterwards. That is wrong and the reason for your issue. When you set the DataSource you have done the binding, so everything happens then and there. The first item in the list is selected so your SelectedIndexChanged handler is executed. You haven't set the DisplayMember or ValueMember yet, so the SelectedValue won't return the appropriate value. ALWAYS set the DataSource last, as I have done in my example below.
ORIGINAL:
Unless you have a large amount of data, you should just get all the data from both tables upfront, bind the data and then let the binding take care of the filtering automatically. You do that using BindingSources and binding the child to a DataRelation rather than a DataTable. Behold!
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim parentTable = GetParentTable()
Dim childTable = GetChildTable()
Dim data As New DataSet
'Create a foreign key relation between the tables.
data.Tables.Add(parentTable)
data.Tables.Add(childTable)
data.Relations.Add("ParentChild", parentTable.Columns("ParentId"), childTable.Columns("ParentId"))
'Bind the parent BindingSource to the parent table.
parentBindingSource.DataMember = "Parent"
parentBindingSource.DataSource = data
'Bind the child BindingSource to the relation.
childBindingSource.DataMember = "ParentChild"
childBindingSource.DataSource = parentBindingSource
parentComboBox.DisplayMember = "ParentName"
parentComboBox.ValueMember = "ParentId"
parentComboBox.DataSource = parentBindingSource
childComboBox.DisplayMember = "ChildName"
childComboBox.ValueMember = "ChildId"
childComboBox.DataSource = childBindingSource
End Sub
Private Function GetParentTable() As DataTable
Dim table As New DataTable("Parent")
table.PrimaryKey = {table.Columns.Add("ParentId", GetType(Integer))}
table.Columns.Add("ParentName", GetType(String))
table.Rows.Add(1, "Parent 1")
table.Rows.Add(2, "Parent 2")
table.Rows.Add(3, "Parent 3")
Return table
End Function
Private Function GetChildTable() As DataTable
Dim table As New DataTable("Child")
table.PrimaryKey = {table.Columns.Add("ChildId", GetType(Integer))}
table.Columns.Add("ChildName", GetType(String))
table.Columns.Add("ParentId", GetType(Integer))
table.Rows.Add(1, "Child 1.1", 1)
table.Rows.Add(2, "Child 1.2", 1)
table.Rows.Add(3, "Child 1.3", 1)
table.Rows.Add(4, "Child 2.1", 2)
table.Rows.Add(5, "Child 2.2", 2)
table.Rows.Add(6, "Child 2.3", 2)
table.Rows.Add(7, "Child 3.1", 3)
table.Rows.Add(8, "Child 3.2", 3)
table.Rows.Add(9, "Child 3.3", 3)
Return table
End Function
If you do that, selecting a parent will automatically filter the children displayed for selection.
In case it's not obvious, you would get the parent and child tables by querying a database rather than building them manually, as I have done in my example.
As it stands now I can see two errors. First, do not concatenate strings to build sql command texts. Use always a parameterized query, specifying exactly what is the datatype of the parameter that you are passing. Second error is in the DisplayMember and ValueMember for the second combo. You don't have here a Bank_Id or a Bank name but the Branch name
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
' Always check if you have a valid selection to avoid NRE.
if ComboBox1.SelectedValue Is Nothing Then
Return
End if
' If bankid is an integer then convert to an integer
Dim bankId as Integer = Convert.ToInt32(ComboBox1.SelectedValue)
Using con As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\New\Test.accdb")
Using branch_cmd As New OleDbCommand("Select Branch from Branch where Bank_id =#id", con)
cmd.Parameters.Add("#id", OleDbType.Integer).Value = bankId
Dim da As New OleDbDataAdapter(branch_cmd)
Dim dt As New DataTable
da.Fill(dt)
ComboBox2.DataSource = dt
ComboBox2.DisplayMember = "Branch"
ComboBox2.ValueMember = "Branch"
End Using
End Using
End Sub
According to your comment below you get a System.Data.DataRowView as the element contained in the SelectedValue. This should not happen with the code shown in your question, so perhaps, there is something different that creates the problem. (For example, if the datatable fields names don't match with the ValueMember/DisplayMember properties)
In any case, from a DataRowView, you should be able to get the integer in this way
Dim drv = DirectCast(ComboBox1.SelectedValue, DataRowView)
if drv IsNot Nothing then
Dim bankid = Convert.ToInt32(drv("ID"))
...
End if

Add column to SQL table and populate to datagridview

I have a windows form application with databound datagridview. I want to add column at run time (if user wants to add more column to it). So on button click I wanted to add column. I have added following code to event it adds column in server explorer view under tables column's list but does not show in table definition neither in data source window (in column list under table) nor in datagridview.
Imports System.Configuration
Imports System.Data.SqlClient
Public Class Form3
Private Sub Form3_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'Small_databaseDataSet.newtable' table. You can move, or remove it, as needed.
Me.NewtableTableAdapter.Fill(Me.Small_databaseDataSet.newtable)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
AddColumn()
End Sub
Private Sub AddColumn()
Dim connString As String = "Data Source=(localDb)\ProjectsV13;Initial Catalog=small database;Integrated Security=True"
Dim dt As New DataTable
Using conn As New SqlConnection(connString)
Dim str As String = "ALTER TABLE newtable ADD " & TextBoxX1.Text & " INT null;"
Using comm As New SqlCommand(str, conn)
conn.Open()
comm.ExecuteNonQuery()
End Using
End Using
Validate()
DataGridViewX1.Columns.Clear()
NewtableTableAdapter.Update(Small_databaseDataSet.newtable)
NewtableTableAdapter.Fill(Small_databaseDataSet.newtable)
DataGridViewX1.DataSource = NewtableBindingSource
End Sub
End Class
Change this line of code:
' Add the keyword NULL and brackets around the column name
Dim comm As New SqlCommand("ALTER TABLE testTable ADD [col1] INT NULL", conn)
If I wanted to have the new column to show up automatically, I would re-query the database, retrieving the data on that table and just set the datagridview datasource to the resultset like:
'I assume the datagridview name is DataGridView1
DataGridView1.Columns.Clear()
DataGridView1.DataSource = USTDatabaseDataSet
DataGridView1.DataMember = "testTable"
DataGridView1.DataBind()
A DataReader is used to retrieve data. Since there is no data retrieved nothing is loaded into your DataTable except maybe a return value of success or failure. The Using statements ensure that your objects are closed and disposed properly even if there is an error.
Private Sub AddColumn()
Dim connString As String = ConfigurationManager.ConnectionStrings("USTDatabaseConnectionString").ConnectionString
Dim dt As New DataTable
Using conn As New SqlConnection(connString)
Using comm As New SqlCommand("ALTER TABLE testTable ADD col1 INT;", conn)
conn.Open()
comm.ExecuteNonQuery()
End Using
Using com2 As New SqlCommand("Select * From testTable;", conn)
Using reader As SqlDataReader = com2.ExecuteReader
dt.Load(reader)
conn.Close()
End Using
End Using
End Using
DataGridView1.DataSource = dt
End Sub

Adding associated double values from database when checkedlistbox item is selected

Edited
Hi I have this program where I need to display the sum of the values when read from the database. I tried something like this:
Dim selec As String
Dim con As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\rose&mike\Desktop\DbSysDel3\salondbaccess.accdb")
Dim dt2 As New DataTable
selec = ""
con.Open()
For Each incheck In chcklstbx1.CheckedIndices
Dim valName As String
valName = chcklstbx1.Items.Item(incheck).ToString
Dim sqlstr2 As String = "SELECT Service_Fee FROM Service_Types WHERE [Service_Name] = '" & valName & "'"
Dim cmd As New OleDbCommand(sqlstr2, con)
Dim sum As Double = 0
Dim rdr As OleDbDataReader = cmd.ExecuteReader
If rdr.HasRows Then
While rdr.Read
selec += "P" + rdr("Service_Fee").ToString & ControlChars.NewLine
sum = sum + rdr("Service_Fee")
End While
End If
lblFees.Text = selec
lblTotal.Text = sum.ToString
rdr.Close()
Next
con.Close()
But all it does is display the values I want to add one by one when checked.
Here's an example of how this whole thing should be handled:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Using connection As New OleDbConnection("connection string here"),
adapter As New OleDbDataAdapter("SELECT Name, Amount FROM MyTable", connection)
Dim table As New DataTable
adapter.Fill(table)
'Bind the DataTable to the CheckedListBox.
'Normally the DataSource should be set last but, in my experience, that can cause problems with a CheckedListBox.
With CheckedListBox1
.DataSource = table
.DisplayMember = "Name"
.ValueMember = "Amount"
End With
End Using
End Sub
Private Sub CheckedListBox1_ItemCheck(sender As Object, e As ItemCheckEventArgs) Handles CheckedListBox1.ItemCheck
'Get all the currently checked items.
Dim checkedItems = CheckedListBox1.CheckedItems.Cast(Of DataRowView)().ToList()
'Get the item that is being checked or unchecked.
Dim currentItem = DirectCast(CheckedListBox1.Items(e.Index), DataRowView)
If e.NewValue = CheckState.Checked Then
'The current item is being checked so add it to the list.
checkedItems.Add(currentItem)
Else
'The current item is being unchecked so remove it from the list.
checkedItems.Remove(currentItem)
End If
'Sum the Amounts from each checked item.
Dim sum = checkedItems.Sum(Function(drv) CDec(drv("Amount")))
'Use sum here.
'...
End Sub
You get all the data up front, including all the text to display and all the associated numeric values. That data can be bound to the CheckedListBox as a DataTable, keeping it all packaged together.
Each time the user checks or unchecks an item in the list, you perform the calculation based on the data you already have. No need to go back to the database.
The important thing to note about the ItemCheck event is that it is raised BEFORE the item is checked or unchecked. That's why the code needs to ad the current item, or remove it from, the list of checked items.
When you bind a DataTable, each bound item is a DataRowView, i.e. an item from the table's DefaultView. You get all the checked DataRowView items, get their numeric value and sum them. Note that I've used a LINQ query to calculate the sum succinctly but you could use a loop if you wanted to, e.g.
Dim sum As Decimal = 0D
For Each drv In checkedItems
sum += CDec(drv("Amount"))
Next

how to update database using DataGridView

Basically i have a datagridview which is filled by a query upon the loading of the page to display all the incomplete orders in my database table as below:
I was wondering if it's possible to allow the user to edit them so they can mark the incomplete orders as completed, i was thinking through either just allowing the column to be editable, or maybe a set of checkboxes alongside each row which would mark them as completed.
here's my current code the page:
Public Class processorders
Dim sql As New sqlcontrol
Private Sub ammendorders_Load(sender As Object, e As EventArgs) Handles MyBase.Load
If sql.HasConnection = True Then
sql.RunQuery("SELECT customers.customer_id, first_name, second_name, phone_number, date_ordered, order_total, collection_method FROM (Orders INNER JOIN Customers on orders.customer_id = customers.customer_id) WHERE order_status='In Progress'")
If sql.sqldataset.Tables.Count > 0 Then
dgvData.DataSource = sql.sqldataset.Tables(0)
End If
End If
End Sub
'above queries database to find all incomplete orders
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
Me.Close()
End Sub
If you wanted to edit the order_status field, you could set the the column as a DataGridViewComboBox which would contain all possible status values. Then create an event handler to update the database when the combo box value is changed.
Edit: Code
Private Sub MyDataGridView_RowValidated(sender As Object, e As DataGridViewCellEventArgs) Handles MyDataGridView.RowValidated
'update the data source here, could vary depending on the method used.
if sql.HasConnection
Dim sqlCmd as SqlCommand = new SqlCommand
sqlCmd.connection = "<Your connection string>"
sqlCmd.commandText =
String.format(
"UPDATE Orders SET order_status='{0}' WHERE customer_id='{2}';",
MyDataGridView.Rows(e.RowIndex).Cells(<order_status column index>).Value,
MyDataGridView.Rows(e.RowIndex).Cells(<customer_id column index>).Value
)
sqlCmd.ExecuteNonQuery
end if
End Sub
Edit 1: Found another possible answer: DataGridView Cell Editing and Updating DB (C#)
Edit 2: Changed sql.RunQuery to a SqlCommand object.
This is how I do it. This is hooked to a dropdown list but it can be hooked to any control in the grid:
' This enables you to capture the Update event on a gridview
Dim clickedRow As GridViewRow = TryCast(DirectCast(sender, DropDownList).NamingContainer, GridViewRow)
Dim cust_id As Label = DirectCast(clickedRow.FindControl("lbl_grd_id"), Label)
Dim status As DropDownList = DirectCast(clickedRow.FindControl("ddl_grd_crew_id"), DropDownList)
Dim cmd As New SqlCommand()
cmd.CommandText = "UPDATE [your_orders_table] set status = #status where customer_id = #cust_id "
cmd.Parameters.Add("#cust_id", SqlDbType.Int).Value = Convert.ToInt32(cust_id.Text)
cmd.Parameters.Add("#status", SqlDbType.VarChar).Value = status.Text
cmd.CommandType = CommandType.Text
cmd.Connection = Me.sqlConnection1
Me.sqlConnection1.Open()
'execute insert statement
cmd.ExecuteNonQuery()
Me.sqlConnection1.Close()
're-populate grid with a method call. if you don't the edits will not be reflected when the grid reloads
fill_order_status_grd()
fill_order_status_grd.databind()