change format date and can update in textbox with blank or zero in vb.net - vb.net

I wanted to change the date format in the textbox to the format "dd-mmm-yy" but it did not work when in datagridview did not appear the date with the time and also I could not update in the textbox with blank and zero which caused the error "data type error". if I do not perform sql command for update in the "DATE" field then do not cause error. I use visual studio 2010
so the problem in the date column and if I update without a date column then it runs perfectly. Problem error : syntax error in update statement
thanks
jack
Dim Path As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
Dim cn As String = "provider=Microsoft.Jet.OLEDB.4.0; data source=" & Path & "; Extended Properties=dBase IV"
Private connectionString As String
Private con As OleDbConnection
Private cmd As OleDbCommand
Private da As OleDbDataAdapter
Private sql As String
Public x As Integer
Public Sub dbConnection()
connectionString = CStr(cn)
con = New OleDbConnection(connectionString)
con.Open()
End Sub
Private Sub DataGridView1_CellDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellDoubleClick
x = DataGridView1.Rows.IndexOf(DataGridView1.CurrentRow)
txtCODE.Text = DataGridView1.Rows(x).Cells(0).Value.ToString()
DateTimePicker1.Value = DataGridView1.Rows(x).Cells(1).Value.ToString()
NumericUpDown1.Value = DataGridView1.Rows(x).Cells(2).Value.ToString()
End Sub
Private Sub FillDataGridView()
Try
Dim query = "select CODE,DTE,QTY FROM EXAMPLE"
Using con As OleDbConnection = New OleDbConnection(CStr(cn))
Using cmd As OleDbCommand = New OleDbCommand(query, con)
Using da As New OleDbDataAdapter(cmd)
Dim dt As DataTable = New DataTable()
da.Fill(dt)
Me.DataGridView1.DataSource = dt
End Using
End Using
End Using
Catch myerror As OleDbException
MessageBox.Show("Error: " & myerror.Message)
Finally
End Try
End Sub
Private Sub btnUpdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUpdate.Click
Try
dbConnection()
x = DataGridView1.Rows.IndexOf(DataGridView1.CurrentRow)
'sql = "UPDATE EXAMPLE SET QTY=? WHERE CODE=?"
sql = "UPDATE EXAMPLE SET DTE=?,QTY=? WHERE CODE=?"
cmd = New OleDbCommand(sql, con)
cmd.Parameters.Add("DTE", OleDbType.Date)
cmd.Parameters.Add("QTY", OleDbType.Numeric)
cmd.Parameters.Add("CODE", OleDbType.VarChar)
cmd.Parameters("DTE").Value = DateTimePicker1.Value
cmd.Parameters("QTY").Value = NumericUpDown1.Value
cmd.Parameters("CODE").Value = txtCODE.Text
cmd.ExecuteNonQuery()
MessageBox.Show("Successfully Updated...", "Update")
con.Close()
FillDataGridView()
Catch myerror As OleDbException
MessageBox.Show("Error: " & myerror.Message)
Finally
End Try
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
FillDataGridView()
End Sub

