vb net-database with two tables ,retrieving records - database

my question is the following:
i have 2 tables created in access and created a form in vb net.
The first table consists of: Id(primary key),first name,lastname.
thes second table contains the visits and it consists of:visitID,DateOfVisit.
My question is how to join these two tables so that each ID fron the first table when selected to display the correspodind row from the second table..
For example one ID can have surname and lastname and 1 or more dates that are stored in the second table..
When i search for name it fills only the firstname and the lastname but not the date.This is where i have stuck.I want when i search with the name to also fill the correspoding textbox or display in a grid the dates that the selected record has.
Thanks.

Imports System.Data.OleDb
Public Class Form1
Dim provider As String
Dim dataFile As String
Dim connString As String
Public myConnection As OleDbConnection = New OleDbConnection
Public dr As OleDbDataReader
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'DoctorDataSet.Table1' table. You can move, or remove it, as needed.
Me.Table1TableAdapter.Fill(Me.DoctorDataSet.Table1)
provider = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source ="
dataFile = "C:\Users\Desktop\Desktop\doctor.accdb" ' Change it to your Access Database location
connString = provider & dataFile
myConnection.ConnectionString = connString
End Sub
Private Sub FindButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FindButton.Click
myConnection.Open()
FirstnameTextBox.Clear()
LastnameTextBox.Clear()
VisitsTextBox.Clear()
Dim str As String
str = "SELECT * FROM table1 WHERE (Firstname = '" & CodeText.Text & "')"
Dim cmd As OleDbCommand = New OleDbCommand(str, myConnection)
dr = cmd.ExecuteReader
While dr.Read()
FirstnameTextBox.Text = dr("Firstname").ToString
LastnameTextBox.Text = dr("Lastname").ToString
VisitsTextBox.Text = dr("Visits").ToString
End While
myConnection.Close()
End Sub
Private Sub Table1BindingNavigatorSaveItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Table1BindingNavigatorSaveItem.Click
Me.Validate()
Me.Table1BindingSource.EndEdit()
Me.TableAdapterManager.UpdateAll(Me.DoctorDataSet)
End Sub
Private Sub BindingNavigatorMovePreviousItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BindingNavigatorMovePreviousItem.Click
End Sub
End Class
I attach the full code as well as the database and a screenshot from the prgoramm.everything works well when i search,but as you can see i have also one more table(table2) which contains the number of appointments for each id from table1.Thats where i have stuck,i cant get this to work ..for example id from table1 apart from the info for name and surnames to also display and the number of visits.
I hope i am more clear now..:)
ps: i am new in vbnet and only started a few days ago programming in that language.

Ok just forget what i wrote i will try to put it in another way...
These are my 2 tables:
Table1 for customers,first column is for the id of each one which is unique,then the firstname and second name follow.
ID Firstname SecondName
1 John Jones
2 James Jameson
3 Nick Patrick
4 Nicky Summers
Table2 is for storing the date of visit.Each ID from table1 can have 0 or more visits.In that case only the third(Nick Patrick) in null.
ID Visit_Date
1 1/1/2010
2 5/1/2012
3 -
4 7/1/2014
I have created the database in access and load it on my project in visual studio.When I drag and drop the boxes from my datasource from the right column into the form I have one textbox for id,one for firstname,one for secondname and one for visitdate.
The navigation bar is placed on the top.when I press the next button all the fields are filled apart from the visit_date textbox which displays the first record always.

This should be the answer to your problem.
You can't join the 2 tables unless they both have a common field. So your 2nd table should have an ID field too and should not be a primary key. Then you can use this SQL statement.
"SELECT table1.ID, table1.firstname, table1.lastname, table2.visitID, table2.dateofvisit FROM table1 INNER JOIN table2 ON table1.ID=table2.ID WHERE table1.ID='" & ID & "'"
where ID is the variable name which holds the ID of a person. You shouldn't be using the FirstName field for the WHERE clause since it is possible that people have the same first names. Use the unique field among all the fields...which in this case is the ID field.

Related

how to display a selected item on a list box (from an access database) to a text box?

