My app in VB.Net loads data from MS Access in a datagridview (bound with a BindingSource, but result/problem is the same if that's a DataTable).
Private Sub LecturesPrestations()
Dim myConnection = New OleDbConnection(S7ConnString)
Try
myConnection.Open()
Requete = "SELECT s.ID, u.Nom, s.DatePresta, s.TimeIn, s.TimeOut, IIF(s.TimeOut IS NULL, NULL, CDATE(s.TimeOut - s.TimeIn)) AS Duree, s.Description " &
"FROM SAV_Prestas AS s " &
"INNER JOIN Users AS u ON u.ID = s.UserID " &
"WHERE s.NumRMA = " & monRetour.ID & ";"
Call GetBindingSource(Requete, bsPrestas, RequeteOK)
If Not RequeteOK Then
MsgBox("Problème de lecture des données",, "Chargement des prestations")
Else
With Me.dgvPresta
.DataSource = bsPrestas
...
We can then insert, delete or modifiy a row in this dgv by explicit Access instructions (INSERT, DELETE, UPDATE...). The dgv is then refreshed (reload), to include these modifications.
Private Sub tsmiSuppression_Click(sender As Object, e As EventArgs) Handles tsmiSuppression.Click
If dgvPresta.CurrentCell IsNot Nothing Then
Requete = "DELETE * FROM SAV_Prestas WHERE ID = " & CInt(dgvPresta.Item("ID", dgvPresta.CurrentCell.RowIndex).Value.ToString)
RequeteSQL(Requete, RequeteOK)
If Not RequeteOK Then
MsgBox("La prestation n'a pas pu être supprimée.")
Else
Call LecturesPrestations()
End If
Else
MsgBox("Sélectionnez une prestation.", vbOKOnly, vbInformation)
End If
End Sub
Public Sub RequeteSQL(ByVal Request As String, ByRef Resultat As Boolean, Optional ByRef MsgErreur As String = Nothing)
Dim myConnection = New OleDb.OleDbConnection(S7ConnString)
Try
myConnection.Open()
Dim myCommand = New OleDbCommand(Request, myConnection)
myCommand.ExecuteNonQuery()
Resultat = True
Catch ex As Exception
Resultat = False
MsgErreur = ex.Message
Finally
myConnection.Close()
End Try
End Sub
In this way, the dgv does not display the modified data (example: deleted data still appears). It is only after a new "refresh" a few seconds later that the modifications appear.
Have you any idea what's wrong and how to solve this?
Thank you.
Have you tried to refresh your datagridview after SQL Query?
Call dgvPresta.refresh() after "Call LecturesPrestations()"
Connection performance to your DB and size might be the problem.
Related
Imports MySql.Data.MySqlClient
Public Class Form1
Dim cmd As New MySqlCommand
Dim da As New MySqlDataAdapter
Dim con As MySqlConnection = JOKENCONN()
Public Function JOKENCONN() As MySqlConnection
Return New MySqlConnection("server=localhost; user id=root; password=; database =studentdb")
End Function
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
GroupBox1.Enabled = False
End Sub
Private Sub LBLLOGIN_CLICK(sender As Object, e As EventArgs) Handles lbllogin.Click
lbllogin.Text = "Login"
lbllogin.Text = "Login"
lblname.Text = "Hi, Guest"
If lbllogin.Text = "Login" Then
GroupBox1.Enabled = True
End If
End Sub
Private Sub BTNOK_CLICK(sender As Object, e As EventArgs) Handles btnok.Click
Dim Sql As String
Dim publictable As New DataTable
Try
If txtusername.Text = "" And txtpass.Text = "" Then
MsgBox("Password or username is incorrect!")
Else
Sql = "select ' from tbluseraccount where username='" & txtusername.Text & "' and userpassword='" & txtpass.Text & "'"
With cmd
.Connection = con
End With
da.SelectCommand = cmd
da.Fill(publictable)
If publictable.Rows.Count > 0 Then
Dim user_type As String
user_type = publictable.Rows(0).Item(4)
Name = publictable.Rows(0).Item(1)
If user_type = "Admin" Then
MsgBox("Welcome " & Name & "you login as Administrator")
lbllogin.Text = "logout"
lblname.Text = "Hi, " & Name
GroupBox1.Enabled = False
txtusername.Text = ""
txtpass.Text = ""
ElseIf user_type = "cetakoradi2" Then
MsgBox("Welcome " & Name & "you login as cetakoradi2")
lbllogin.Text = "logout"
lblname.Text = "Hi, " & Name
GroupBox1.Enabled = False
txtusername.Text = ""
txtpass.Text = ""
Else
End If
Else
MsgBox("contact administrator to register")
txtusername.Text = ""
txtpass.Text = ""
End If
da.Dispose()
End If
Catch ex As Exception
MsgBox(ex.Message)
con.Close()
End Try
End Sub
End Class
this the error i received
ExecuteReader CommandText property has not been properly initialized
i really need help on that. this is the error that i receives. thank you
Assuming that the name of the field represented in publictable.Rows(0).Item(4) is named user_type, then you could use the following:
'Declare the object that will be returned from the command
Dim user_type As String
'Declare the connection object
Dim con As OleDbConnection
'Wrap code in Try/Catch
Try
'Set the connection object to a new instance
con = JOKENCONN()
'Create a new instance of the command object
Using cmd As OleDbCommand = New OleDbCommand("SELECT user_type FROM tbluseraccount WHERE username=#0 AND userpassword=#1;", con)
'Paramterize the query
cmd.Parameters.AddWithValue("#0", txtusername.Text)
cmd.Parameters.AddWithValue("#1", txtpass.Text)
'Open the connection
con.Open()
'Use ExecuteScalar to return a single value
user_type = cmd.ExecuteScalar()
'Close the connection
con.Close()
End Using
Catch ex As Exception
'Display the error
Console.WriteLine(ex.Message)
Finally
'Check if the connection object was initialized
If con IsNot Nothing Then
If con.State = ConnectionState.Open Then
'Close the connection if it was left open(exception thrown)
con.Close()
End If
'Dispose of the connection object
con.Dispose()
End If
End Try
If (String.IsNullOrWhitespace(user_type)) Then
'Failed login
ElseIf (user_type = "Admin") Then
'Admin login
ElseIf (user_type = "cetakoradi2") Then
'cetakoradi2 login
Else
'Not a failed login, but also not an admin or cetakoradi2 either
End If
What this code does is setup a parameterized query to get just the user_type where the username and password match the parameterized values. Since there should only ever be one record that matches those conditions (presumably) then we're able to use ExecuteScalar to return just that single field value.
Just to reinforce the point, MySqlCommand.ExecuteScalar, just like the Microsoft counterparts, "executes the query, and returns the first column of the first row in the result set returned by the query. Extra columns or rows are ignored" and returns " The first column of the first row in the result set, or a null reference if the result set is empty ".
The proposed code by #David checks for this condition using IsNullOrWhitespace.
ExecuteScalar is effective but retrieves only one value at a time.
The other option pursued by the OP is to return a datarow, which is a valid approach if he wants to return several fields at the same time. In his example he retrieves two fields for variables user_type and Name respectively.
Be careful, VB.net like any other programming language has reserved keywords. If you do not take a habit of using good naming conventions you might one day stumble upon on one of those keywords, possibly hit obscure bugs. Name is not a good name for a variable and has the potential for confusion since every object has a name property.
To address the specific issue at hand, the error message ExecuteReader CommandText property has not been properly initialized is self-explanatory. What should have been done is simply:
With cmd
.Connection = con
.CommandText = Sql
End With
You defined a command, but did not tell it what to do. In your code variable Sql is defined but unused. With this missing bit there is a chance the code will work as expected.
Small details:
Not critical, but his condition does not work if you enter whitespace for example:
If txtusername.Text = "" And txtpass.Text = "" Then
An improvement is to simply trim the values from the textboxes:
If txtusername.Text.Trim = "" And txtpass.Text.Trim = "" Then
But I think what you want is not an And but Or. I don't think you want to allow logins without passwords.
Instead of doing multiple If/ElseIf you could have a Select Case
Private Sub BtnReturn_Click(sender As Object, e As EventArgs) Handles btnReturn.Click
If BorrowAccession.Text = "" Or txtBorrowerstype.Text = "" Then
MsgBox("All fields are required.", MsgBoxStyle.Exclamation)
ElseIf txtremarks.Text = "Over Due" Then
sql = "Select * From `maintenance` fine ='" & txtfine.Text & "' "
reloadtxt(sql)
End sub
how will i display the fine in txtfine.text from my maintenance database after it satisfy the condition from txtremarks. i tried some youtube tutorials but only displaying it from data grid .. want i basically want is directly display it from database to textbox. btw im newbie in vb programming thank you in advance
for my reloadtxt this is the code.
Public Sub reloadtxt(ByVal sql As String)
Try
con.Open()
With cmd
.Connection = con
.CommandText = sql
End With
dt = New DataTable
da = New MySqlDataAdapter(sql, con)
da.Fill(dt)
Catch ex As Exception
' MsgBox(ex.Message & "reloadtxt")
Finally
con.Close()
da.Dispose()
End Try
End Sub
To populate an object with data from a database you need to access the objects text property.
Textbox1.Text = "Some Text, static or dynamic"
Since you are pulling the data from a datatable you would access the column named "fine" and put that value in the textbox.text property.
Textbox1.Text = dt.row(0).item("fine").tostring
Changed Or to OrElse because it short circuits the If and doesn't have to check the second condition if the first condition is True.
In the reloadtxt method you filled a DataTable and did nothing with it. I changed it to a Function that returns the DataTable. The connection and command are now included in a Using...End Using block so they are closed and disposed even if there is an error.
Never concatenate strings to build an sql statement. Always used parameters.
Private Sub BtnReturn_Click(sender As Object, e As EventArgs) Handles btnReturn.Click
If BorrowAccession.Text = "" OrElse txtBorrowerstype.Text = "" Then
MsgBox("All fields are required.", MsgBoxStyle.Exclamation)
ElseIf txtremarks.Text = "Over Due" Then
Dim dt = reloadtxt()
DataGridView1.DataSource = dt
End If
End Sub
Public Function reloadtxt() As DataTable
Dim dt As New DataTable
Using con As New MySqlConnection("Your connection string"),
cmd As New MySqlCommand("Select * From maintenance Where fine = #Fine", con)
cmd.Parameters.Add(#Fine, MySqlDbType.VarChar, 50).Value = txtfine.Text
Try
con.Open()
dt.Load(cmd.ExecuteReader)
Catch ex As Exception
MsgBox(ex.Message & "reloadtxt")
End Try
End Using
Return dt
End Function
i can access to local Access Database and i can add some data using Query, but it JUST shows its data when the program is alive. when I re-execute this program, i cannot see any previously added data and so do original Database file(SourceDB.mdb).
How can I save my data? Here is my code.
Imports System.Data.OleDb
Public Class UserForm
Private myConn As String = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=.\SourceDB.mdb"
Private mDbConn As OleDbConnection
Private Sub Button_Search_Click(sender As Object, e As EventArgs) Handles Button_Search.Click
Dim myAdapter As New OleDbDataAdapter("SELECT * FROM user WHERE u_name = '" + tBoxName.Text + "'", myConn)
Dim myDataTable As New DataTable
If tBoxName.Text = "" Then
MsgBox("Input name")
Else
myAdapter.Fill(myDataTable)
If myDataTable.Rows.Count > 0 Then
tBoxPhone.Text = myDataTable.Rows(0).Item("u_phone")
tBoxAddr.Text = myDataTable.Rows(0).Item("u_addr")
tBoxBName.Text = myDataTable.Rows(0).Item("u_bname")
tBoxBAccount.Text = myDataTable.Rows(0).Item("u_baccount")
tBoxEtc.Text = myDataTable.Rows(0).Item("u_comment")
Else
MsgBox("No Name in Table")
End If
End If
End Sub
Private Sub Button_OK_Click(sender As Object, e As EventArgs) Handles Button_OK.Click
Try
If lblAOE.Text = "Add" Then
Dim myAdapter As New OleDbDataAdapter("INSERT INTO user (u_name, u_phone, u_addr, u_bname, u_baccount, u_comment) VALUES ('" + _
tBoxName.Text + "', '" + tBoxPhone.Text + "', '" + tBoxAddr.Text + "', '" + tBoxBName.Text + _
"', '" + tBoxBAccount.Text + "', '" + tBoxEtc.Text + "')", myConn)
Dim myDataTable As New DataTable
myAdapter.Fill(myDataTable)
Button_Add.Visible = True
Button_Modify.Visible = True
Button_OK.Visible = False
ClearTextBoxes()
Button_Clear.Text = "비우기"
End If Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Sub Button_Delete_Click(sender As Object, e As EventArgs) Handles Button_Delete.Click
If MessageBox.Show("Sure Wanna delete data?", "Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) = DialogResult.No Then
MsgBox("Cancelled")
Exit Sub
Else
Dim myAdapter As New OleDbDataAdapter("DELETE FROM user WHERE u_name = '" + tBoxName.Text + "'", myConn)
Dim myDataTable As New DataTable
myAdapter.Fill(myDataTable)
MsgBox("DELETED")
ClearTextBoxes()
End If
End Sub
Private Sub ClientForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.UserTableAdapter.Fill(Me.SourceDBDataSet.user)
Me.Text = "User Form"
End Sub
End Class
You are using a OleDbDataAdapter trying to execute an INSERT operation (or a DELETE one), but this is not how the OleDbDataAdapter works.
An OleDbDataAdapter uses the SELECT command to retrieve the records and, if defined, its InsertCommand property to update records of a dataset through the call to the OleDbDataAdapter.Update method. You are not in this situation and you have your values directly in the textboxes. You could simply use an OleDbCommand with the appropriate sql statement (and this is the same for your DELETE method)
Try to change your code to
Dim cmdText = "INSERT INTO [user] (u_name, u_phone, u_addr, u_bname, " & _
"u_baccount, u_comment) VALUES (?, ?, ?, ?,?,?)"
Dim cmd = New OleDbCommand(cmdText, myConn)
cmd.Parameters.AddWithValue("#p1",tBoxName.Text)
cmd.Parameters.AddWithValue("#p2",tBoxPhone.Text )
cmd.Parameters.AddWithValue("#p3",tBoxAddr.Text)
cmd.Parameters.AddWithValue("#p4",tBoxBName.Text)
cmd.Parameters.AddWithValue("#p5",tBoxBAccount.Text)
cmd.Parameters.AddWithValue("#p6",tBoxEtc.Text )
cms.ExecuteNonQuery()
I have changed your string concatenation to a more correct parameterized query to avoid Sql Injection and parsing problems in case one of your textbox values contains a single quote.
you use OleDbCommand class. you make class object and use ExecuteNonQuery for insert data
like
Dim o As OleDbCommand
o.Connection = con
o.CommandType = CommandType.Text
o.CommandText = "your Query"
o.ExecuteNonQuery()
and you should use try block
try
o.ExecuteNonQuery()
catch
end try
I have a created a database containing historical stock prices. On my form I have two comboboxes, ComboBox_Ticker and ComboBox_Date. When these comboboxes are filled I want to check the database and see if the respective data exists in the database. If it does I want to change the text of a label called Label_If_Present to "In Database".
My problem occurs with the change event. I want all of this to happen once I change the data in the textboxes. I have tried both the .TextChanged and .LostFocus events. The '.TextChanged' triggers the code to early and throws and error in my SQL command statement. The `.LostFocus' event doesn't do trigger my code at all.
Here is my current code:
Public databaseName As String = "G:\Programming\Nordeen Investing 3\NI3 Database.mdb"
Public con As New OleDb.OleDbConnection("PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source =" & databaseName)
Public tblName As String = "Historical_Stock_Prices"
Private Sub Change_Labels(ByVal sender As Object, ByVal e As EventArgs) Handles ComboBox_Ticker.TextChanged, ComboBox_Date.TextChanged
con.Close()
Dim dr As OleDbDataReader
con.Open()
If (File.Exists(databaseName)) Then
Dim restrictions(3) As String
restrictions(2) = tblName
Dim dbTbl As DataTable = con.GetSchema("Tables", restrictions)
If dbTbl.Rows.Count = 0 Then
Else
Dim cmd2 As New OleDb.OleDbCommand("SELECT * FROM " & tblName & " WHERE Ticker = '" & ComboBox_Ticker.Text & "' " & " AND Date1 = '" & ComboBox_Date.Text & "'", con)
dr = cmd2.ExecuteReader
If dr.Read() = 0 Then
'If record does not exist
Label_If_Present.Text = ""
Else
Label_If_Present.Text = "In Database"
End If
con.Close()
End If
Else
End If
End Sub
I have successfully implemented this concept on other forms within my project. This one is slightly different and I can't figure out why I can't get this one to work.
Handling the TextChanged event should work, however you need to set the DropDownStyle to DropDownList so that the Text property can only be a given value.
Then check to see that both comboboxes have values selected. Something like this should work:
If ComboBox_Ticker.Text <> "" AndAlso DateTime.TryParse(ComboBox_Date.Text, Nothing) Then
Well I'm creating a search bar to find some patients in my school project, but when I search it works, but when I made another search it sent me the message as if the number dont exist even when it exist, this is the code of the button hope you can help me.
Private Sub cmdIDBuscar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdBuscarID.Click
Dim sqlCon As New SqlClient.SqlConnection
Dim sqlComm As New SqlClient.SqlCommand
'Ruta de la conección.
sqlCon.ConnectionString = ("Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Sistema para Hospitales.mdf;Integrated Security=True;User Instance=True")
'Instrucción con la que se trabajara.
sqlComm.CommandText = "SELECT * FROM [Pacientes] WHERE IDPaciente= '" & txtID.Text & "';"
'Abrir la coneccion SQL
sqlCon.Open()
Do Until txtID.Text = txtCompararID.Text
Me.PacientesBindingSource.MoveNext()
Exit Do
If EOF(True) Then KryptonMessageBox.Show("Error, no se encontro paciente.", "Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error)
Loop
If txtID.Text = txtCompararID.Text Then
txtNombres.Text = txtCompararN1.Text & " " & txtCompararN2.Text & " " & txtCompararN3.Text
txtApellidos.Text = txtCompararAp1.Text & " " & txtCompararAp2.Text
txtEdad.Text = txtCompararEdad.Text
Select Case txtCompararSexo.Text
Case Is = "F"
txtSexo.Text = "Femenino"
Case Is = "M"
txtSexo.Text = "Masculino"
End Select
Select Case TipoAfiliacionTextBox.Text
Case Is = "1"
txtTAfiliacion.Text = "Cotizante"
Case Is = "2"
txtTAfiliacion.Text = "Beneficiario"
Case Is = "3"
txtTAfiliacion.Text = "Pensionado"
End Select
txtAltura.Text = AlturaTextBox1.Text
txtPeso.Text = PesoTextBox1.Text
txtPresion.Text = PresionTextBox.Text
txtTemperatura.Text = TemperaturaTextBox.Text
Else
KryptonMessageBox.Show("No se encontro el paciente", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
End Sub
Among other problems, because you have an Exit Do statement in the middle of your comparison loop, you will probably only ever match the first record since your do loop will execute a maximum of one time.
I am guessing that txtCompararID is databaound to your PacientesBindingSource and that the intent of your loop is move through this binding source until you find the value that matches txtID.
If that is the case, your do loop should look something more like:
' Get back to the top of the list
Me.PacientesBindingSource.MoveFirst()
Do Until txtID.Text = txtCompararID.Text
Me.PacientesBindingSource.MoveNext()
If EOF(True) Then
KryptonMessageBox.Show("Error, no se encontro paciente.", "Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error)
Exit Do
End If
Loop
In addition, you should use Using statements for your connection and command objects so that they are properly closed and disposed of when you are done using them.
For example:
Using sqlCon As New SqlClient.SqlConnection
Using sqlComm As New SqlClient.SqlCommand
... all of your code
End Using
End Using
And finally, and most importantly, you should be using a parameterized query statement in order to prevent SQL injection attacks since you are allowing direct entry of values. This statement:
sqlComm.CommandText = "SELECT * FROM [Pacientes] WHERE IDPaciente= '" & txtID.Text & "';"
should be changed to something like:
sqlComm.CommandText = "SELECT * FROM [Pacientes] WHERE IDPaciente= ?"
sqlComm.Parameters.AddWithValue("IDPaciente", txtID.text)