Your SQL line must be written like:
sql = "UPDATE EXAMPLE SET DATE=#d,QTY=#q WHERE CODE=#c"
You set the values of these #xxx by adding more code:
cmd.Parameters.AddWithValue("#d", dtpDATE.Value)
cmd.Parameters.AddWithValue("#q", nudQTY.Value)
cmd.Parameters.AddWithValue("#c", txtCODE.Text)
Change your date time TextBox to be a datetimepicker instead. Instead of using textboxes for numeric values, use a NumericUpDown instead.
You must call AddWithValue("#xxx"... in the same order as the #xxx appear in the SQL. Access ignores the names and looks at the order Parameters appear in the SQL so it is important to call AWV on the same order. One day when you upgrade o using a different database it will support the name part of the parameter so you can add your values in any order but right now on access, order is important
You must write your SQL like I've shown. Never, ever do what you were doing before. Never use string concatenation to build a user-supplied data value into an SQL statement. It makes your program trivial to hack into. This might not matter while you're writing a tiny app to index grandma's record collection but it must never be done on any system of importance such as one used by many people

Related

VB.net/MS Access Monthly Donations System Assistance

I'm doing a project for my Database Management subject. I cannot figure out how to add an amount to a previously added amount. For now, I'm only able to update the amount. Here's the code. I'm sorry if I cannot explain it well.
I have 2 forms. My first form allows me to enter a last name and retrieve the data to my list view.
My second form lets me retrieve the data I entered in my first form and it will show up on a separate list view with a "Last Name | Amount" tab.
I have two textboxes. One for last name set to readonly to disable editing, and another for the amount I want to enter.
After entering an amount, let's say 20, it will update on the listview and my database as 20.
The problem is that when I enter a new amount for the same last name, let's say 30, the 30 will replace the 20 but it should be 50 because 20+30 = 50.
I understand the logic and I have tried adding another textbox for addition but I simply do not know the codes for it.
Imports System.Data.OleDb
Public Class Form2
Dim conString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Israel De Leon\Documents\testing.accdb;"
Dim con As OleDbConnection = New OleDbConnection(conString) 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Database2.accdb
Dim cmd As OleDbCommand
Dim adapter As OleDbDataAdapter
Dim dt As DataTable = New DataTable()
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'SET LISTVIEW PROPERTIES
ListView1.View = View.Details
ListView1.FullRowSelect = True
'Construct Columns
ListView1.Columns.Add("Last Name", 100)
ListView1.Columns.Add("Amount", 100)
End Sub
Private Sub UpdateLV(lname As String)
'Updates last name and amount entered into the database
Dim sql As String = "UPDATE Table1 SET LastName='" + TextBox1.Text + "',Amount='" + TextBox2.Text + "' WHERE LastName='" + lname + "'"
cmd = New OleDbCommand(sql, con)
'OPEN CON, EXECUTE, UPDATE, CLOSE
Try
con.Open()
adapter = New OleDbDataAdapter(cmd)
adapter.UpdateCommand = con.CreateCommand()
adapter.UpdateCommand.CommandText = sql
If (adapter.UpdateCommand.ExecuteNonQuery() > 0) Then
MsgBox("Successfully Updated")
End If
con.Close()
Retrieve()
ClearBox()
Catch ex As Exception
MsgBox(ex.Message)
con.Close()
End Try
End Sub
Private Sub Retrieve()
ListView1.Items.Clear()
'SQL STM
Dim sql As String = "SELECT * FROM Table1 "
cmd = New OleDbCommand(sql, con)
'OPEN CON, RETRIEVE, FILL LISTVIEW
Try
con.Open()
adapter = New OleDbDataAdapter(cmd)
adapter.Fill(dt)
'LOOP THROUGH DT
For Each row In dt.Rows
Populate(row(0), row(1)) 'Index of database row
Next
'CLEAR DATATABLE
dt.Rows.Clear()
con.Close()
Catch ex As Exception
MsgBox(ex.Message)
con.Close()
End Try
End Sub
Private Sub Populate(lname As String, aamount As String)
'ROW ARRAY
Dim row As String() = New String() {lname, aamount}
Dim item As ListViewItem = New ListViewItem(row)
'ADD TO ROWS COLLECTION
ListView1.Items.Add(item)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Retrieve()
End Sub
Private Sub ListView1_MouseClick(sender As Object, e As MouseEventArgs) Handles ListView1.MouseClick
Dim llname As String = ListView1.SelectedItems(0).SubItems(0).Text
Dim amounts As String = ListView1.SelectedItems(0).SubItems(1).Text
TextBox1.Text = llname
TextBox2.Text = amounts
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim amounts As String = ListView1.SelectedItems(0).SubItems(0).Text
UpdateLV(amounts)
End Sub
Private Sub ClearBox()
TextBox1.Text = ""
TextBox2.Text = ""
End Sub
End Class
Mathematical operation should not be done using strings. This is a real basic principle that many VB.NET programmers don't think enough thanks to the forgiveness allowed by Option Strict Off in the VB.NET project settings.
If you are just starting a new project in VB.NET don't use this setting but switch it ASAP to On. This will give you an halt when you try to use strings as they were numbers and force you to do the appropriate conversion and checking on the values provided.
So your code that updates the amount rewritten
Private Sub UpdateLV(lname As String)
' Get the amount as a number (decimal for currency is the best)
Dim addAmt As Decimal
if Not decimal.TryParse(textbox2.Text, addAmt) Then
MessageBox.Show("Insert a valid amount please")
return
End If
' Sanity check
if addAmt <= 0 Then
MessageBox.Show("Amount should be > 0")
return
End If
'Updates last name and amount entered into the database
Dim sql As String = "UPDATE Table1 SET LastName=#name
,Amount=Amount+#amt
WHERE LastName=#oldname"
cmd = New OleDbCommand(sql, con)
Try
con.Open()
' Using an adapter here is wrong. You use directly the command
cmd.Parameters.Add("#name", OleDbType.VarWChar).Value = textBox1.Text
cmd.Parameters.Add("#amt", OleDbType.Decimal).Value = addAmt
cmd.Parameters.Add("#oldname", OleDbType.VarWChar).Value = lName
If (cmd.ExecuteNonQuery() > 0) Then
MsgBox("Successfully Updated")
End If
con.Close()
Retrieve()
ClearBox()
Catch ex As Exception
MsgBox(ex.Message)
con.Close()
End Try
End Sub
Something else is not clear in your code. What is the purpose of changing also the LastName here? Finally do not keep a global connection object. Instead create it when you need it and destroy it afterward with Using statement. It will be better for your memory footprint and for your database

SQL insert statement syntax error [duplicate]

This question already has an answer here:
VB.net Syntax error in INSERT INTO statement (Although, there's not syntax error in the statment)
(1 answer)
Closed 5 years ago.
Im trying to insert this name on the uname database field. But it seems its not doing good. Anhy help will be appreciated. I already check by the way all the sources of help that I could have. However its still the same.
Public Conn_OLE As New OleDb.OleDbConnection
Public myCMD As New OleDb.OleDbCommand
Public myDR As OleDb.OleDbDataReader
Public Sub ConOpenDB_OLE() 'Use to connect to a database via oledb
Try
Conn_OLE = New OleDb.OleDbConnection
Conn_OLE.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source =C:\Users\DHALIA\Downloads\ThesisSystem - Copy\ThesisSystem - Copy\Thesis_Try_1\ThesisDB.accdb;Jet OLEDB:Database Password=mdr_mvp"
Conn_OLE.Open()
Conn_OLE.Close()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Private Sub OK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK.Click
ConOpenDB_OLE()
Conn_OLE.Open()
myCMD.CommandText = "INSERT INTO USER ([uname],) VALUES (#uname)"
myCMD.Parameters.AddWithValue("#uname", UsernameTextBox.Text)
myCMD.Connection = Conn_OLE
myCMD.ExecuteNonQuery()
myCMD.Dispose()
Conn_OLE.Close()
End Sub
USER is a reserved keyword in Access, you need square brackets around it and fix the typo after the uname field: (no comma is required after the last field listed)
CMD.CommandText = "INSERT INTO [USER] ([uname]) VALUES (#uname)"
Also, I suggest you to change your code that creates the connection, to
Public Function ConOpenDB_OLE() As OleDbConnection
Dim con = New OleDb.OleDbConnection
con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source =C:\Users\DHALIA\Downloads\ThesisSystem - Copy\ThesisSystem - Copy\Thesis_Try_1\ThesisDB.accdb;Jet OLEDB:Database Password=mdr_mvp"
con.Open()
Return con
End Sub
This allows you to write this code
Private Sub OK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK.Click
Using con = ConOpenDB_OLE()
myCMD.CommandText = "INSERT INTO [USER] ([uname]) VALUES (#uname)"
myCMD.Parameters.AddWithValue("#uname", UsernameTextBox.Text)
myCMD.Connection = con
myCMD.ExecuteNonQuery()
End Using
End Sub
In this way, you don't need anymore a global variable to keep your connection, you just get it when you need it and with the using statement you don't risk to forget the proper closing and disposing also in case of exceptions.

VB.Net SQL Count Statement into a label

I'm trying to count the students whose teacher where teacher = '" & lblTeacher.Text & "'"
EXAMPLE :
Public Class Form1
Dim conn As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Richard\Desktop\Dbase.mdb"
Dim con As New OleDbConnection
Dim da, da1 As New OleDbDataAdapter
Dim dt, dt1 As New DataTable
Dim sql As String
Dim ds As New DataSet
Public Sub display()
sql = "select * from Info"
dt.Clear()
con.Open()
da = New OleDbDataAdapter(sql, con)
da.Fill(dt)
con.Close()
DataGridView1.DataSource = dt.DefaultView
End Sub
Public Sub count()
sql = "select COUNT(name) from Info where teacher = '" & lblTeacher.Text & "'"
da1 = New OleDbDataAdapter(sql, con)
ds.Clear()
con.Open()
da.Fill(ds)
lblCount.Text = ds.Tables(0).Rows.Count.ToString
con.Close()
End Sub
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
con.ConnectionString = conn
display()
End Sub
Private Sub DataGridView1_Click(sender As System.Object, e As System.EventArgs) Handles DataGridView1.Click
lblTeacher.Text = DataGridView1.CurrentRow.Cells("teacher").Value.ToString
count()
End Sub
End Class
1:
Try this instead of your current count() method. Pay special attention to my comments; they address some poor practices from the original code:
' Better functional style: accept a value, return the result
Public Function GetStudentCount(teacher As String) As Integer
'**NEVER** use string concatenation to put data into an SQL command!!!
Const sql As String = "select COUNT(name) from Info where teacher = ?"
'Don't try to re-use the same connection in your app.
' It creates a bottleneck, and breaks ADO.Net's built-in connection pooling,
' meaning it's more likely to make object use *worse*, rather than better.
'Additionally, connection objects should be created in a Using block,
' so they will still be closed if an exception is thrown.
' The original code would have left the connection hanging open.
Using con As New OleDbConnection(conn), _
cmd As New OleDbCommand(sql, con)
'This, rather than string concatenation, is how you should put a value into your sql command
'Note that this NEVER directly replaces the "?" character with the parameter value,
' even in the database itself. The command and the data are always kept separated.
cmd.Parameters.Add("teacher", OleDbType.VarChar).Value = teacher
con.Open()
' No need to fill a whole dataset, just to get one integer back
Return DirectCast(cmd.ExecuteScalar(), Integer)
'No need to call con.Close() manually. The Using block takes care of it for you.
End Using
End Function
Here it is again, without all the extra comments:
Public Function GetStudentCount(teacher As String) As Integer
Const sql As String = "select COUNT(name) from Info where teacher = ?"
Using con As New OleDbConnection(conn), _
cmd As New OleDbCommand(sql, con)
cmd.Parameters.Add("teacher", OleDbType.VarChar).Value = teacher
con.Open()
Return DirectCast(cmd.ExecuteScalar(), Integer)
End Using
End Function
Call it like this:
Private Sub DataGridView1_Click(sender As System.Object, e As System.EventArgs) Handles DataGridView1.Click
lblTeacher.Text = DataGridView1.CurrentRow.Cells("teacher").Value.ToString()
lblCount.Text = GetStudentCount(lblTeacher.Text).ToString()
End Sub

Type mismatch in criteria expression

I am new to visual basic . I want to delete a record based on phone number . The program will ask the user to enter his number and will delete the record after matching the phone number with the database . I tried doing so but it is giving me an error "Type mismatch in criteria expression".
I am using ms access 2007 and I have speciefied the data type of the phone column as Number . Here is my vb code . Please help me . It must be one of my silly mistakes . In the insert data module , I have specified the datatype as Long , before that I had specified it as Integer but the same error persists .
Imports System.Data.OleDb
Public Class Form5
Public Connstring As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source = C:\Users\AMEN\Documents\Railway.accdb"
Public Conn As New OleDbConnection
Private Sub Form5_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Conn.ConnectionString = Connstring
If Conn.State = ConnectionState.Closed Then
Conn.Open()
End If
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim okToDelete As MsgBoxResult = MsgBox("Are you sure you want to cancel your ticket?", MsgBoxStyle.YesNo)
If okToDelete = MsgBoxResult.Yes Then
Dim str As String
str = "Delete from Table2 Where Phone = '" & TextBox1.Text & "'"
Dim cmd As OleDbCommand = New OleDbCommand(str, Conn)
Try
cmd.ExecuteNonQuery()
cmd.Dispose()
Conn.Close()
MsgBox("Your Ticket Cancelled Sucessfully ! ")
Catch ex As Exception
MsgBox(ex.Message)
End Try
ElseIf okToDelete = MsgBoxResult.No Then
End If
End Sub
End Class
Phone numbers should be stored as strings not as numbers.
But a part from this your query is wrong if your Phone field is numeric.
In that case you don't need quotes around the TextBox1.Text. This will treat your input as a string and this string cannot be used to search in a numeric field.
The best approach is to use a parameterized query where you could specifiy the datatype of the parameter passed
(I have assumed that you have created the field Phone as Long Number in Access)
If okToDelete = MsgBoxResult.Yes Then
' Check if your user types really a number.
Dim number As Integer
if Not Int32.TryParse(TextBox1.Text, number) Then
MessageBox.Show("Not a valid number!")
return
End If
Dim str As String
str = "Delete from Table2 Where Phone = #phone"
Dim cmd As OleDbCommand = New OleDbCommand(str, Conn)
Try
cmd.Parameters.Add("#phone", OleDbType.Integer).Value = number
cmd.ExecuteNonQuery()
....

The multi-part identifier “System.Data.DataRowView” could not be bound." SQL SERVER + VB.NET

Hi I am making a small database using sql server as the back and vb as the front end, I have nearly made it work however I have stumbled across this error.
My code is provided below would really appreciate some help.
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
Dim cmd As New SqlCommand
conn = New SqlConnection(connectionstring)
conn.Open()
cmd = New SqlCommand("select tarif from tarif_sewa where kode_tarif = " & ComboBox1.Text & "", conn)
TextBox2.Text = cmd.ExecuteScalar
conn.Close()
End Sub
End Class
The correct approach at your query should be
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
Using conn = New SqlConnection(connectionstring)
Using cmd = New SqlCommand("select tarif from tarif_sewa where kode_tarif = #p1", conn)
conn.Open()
cmd.Parameters.AddWithValue("#p1", ComboBox1.Text)
Dim result = cmd.ExecuteScalar
If result IsNot Nothing Then
' A better conversion could be applied knowing the exact datatype of tarif '
TextBox2.Text = result.ToString
End If
End Using
End Using
End Sub
This will replace your string concatenation with a parameterized query and enclose your disposable object in a Using statement.
However I can't figure out how this error could be emitted by your code that (while it is not to be recommended as best practice) is not formally wrong