Select commannd in Visual Basic not working properly - vb.net

I am new to Visual Basic for Applications. I have a login system in my current program. You will understand the system by reading below. I have an Access database whose table looks like following :-
Name : Cookies
----------------------------
ID | Nme | Val |
----------------------------
The table is cleared and all the contents of it is deleted when the form is closed. Now, when a user signs in, a row is added :-
----------------------------
(id) | "user" | username |
----------------------------
Now, the user enters his id and password in the form index.vb and the command to add the row in the access database is also there in the index.vb file. After the row is added, the index.vb file is hidden and the file userpage.vb is shown. Now, I have seen this that when the user logs in, the row is added properly in the access file (by refreshing the access file manually) and everything is deleted properly in the table when the window is closed. So, there is no problem in inserting and deletion of rows. So, obviously, the problem is with the displaying part. My code for displaying the username is as follows (the code is in the userpage.vb file) :-
Dim Username As String = ""
Dim Conn As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Software\db.accdb")
Conn.Open()
Dim Cmd As New OleDb.OleDbCommand("Select Val From Cookies Where Nme='user'", Conn)
Dim Reader = Cmd.ExecuteReader
Do While Reader.Read
Username = Reader.Item("Val")
Loop
Label1.Text = "Welcome " & Username
Conn.Close()
The output that is given is "Welcome" and Username is "" even when the row has been added. Now, I have also seen this by experimenting that when I manually add a row in the access database with the same details that is going to be added in the database problematically, the program works fine. Any help, of course, will be appreciated and thanks for reading this long post.
UPDATE 1 ( as suggested by #Dimple)
My code for insertion is as follows(This code is in the index.vb page) :-
Dim usernameinput As String = TextBox1.Text
Dim Cmmd As New OleDb.OleDbCommand()
Cmmd.Connection = Conn
Cmmd.CommandText = "INSERT INTO Cookies (Nme, Val) Values('user','" & usernameinput & "')"
Cmmd.ExecuteNonQuery()
Dim Userpage As New User_page
Me.Hide()
Userpage.Show()

You said that Access displays row after manually refreshing Access file (database). Sometimes you need to Requery() the database after insertion. I had this problem while working with Access.
Form1
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim Conn As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\db.accdb")
Conn.Open()
Dim usernameinput As String = "TextBox3.Text"
Dim Cmmd As New OleDb.OleDbCommand()
Cmmd.Connection = Conn
Cmmd.CommandText = "INSERT INTO Cookies (Nme, Val) Values('user','" & usernameinput & "')"
Cmmd.ExecuteNonQuery()
Conn.Close()
Me.Hide()
Form2.Show()
End Sub
End Class
Form2
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim Conn As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\db.accdb")
Conn.Open()
Dim usernameinput As String = "TextBox3.Text"
Dim Cmmd As New OleDb.OleDbCommand()
Cmmd.Connection = Conn
Cmmd.CommandText = "INSERT INTO Cookies (Nme, Val) Values('user','" & usernameinput & "')"
Cmmd.ExecuteNonQuery()
Conn.Close()
Me.Hide()
Form2.Show()
End Sub
End Class
I didnt even change the variables you named. Just avoided form designing by using msgbox.

My brother instead of using,
Do While Reader.Read
Username = Reader.Item("Val")
Loop
try
Do While Reader.Read = True
Username = Reader.Item(0)
Loop
Let me Know if it works for you.

Related

How to link to a relational database - visual basic

I am creating a flashcard application where each user can create flashcards which will be specific to them. I was wondering how I can link each flashcard they create to their specific account.
Imports System.Data.OleDb
Public Class CreateFlashcards
Dim pro As String
Dim connstring As String
Dim command As String
Dim myconnection As OleDbConnection = New OleDbConnection
Private Sub btnCreateFlashcard_Click(sender As Object, e As EventArgs) Handles btnCreateFlashcard.Click
pro = "provider=microsoft.ACE.OLEDB.12.0;Data Source=flashcard login.accdb"
connstring = pro
myconnection.ConnectionString = connstring
myconnection.Open()
command = " insert into Flashcards ([Front],[Back]) values ('" & txtFront.Text & "','" & txtBack.Text & "')"
Dim cmd As OleDbCommand = New OleDbCommand(command, myconnection)
cmd.Parameters.Add(New OleDbParameter("username", CType(txtFront.Text, String)))
cmd.Parameters.Add(New OleDbParameter("password", CType(txtBack.Text, String)))
MsgBox("You have successfully added the flashcard into your deck!")
Try
cmd.ExecuteNonQuery()
cmd.Dispose()
myconnection.Close()
txtFront.Clear()
txtBack.Clear()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
End Class
This works in that it adds the data into the access database but it does not link to the users account. I have also linked the tables in access
The login table
The flashcard table
As you can see the loginID key does not link
Normally, the connection string for Access contains the the path to the database file for the Data Source attribute.
You will need to add a field to your Flashcard table to hold the UserID. This will tie the 2 tables together.
Database objects like connections and commands need to be disposed as well as closed. Using...End Using blocks handle this for you even if have an error. In this code you both the connection and the command are included in the same Using block.
You can pass the connection string directly to the constructor of the connection. Likewise, pass the sql command text and the connection to the constructor of the command.
When you are using parameters, which you should in Access and Sql Service, put the name of the parameter in the sql command text. It is not necessary to convert the Text property of a TextBox to a string. It is already a String.
I had to guess at the OleDbType for the parameters. Check your database. It is important to note that the order that parameters appear in the sql command text must match the order that they are added to the parameters collection. Access does not consider the name of the parameter, only the position.
I assume you can retrieve the user's ID when they log in to create flash cards. When the user logs in to use there flash cards you would do something like Select * From Flashcards Where LoginID = #UserID;.
Private Sub btnCreateFlashcard_Click(sender As Object, e As EventArgs) Handles btnCreateFlashcard.Click
Try
InsertFlashcard()
MsgBox("You have successfully added the flashcard into your deck!")
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Sub InsertFlashcard()
Dim pro = "provider=microsoft.ACE.OLEDB.12.0;Data Source=Path to login.accdb"
Dim Command = " insert into Flashcards (LoginID, [Front],[Back]) values (#Id, #Front, #Back);"
Using myconnection As New OleDbConnection(pro),
cmd As New OleDbCommand(Command, myconnection)
cmd.Parameters.Add("#UserID", OleDbType.Integer).Value = ID
cmd.Parameters.Add("#Front", OleDbType.VarChar).Value = txtFront.Text
cmd.Parameters.Add("#Back", OleDbType.VarChar).Value = txtBack.Text
myconnection.Open()
cmd.ExecuteNonQuery()
End Using
End Sub
EDIT
As per comment by ADyson I have added code to retrieve ID. Of course in your real application you would be salting and hashing the password. Passwords should never be stored as plain text.
Private ID As Integer
Private Sub btnLogIn_Click(sender As Object, e As EventArgs) Handles btnLogIn.Click
Dim pro = "provider=microsoft.ACE.OLEDB.12.0;Data Source=Path to login.accdb"
Using cn As New OleDbConnection(pro),
cmd As New OleDbCommand("Select LoginID From login Where Username = #Username and Password = #Password;")
cmd.Parameters.Add("#Username", OleDbType.VarChar).Value = txtUserName.Text
cmd.Parameters.Add("#Password", OleDbType.VarChar).Value = txtPassword.Text
cn.Open()
Dim result = cmd.ExecuteScalar
If Not result Is Nothing Then
ID = CInt(result)
Else
MessageBox.Show("Invalid Login")
End If
End Using
End Sub

Update From DataGridView to Database

Dim sb As New MySqlConnectionStringBuilder
sb.Server = Form1.hostname.Text
sb.UserID = Form1.rootuser.Text
sb.Password = Form1.rootpassword.Text
sb.Database = Form1.hostdb.Text
sb.Port = Form1.hostport.Text
Using connection As New MySqlConnection(sb.ConnectionString)
Try
connection.Open()
Dim adapter1 As New MySqlDataAdapter(TextBox1.Text, connection)
Dim cmdb1 = New MySqlCommandBuilder(adapter1)
Dim ds As New DataSet
Dim words As String() = TextBox1.Text.Split(New Char() {" "c})
Dim tablenamewords = (words(3))
adapter1.Update(ds, tablenamewords)
Catch ex As MySqlException
MessageBox.Show(ex.Message)
Finally
connection.Dispose()
End Try
End Using
It's giving me this error:
Update unable to find TableMapping['creature_template'] or DataTable 'creature_template'.
I want to select items then use a DataGrid to update them.
Note: tablenamewords = "creature_template"
You can solve this in alot of different methods.
I prefer to update the DB with a single query every time the the user ends editing a cell.
BUT FIRST you have to bind a source to your DataGridView!
How to bind a source:
Go to your application design an click on your DataGridView
Click on the pause/start like little button as shown:
Click on the "ComboBox" like textbox labeled as "chose data source" as shown and click on it:
It will open a "form", click on the Add data source as shown:
Follow the wizard, you can do it without any furhter explanation!
Well done, you almost completed it. Just go in your code, and look for this sub:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.your_table_nameTableAdapter.Fill(Me.your_db_nameDataSet.your_table_name)
End Sub
The line inside your Form1_Load Sub will upload the data inside your DataGridView, leave it there if you want it to load with the form or cut/paste it wherever you like.
Now you can add this the code to programmatically update the DB:
Private Sub DataGridView1_CellEndEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit
Try
Dim location As Point = DataGridView1.CurrentCellAddress
Dim sqlCmd As String = "UPDATE table_name SET " & _
DataGridView1.Columns(location.X).Name.Replace("DataGridViewTextBoxColumn", "") & " = #Data " & _
"WHERE " & _
DataGridView1.Columns(0).Name.Replace("DataGridViewTextBoxColumn", "") & " = #ID"
Using myConn As New SqlConnection(My.Settings.VISURE_DA_PDFConnectionString)
myConn.Open()
Using myCmd As New SqlCommand(sqlCmd, myConn)
myCmd.Parameters.Add("#Data", SqlDbType.VarChar)
myCmd.Parameters.Add("#ID", SqlDbType.Int)
myCmd.Parameters("#Data").Value = DataGridView1.Rows(location.Y).Cells(location.X).Value
myCmd.Parameters("#ID").Value = DataGridView1.Rows(0).Cells(location.X).Value
myCmd.ExecuteNonQuery()
End Using
myConn.Close()
End Using
Catch ex As Exception
Err.Clear()
End Try
End Sub
Remarks:
location.X is the col index, location.Y is the row index
DataGridView1.Columns(0).Name This is my ID (primary key) and it is always in the first column. Change it with yours.
Don't forget to add .Replace("DataGridViewTextBoxColumn", "") whan you are getting your column name
As previously said, this code will update your DB every time the user edits one cell on your DataGridView updating only the edited cell. This is not a big issue because if you want to edit two ore more cell, every time you leave an edited cell the method DataGridView1_CellEndEdit is fired!

How to represent currently logged in user in vb.net

I am in desperate need of some help.
I'm using SQL Server and vb.net. On my personal info Windows form I'm trying to populate textboxes with user information based on the currently logged in user.
However I don't know how to represent the value of the current user. I'm trying to pass the value as a parameter. What should be put in place of: #idontknow ?
Code for form:
Private Sub PersonalInfo_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim connection As New SqlConnection("server=DESKTOP-PL1ATUA\DMV;Database=EHR;Integrated Security=True")
Dim dt As New DataTable
connection.Open()
Dim sqlcmd As New SqlCommand("SELECT * FROM PATIENT WHERE PATIENT_ID = #id", connection)
Dim sqlda As New SqlDataAdapter(sqlcmd)
Dim user_email As Object = Nothing
sqlcmd.Parameters.AddWithValue("#id", #idontknow)
Dim reader As SqlDataReader = sqlcmd.ExecuteReader()
While reader.Read()
fname.Text = reader("PATIENT_FNAME")
ComboBox1.Text = reader("patient_gender")
TextBox4.Text = reader("patient_street")
TextBox5.Text = reader("patient_city")
TextBox6.Text = reader("patient_state")
TextBox7.Text = reader("patient_zip")
TextBox8.Text = reader("patient_phone")
email.Text = reader("user_email")
End While
End Sub
Here I validate User credentials on a windows form by checking email and password, the primary key (patient_id) is generated upon insert when a new user registers (this code is on a separate form, which is not displayed below):
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim connection As New SqlConnection("server=DESKTOP-PL1ATUA\DMV;Database=EHR;Integrated Security=True")
Dim command As New SqlCommand("select * from patient where user_email = #email and user_pass = #pass", connection)
command.Parameters.Add("#email", SqlDbType.VarChar).Value = email.Text
command.Parameters.Add("#pass", SqlDbType.VarChar).Value = pass.Text
Dim adapter As New SqlDataAdapter(command)
Dim table As New DataTable()
adapter.Fill(table)
If table.Rows.Count() <= 0 Then
MessageBox.Show(" Username or Password are Invalid")
Else
MessageBox.Show("Login Successful")
command.CommandType = CommandType.StoredProcedure
dashboard.Show()
End If
End Sub
Your login code queries for a record from the patient table that has the appropriate username and password. Right now it looks like all you're doing is checking for the existence of such a record. What you want to do is take that record's patient_id and store it somewhere that you can refer back to from elsewhere in your code. This could be something as simple as a shared property somewhere. This question discusses a few options that might suit. For instance, a module:
Module CurrentUser
Public Property PatientId As Integer
End Module
Or a class that can't be instantiated:
NotInheritable Class CurrentUser
Private Sub New()
End Sub
Public Shared Property PatientId As Integer
End Class
Review the answers to the question linked above for a discussion of the differences between the two approaches. In either case, you'd assign the value of CurrentUser.PatientId in your login code and then access its value where you've written #idontknow.
One last thing: it looks like your login code is taking the contents of a password box somewhere and comparing it directly to the contents of the password field in your database, which strongly implies that you're storing passwords as plain text. This is not secure. Review this question for a thorough overview of how to store passwords securely.
Well, I'm not sure if you're looking for a logged user in Windows, then it's a string (not Integer) as follows:
Dim UserNameStr As String = Environment.UserName
Same applies to the SQL Server:
SELECT CURRENT_USER;
...it's a string too.

How do I transfer data from Text Boxes in a form to an Access Table

I'm currently trying to write code for a form that has text boxes for a user to input the required data into which then with the use of button the data in the text boxes will be sent to an access table.
If you need any more information to help solve the problem I'm willing to provide it if you ask (I would upload pictures/screenshots but I need "10 reputation" apparently.
You can do this
Imports System.Data.OleDb
Public Class Form1
Dim AccessConection As OleDbConnection
Private Sub btSave_Click(sender As Object, e As EventArgs) Handles btSave.Click
Dim cmd As New OleDbCommand
Dim mySql As String
mySql = "INSERT INTO Customs (CustomName,Address) VALUES(#Name,#Address)"
Try
cmd.Parameters.AddWithValue("#Name", txName.Text)
cmd.Parameters.AddWithValue("#Address", txAddress.Text)
cmd.Connection = AccessConection
cmd.CommandType = CommandType.Text
cmd.CommandText = mySql
cmd.ExecuteNonQuery()
Catch ex As Exception
MessageBox.Show("Whatever you want to say..." & vbCrLf & ex.Message)
End Try
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim myDataBasePath As String = "C:\Users\user\Source\Workspaces\......\SOF003\Data.accdb" 'Here you put the full name of the database file (including path)
'The next line is for Access 2003 .mdb files
'Dim CadenaConection As String = String.Format("Provider=Microsoft.Jet.OLEDB.4.0; Data Source={0}", myDataBasePath)
Dim CadenaConection As String = String.Format("Provider=Microsoft.ACE.OLEDB.12.0; Data Source={0}", myDataBasePath)
AccessConection = New OleDbConnection(CadenaConection)
AccessConection.open()
End Sub
End Class
btSave is the command button.
Customs is the table's name.
CustomName and Address are two fields.
txName and txAddress are two TextBox Control.
Obviously you should be careful with the data types (here I use only strings), validation, etc, etc... But, this is a starting point. If you search, you'll find another ways, more elaborated.

how to open database connection in 1 form then close it in another form?

Public Class Login
Private Shared con As New OleDb.OleDbConnection
Dim sql As String
Dim da As OleDb.OleDbDataAdapter
Dim ds As New DataSet
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If TextBox1.Text <> "fcf#gmail.com" Or TextBox2.Text <> "fcf1234567" Then
MsgBox("Wrong username or password!! Please try again!!", 0, "!!!")
Else
con.Open()
sql = "SELECT * FROM c_info"
da = New OleDb.OleDbDataAdapter(sql, con)
da.Fill(ds, "c_information")
Me.Hide()
Home.Label6.Show()
Home.Label6.Text = ds.Tables("c_information").Rows(0).Item(0)
Home.Button8.Show()
Home.Button6.Hide()
Home.Button9.Show()
Profile.Enabled = True
Profile.TextBox1.Text = ds.Tables("c_information").Rows(0).Item(0)
Profile.TextBox2.Text = ds.Tables("c_information").Rows(0).Item(1)
Profile.TextBox3.Text = ds.Tables("c_information").Rows(0).Item(2)
Profile.TextBox4.Text = ds.Tables("c_information").Rows(0).Item(3)
Profile.TextBox5.Text = ds.Tables("c_information").Rows(0).Item(4)
Profile.ComboBox1.Text = ds.Tables("c_information").Rows(0).Item(5)
End If
End Sub
I'm doing a log-in system, try to open database connection then close it in another form, no idea how to do it...in this code i have typed con.open(), but when i run it twice, it says "current connection still open"
3 Suggestions:
(Less recomendable) Change con to Public Shared or Protected Shared (preferable to have it on a separate class/module); this way you'll be able to access it from all your forms and clases
(Most adecuate to your scenario) Add a property on your 2nd form of OleDb.OleDbConnection or a parameter on its constructor and pass it from Form1 when you create the second form.
(Most recommended) Rethink your design and logic. Having an open database connection wandering over all your program is a bad idea for many reasons. Create a database connection on every form/class you need one, open and close it as soon as you use it.