Hi I'm trying to display a selected product on a listbox similar in this video:
https://www.youtube.com/watch?v=QbbZzaMZGhY
In the video, when he click an item from the listbox, its values appear(price and name) on the textbox. I reviewed the source code but he was not using a database. In my case, I need to use an access database to list all of my product and their id and price. Here's what I got so far from asking here:
Private Sub listboxitems_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles listboxitems.SelectedIndexChanged
Using lbconn As New OleDb.OleDbConnection("PROVIDER=Microsoft.ACE.Oledb.12.0; Data Source = C:\Users\USER PC\Desktop\orderDB1.accdb")
Using lbcmd As New OleDb.OleDbCommand("SELECT productid, product, price FROM productlog WHERE productid = ? AND product = ? AND price = ?", lbconn)
'Set your values here. The parameters must be added in the same order that they
'appear in the sql SELECT command
Dim prodidparam As New OleDbParameter("#productid", Me.txtproductid.Text)
Dim prodparam As New OleDbParameter("#product", Me.txtproduct.Text)
Dim priceparam As New OleDbParameter("#price", Me.txtprice.Text)
lbcmd.Parameters.Add(prodidparam)
lbcmd.Parameters.Add(prodparam)
lbcmd.Parameters.Add(priceparam)
'Open the connection
lbconn.Open()
txtproduct.Text = listboxitems.SelectedItem
Using lbreader As OleDbDataReader = lbcmd.ExecuteReader()
While lbreader.Read
txtproductid.Text = lbreader.GetInt32("productid").ToString()
txtproduct.Text = lbreader.GetString("product")
txtprice.Text = lbreader.GetString("price").ToString()
End While
End Using
End Using
End Using
End Sub
In the line:
txtproduct.Text = listboxitems.SelectedItem
I managed to show its name in the textbox, but its not coming from my database. I can't just type their price and name in the project but I need my data source to come from the database. So far nothing is showing up in the app. What am i missing? Thanks.
EDIT: The form load code where the listbox is filled with the database.
Private Sub shop_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Create a connection to the database
provider = "PROVIDER=Microsoft.ACE.Oledb.12.0; Data Source="
datafile = "C:\Users\USER PC\Desktop\orderDB1.accdb"
connString = provider & datafile
myConnection.ConnectionString = connString
'Open the connection with error handling
Try
If Not myConnection.State = ConnectionState.Open Then
End If
myConnection.Open()
Catch OleDbExceptionErr As OleDbException
MessageBox.Show(OleDbExceptionErr.Message)
Catch InvalidOperationErr As InvalidOperationException
MessageBox.Show(InvalidOperationErr.Message)
End Try
'Command Object. Select from productlog. 'productlog name of table'
Dim objcmd As New OleDbCommand("SELECT * FROM productlog", myConnection)
'data adapter and data table.
Dim da As New OleDbDataAdapter(objcmd)
Dim dt As New DataTable("productlog")
da.Fill(dt)
'Create connection and release resources
myConnection.Close()
myConnection.Dispose()
myConnection = Nothing
objcmd.Dispose()
objcmd = Nothing
da.Dispose()
da = Nothing
'fill from access to the listbox
For Each row As DataRow In dt.Rows
listboxitems.Items.Add(row.Item("product"))
Next
'Release resources
dt.Dispose()
dt = Nothing
End Sub
EDIT: CODE UPDATED
Private Sub listboxitems_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles listboxitems.SelectedIndexChanged
Using lbconn As New OleDb.OleDbConnection("PROVIDER=Microsoft.ACE.Oledb.12.0; Data Source = C:\Users\USER PC\Desktop\orderDB1.accdb")
Using lbcmd As New OleDb.OleDbCommand("SELECT productid, product, price FROM productlog WHERE product = ?", lbconn)
'Set your values here. The parameters must be added in the same order that they
'appear in the sql SELECT command
Dim prodparam As New OleDbParameter("#product", listboxitems.SelectedItem)
Dim prodidparam As New OleDbParameter("#productid", listboxitems.SelectedItem)
Dim prodpriceparam As New OleDbParameter("#price", listboxitems.SelectedItem)
lbcmd.Parameters.Add(prodparam)
lbcmd.Parameters.Add(prodidparam)
lbcmd.Parameters.Add(prodpriceparam)
'Open the connection
lbconn.Open()
txtproduct.Text = listboxitems.SelectedItem
Using lbreader As OleDbDataReader = lbcmd.ExecuteReader()
While lbreader.Read
txtproductid.Text = listboxitems.SelectedItem.ToString()' iknow im missing alot in this line of code i just dont know what that is'
txtproduct.Text = listboxitems.SelectedItem.ToString()
txtprice.Text = listboxitems.SelectedItem.ToString()
End While
End Using
End Using
End Using
End Sub
I changed the get statements cause im having an error that says cannot convert type integer to string. im sorry if im making this really hard stack overflow is like my first line of defense and my last resort at the same time.
Your query is wrong. You want to get back the productid, product and price from the productlog table WHERE the record searched is equal to the productid, product and price that you supply as parameters.
Did you see the problem?
If you already know these values why ask the database? I suppose that your task is to find the product and price given the product stored in the current list item. If so, there is no need to use the textboxes and your query should be
SELECT productid, product, price FROM productlog WHERE product = ?
And the parameter is the data extracted by the listbox item
Dim prodidparam As New OleDbParameter("#product", listboxitems.SelectedItem)
Now your code could reach the while loop and set the textboxes with the missing informations. Of course this works because you have distinct product names in your table (meaning, there are no two records with the same product name)
EDIT
Looking at your comments below it seems that you are really confused how to use the GetPos, GetString, GetInt32 and eventually GetDecimal.
Once you have called lbreader.Read() you have a record at your disposition to transfer into your textboxes. But there is little point to take in consideration. You should call the various GetXXXX appropriate for the datatype of the underlying column. This problem is often overlooked by VB.NET programmers used to the automatic type conversion applied by the VB.NET compiler. These conversions don't exist in the lower levels of NET and it is better to avoid these conversions at all to not fall in subtle problems.
However, to call a OleDbDatareader.GetXXXX you need the ordinal position of the field in the returned record. So you need to call first OleDbDataReader.GetPos and then use the value returned by GetPos to extract the info from the GetXXXXX call.
Using lbreader As OleDbDataReader = lbcmd.ExecuteReader()
While lbreader.Read
Dim pos = lbreader.GetPos("product")
txtProduct.Text = lbreader.GetString(pos)
pos = lbreader.GetPos("productid")
txtProductID.Text = lbreader.GetInt32(pos).ToString()
pos = lbreader.GetPos("Price")
txtPrice.Text = lbreader.GetDecimal(pos).ToString()
End While
End Using
The last line uses GetDecimal assuming the column Price to be a numeric decimal in your database (as it should being it a currency value), if not, then use the appropriate GetXXXXX. Note also that the two last GetXXXX returns an Int32 and a Decimal. To assign these values to a property of type string (like Text) you should use an explicit conversion to a string (ToString())

VB.net autocomplete textbox textchanged for 3 characters min

For a Windows desktop VB.NET application, I am trying to invoke auto suggest only when user type 3 letters or more. The database contains thousands of rows and I do not want to load all of them on form load. I want to only get from database when needed and for items matching first few letters.
So far I have
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
If Len(TextBox1.Text) >= 3 Then
'invoke autosuggest
End If
End Sub
Then not sure how to invoke autosuggest so that user would not have to type the full text, my query would be something like:
Select Fullname, email from Contact where fullname like & textbox1.text order by full name
Any direction or code suggestion would be greatly appreciated.
You can change your query as :
Dim cmd As SqlCommand
Dim con As SqlConnection ='your connexion string here
Dim csql As String = "Select Fullname, email from Contact where fullname like #SEARCH order by full name"
cmd = New SqlCommand(csql, con)
cmd.Parameters.AddWithValue("#SEARCH", "'" + TextBox1.Test + "%'")
cmd.ExecuteNonQuery()
an dalso use
If TextBox1.Text.Length >3 Then
'invoke autosuggest
End If
instead of
If Len(TextBox1.Text) >= 3 Then
'invoke autosuggest
End If

How to fetch record from two Ms.Access tables in Visual Studio 2010?

I am making a railway reservation system in which I want the user to see his booking history. In the reservation system there is multiple login facility . Many users can create account and book tickets . So, a user can check his bookings which were made from his account . Due to this reason , I thought that I should compare the username of the currently opened account with the account username column present in the database . If the username of the currently opened account matches with the account username in the database , then it will fetch all those records under that name but when I try to execute, it gives me an error.
Imports System.Data.OleDb
Public Class Form12
Dim connString As String = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=C:\Users\AMEN\Documents\Railway.accdb"
Dim MyConn As OleDbConnection
Dim da As OleDbDataAdapter
Dim ds As DataSet
Dim tables As DataTableCollection
Dim source1 As New BindingSource
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
MyConn = New OleDbConnection
MyConn.ConnectionString = connString
ds = New DataSet
tables = ds.Tables
da = New OleDbDataAdapter("Select [T.Tnumber], [T.P_Name], [T.Age],[T.Train_Name], [T.Seat_No], [T.Berth],[t.R_Name], [t.Starting_Point],[t.Destination], [t.Departure], [t.Arrival], [t.Fare] from Table2 ,Table1 where T.PNR_Number=t.PNR_Number and T.Account_User=My.Settings.Username", MyConn)
da.Fill(ds, "Table2")
Dim view As New DataView(tables(0))
source1.DataSource = view
DataGridView1.DataSource = view
End Sub
End Class
I think something is wrong with da.Fill(ds, "Table2") but I don't know how to correct it.
In your SELECT statement you are comparing against My.Settings.Username, and I am imagining that this string doesn't exist in your db. You want the value inside the My.Settings.Username, we can just use string concatenation to add that to the end (as long it is a string!).
da = New OleDbDataAdapter("Select [T.Tnumber], [T.P_Name], [T.Age],[T.Train_Name], [T.Seat_No], [T.Berth],[t.R_Name], [t.Starting_Point],[t.Destination], [t.Departure], [t.Arrival], [t.Fare] from Table2 ,Table1 where T.PNR_Number=t.PNR_Number and T.Account_User=" + My.Settings.Username, MyConn)

How to randomly select multiple choice questions from Access database

I have an Access Database containing about 30 questions. The database is divided in 3 tables; Questions, Possible Answers and Answer.
The questions have from 2 to 5 possible answers.
How can I randomly select 10 questions from my database and add them to my vb form?
PS: This is my first time doing this
Here is my code
Dim provider As String
Dim dataFile As String
Dim connString As String
Public myConnection As OleDbConnection = New OleDbConnection
Public dr As OleDbDataReader
Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
provider = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source ="
dataFile = "C:\Users\Phil\Desktop\Questions.accdb"
connString = provider & dataFile
myConnection.ConnectionString = connString
myConnection.Open()
Dim str As String
str = "SELECT Top 10 ID_Question From Questions ORDER BY RND(ID_Question)"
Dim cmd As OleDbCommand = New OleDbCommand(str, myConnection)
dr = cmd.ExecuteReader
While dr.Read()
TextBox1.Text = dr("ID_Question").ToString
End While
myConnection.Close()
MsgBox("fsafa")
End Sub
The Textbox does not change and the msgBox does not show
Solution that worked for me if anyone is interested
SELECT Top 10 ID_Question, Question_Name
FROM tblQuestions
ORDER BY RND(-(100000*ID_Question)*Time())
I have to assume that your questions have an AutoNumber field, your possible answers has a one-to-many join based on that AutoNumber field and your answers have a one-to-one join based on that AutoNumber field? That would be the best way to associate the tables.
If so, try something like this:
SELECT Top 10 Question_ID FROM tblQuestions ORDER BY RND(Question_ID)
This should give you the top 10 randomly selected Question_IDs (or whatever you're calling that AutoNumber field I spoke about above), and then you can left join to the Questions/Possible Answers/Answers tables based on that ID. You would simply populate a form or subform based on the SQL above in order to display the questions.

How to update deleted row in datagridview by using vb.net

I am a beginner of vb.net. Recently I encountering a very strange problem on datagridview.
Here's my code:
Public Class testing
Dim bm As BindingManagerBase
Dim dt As DataTable
Dim dr As DataRow
Private Sub testing_Load(sender As Object, e As EventArgs) Handles MyBase.Load
OleDbDataAdapter1.Fill(DataSet11)
bm = Me.BindingContext(DataSet11, "calculatetable")
End Sub
Public Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
Dim a As Integer
Dim max As Integer
a = 0
OleDbDataAdapter1.Update(DataSet11, "calculatetable")
dt = DataSet11.Tables("calculatetable")
max = dt.Rows.Count - 1
For len As Integer = 0 To max
dr = dt.Rows(len)
a = dr("Number") + a
Next
Label1.Text = a
End Sub
Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
dt = DataSet11.Tables("calculatetable")
dr = dt.NewRow()
dr(0) = TextBox1.Text
dt.Rows.Add(dr)
End Sub
Private Sub btnDelete_Click(sender As Object, e As EventArgs) Handles btnDelete.Click
dt = DataSet11.Tables("calculatetable")
dr = dt.Rows.Find(TextBox1.Text)
dr.Delete()
End Sub
End Class
Actually, I am trying to do a calculating table for my cashier system project. I have a textbox for user to enter number for adding new data in new row and delete the selected row.
In my database, I have a table named "calculatetable" and have one column named "Number" with Primary key in it.
Both add function and delete function must updated into database.
The add function seems doing well but the delete function makes me headache...
I got this error message:
"An unhandled exception of type 'System.Data.MissingPrimaryKeyException' occurred in System.Data.dll
Additional information: Table doesn't have a primary key."
Is there any problem on my coding? Or I missed any part to make this success? And sorry for my bad english :) Thank you.
As already pointed out, the issue stems from not having a primary key on that table. To alleviate this issue, you can define your primary key column easily. When you define your column, then the Rows.Find method knows exactly what row you want to remove.
You can also use the DataTable.Select function without a primary key, but if per say the number is in another row it wont remove it. For example: Say you have 3 rows with Id's 1,12,32. If you use the select function and wanted to remove 12 from the list it wont work because 2 exists in 32.
Add primary key to your table...
DataSet11.Tables("calculatetable").PrimaryKey = New DataColumn() {DataSet11.Tables("calculatetable").Columns("YOURUNIQUECOLUMN")}
You can do this on the load, this way your datatable has it's primary key upfront. Where it says "YOURUNIQUECOLUMN", this is where you would specify your column that is unique; usually an id column of some sort. When you have this done, you can remove the row...
dr = DataSet11.Tables("calculatetable").Rows.Find(TextBox1.Text)
If dr IsNot Nothing Then
DataSet11.Tables("calculatetable").Rows.Remove(dr)
End If

Resources