Update record in DataGridView - vb.net

I use simple SQL to modyf ACC database conected to DataGridView via dataSet.xsc. Inserting works perfect, but updateing is fail (why?)
Table have 3 columns (2 strings and one boolean represented by Checkbox).
UPDATE Tabele
SET We = True 'or False in another SQL
WHERE (Name = ?) AND (Address = ?)
"We" is checkbox in table column, I try change by mouse in DataGridView.
In code i used this line to modyf table:
Private Sub Tabela_adresowDataGridView_CellContentClick(sender As Object, _
e As Windows.Forms.DataGridViewCellEventArgs) Handles _
Tabela_adresowDataGridView.CellContentClick
If e.ColumnIndex = 2 Then
Try
With Tabela_adresowDataGridView
Me.Tabela_adresowBindingSource.EndEdit()
If .Item(e.ColumnIndex, e.RowIndex).Selected = True Then
Me.Tabela_adresowTableAdapter.UpdateQuery_Checked(.Item(0, e.RowIndex).Value.ToString, _
.Item(1, e.RowIndex).Value.ToString)
Else
Me.Tabela_adresowTableAdapter.UpdateQuery_Uncheck(.Item(0, e.RowIndex).Value.ToString, _
.Item(1, e.RowIndex).Value.ToString)
End If
Tabela_adresowDataGridView.Update()
'Me.Validate()
'Me.TableAdapterManager.UpdateAll(Me.Baza_adresowDataSet)
'Baza_adresowDataSet.AcceptChanges()
End With
Catch ex As Exception
MsgBox(ex.Message)
End Try
End If
Regardless of whether the inserted Primarykey or use one simple SQL with 3th parameter for a check state. Table is not modyfied. (?)

Try to select your quert by you want and after put in your table:
Dim SelectQuery As String = "Your Query"
Dim WhereQuery As String = " WHERE (1=1)"
ElseIf BOX_toDate.Text <> Nothing Then
Name= WhereQuery & " AND TargetDate <= '" & Your value & "'"
End If
Dim con As New SqlConnection
Dim cmd As New SqlCommand
con = FunctionConnection()
cmd.Connection = con
cmd.CommandText = SelectQuery & WhereQuery
cmd.CommandType = CommandType.Text
Or like that: How to search data in all tables in database using select query in vb.net?

Related

Using 2 combo boxes to populate a datagridview in VB.NET

I having problems understanding why my one of my comboboxes displays a filtered search but the other one doesn't, I am using the same code for both comboboxes but modified some SQL queries linked to my database. I have also noticed that when I remove or comment out the code for any one of the comboboxes the the filtered search happens for the one hasn't been commented or removed. I also used an "If, Else" statement but still doesn't work. I would also want for both comboboxes to be used to filter a datagridview. Just to keep in mind once the item is selected from the combobox a search button is pressed to filer/display data into the datagridview.
Kind Regards
Here is my code and form:
[Redundant Data being displayed] https://i.stack.imgur.com/JEQI4.png
[ComboBox Brand works as intended] https://i.stack.imgur.com/6YyBf.png
[ComboBox Category displays everything rather than displaying the category chosen] https://i.stack.imgur.com/oEfII.png
Private Sub BtnSearch_Click(sender As Object, e As EventArgs) Handles BtnSearch.Click
If Not CmbBrand.SelectedIndex & CmbCategory.SelectedIndex = Nothing Then
BrandDisplay()
ElseIf CmbBrand.SelectedIndex & Not CmbCategory.SelectedIndex = Nothing Then
CategoryDisplay()
ElseIf Not CmbBrand.SelectedIndex & Not CmbCategory.SelectedIndex = Nothing Then
If DbConnect() Then
DgvRecord.Rows.Clear()
Dim SQLCmd As New OleDbCommand
With SQLCmd
.Connection = cn
.CommandText = "Select * " &
"From TblStock " &
"Where STCategory Like #CategorySearch"
.Parameters.AddWithValue("#CategorySearch", "%" & CmbCategory.Text & "%")
Dim rs As OleDbDataReader = .ExecuteReader()
SQLCmd.ExecuteReader()
While rs.Read
Dim NewStockRow As New DataGridViewRow()
NewStockRow.CreateCells(DgvRecord)
NewStockRow.SetValues({rs("StockID"), rs("STDateTime"), rs("STCategory"), rs("STBrand"), rs("STItemDescription"), rs("STSerialNumber"), rs("StockIn"), rs("StockOut"), rs("Stock")})
NewStockRow.Tag = rs("StockID")
DgvRecord.Rows.Add(NewStockRow)
End While
rs.Close()
If DgvRecord.Rows(0).Selected = True Then
MessageBox.Show("Please select a Category from the drop down list", "Category", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End If
End With
End If
End If
cn.Close()
End Sub
Private Sub BrandDisplay()
If DbConnect() Then
DgvRecord.Rows.Clear()
Dim SQLCmd As New OleDbCommand
With SQLCmd
.Connection = cn
.CommandText = "Select * " &
"From TblStock " &
"Where STBrand Like #BrandSearch"
.Parameters.AddWithValue("#BrandSearch", "%" & CmbBrand.Text & "%")
Dim rs As OleDbDataReader = .ExecuteReader()
SQLCmd.ExecuteReader()
While rs.Read
Dim NewStockRow As New DataGridViewRow()
NewStockRow.CreateCells(DgvRecord)
NewStockRow.SetValues({rs("StockID"), rs("STDateTime"), rs("STCategory"), rs("STBrand"), rs("STItemDescription"), rs("STSerialNumber"), rs("StockIn"), rs("StockOut"), rs("Stock")})
NewStockRow.Tag = rs("StockID")
DgvRecord.Rows.Add(NewStockRow)
End While
rs.Close()
If DgvRecord.Rows(0).Selected = True Then
MessageBox.Show("Please select a Brand from the drop down list", "Brand", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End If
End With
End If
cn.Close()
End Sub
Private Sub CategoryDisplay()
If DbConnect() Then
DgvRecord.Rows.Clear()
Dim SQLCmd As New OleDbCommand
With SQLCmd
.Connection = cn
.CommandText = "Select * " &
"From TblStock " &
"Where STCategory Like #CategorySearch"
.Parameters.AddWithValue("#CategorySearch", "%" & CmbCategory.Text & "%")
Dim rs As OleDbDataReader = .ExecuteReader()
SQLCmd.ExecuteReader()
While rs.Read
Dim NewStockRow As New DataGridViewRow()
NewStockRow.CreateCells(DgvRecord)
NewStockRow.SetValues({rs("StockID"), rs("STDateTime"), rs("STCategory"), rs("STBrand"), rs("STItemDescription"), rs("STSerialNumber"), rs("StockIn"), rs("StockOut"), rs("Stock")})
NewStockRow.Tag = rs("StockID")
DgvRecord.Rows.Add(NewStockRow)
End While
rs.Close()
If DgvRecord.Rows(0).Selected = True Then
MessageBox.Show("Please select a Category from the drop down list", "Category", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End If
End With
End If
cn.Close()
End Sub
```
It is a good idea to separate your User Interface code from you database code. Your event procedure code should be rather brief.
Declare your Connections, Commands and DataReaders in the method where they are used so they can be disposed. Using...End Using blocks do this for us; they also close the connection. Pass your connection string directly to the constructor of the connection.
We have a different CommandText and ParametersCollection for each possibility. For Sql Server use the Add method rather than AddWithValue.
Private Sub BtnSearch_Click(sender As Object, e As EventArgs) Handles BtnSearch.Click
Dim dt = GetSearchData(CmbBrand.Text, CmbCategory.Text)
DGVRecord.DataSource = dt
End Sub
Private Function GetSearchData(Brand As String, Category As String) As DataTable
Dim dt As New DataTable
Dim sqlString = "Select * From From TblStock "
Using cn As New SqlConnection("Your connection string"),
cmd As New SqlCommand()
cmd.Connection = cn
If Not String.IsNullOrEmpty(Brand) AndAlso Not String.IsNullOrEmpty(Category) Then
cmd.CommandText = sqlString & "Where STCategory = #CategorySearch And STBrand = #BrandSearch;"
cmd.Parameters.Add("#CategorySearch", SqlDbType.VarChar).Value = Brand
cmd.Parameters.Add("#BrandSearch", SqlDbType.VarChar).Value = Category
ElseIf Not String.IsNullOrEmpty(Brand) Then
cmd.CommandText = sqlString & "Where STBrand = #BrandSearch;"
cmd.Parameters.Add("#BrandSearch", SqlDbType.VarChar).Value = Category
ElseIf Not String.IsNullOrEmpty(Category) Then
cmd.CommandText = sqlString & "Where STCategory = #CategorySearch;"
cmd.Parameters.Add("#CategorySearch", SqlDbType.VarChar).Value = Brand
Else
cmd.CommandText = sqlString & ";"
End If
cn.Open()
Using reader = cmd.ExecuteReader()
dt.Load(reader)
End Using
End Using
Return dt
End Function
For better understanding you need to change those first "if... then... else...".
If the combobox is not selected it will have value -1 so you can do it like this:
Dim bBrandIsSelected as boolean = CmbBrand.SelectedIndex <> -1
Dim bCategoryIsSelected as boolean = CmbCategory.SelectedIndex <> -1
Now you can build the code more easily like:
If bBrandIsSelected AndAlso bCategoryIsSelected then
' do something
else
if bBrandIsSelected then
BrandDisplay()
else
if bCategoryIsSelected then
CategoryDisplay()
End if
End if
End if

Select from Service Based Database not finding any values without a selection in a DataGridView (WinFormsApp VB .Net Framework)

I'm quite new to VB .Net and Databases in general so I'm not sure which SQL Version I am using. I did most of my coding until now with VBA.
I added a "Service Based Database" to my "WinFormsApp" Project and created a Table with 3 Columns:
CREATE TABLE [dbo].[employees] (
[id] INT IDENTITY (1, 1) NOT NULL,
[nr] VARCHAR (MAX) NULL,
[name] TEXT NULL,
PRIMARY KEY CLUSTERED ([id] ASC)
);
Afterwards I added a Dataset for the created Table.
Following this, I added a new Form to my Project and added a few controls to it including two TextBoxes for Dataentry and a DataGridView to show the saved data. On Form_Load I fill the DataGridView using the following code:
Private Sub UpdateGridView()
'Loading the data into the GridView
'---------------------------------------
Dim Conn As SqlConnection = New SqlConnection
Dim ADP As SqlDataAdapter
Dim DS As DataSet = New DataSet
Conn.ConnectionString = My.Settings.DBConnEmployees
ADP = New SqlDataAdapter("SELECT * FROM employees", Conn)
ADP.Fill(DS)
Me.DataGridView_Employees.DataSource = DS.Tables(0)
'---------------------------------------
'Hidding the ID Col
Me.DataGridView_Employees.Columns(0).Visible = False
End Sub
Also in the Form_Load I set a few unrelated variables and TextBoxes (as I'm not able to find the errors after several hour of trial and error, I include this. Maybe I'm overlooking something):
Private Sub NewEmployee()
'Reseting the Variables
DataGridIndex = -1
EmployeeId = 0
EmployeeNr = String.Empty
EmployeeName = String.Empty
'Writing to TBs
Me.tbNr.Text = EmployeeNr
Me.tbName.Text = EmployeeName
'Select Nothing
Me.DataGridView_Employees.CurrentCell = Nothing
'Changing Btn Desc
Me.btnSaveEmployee.Text = "Neuen Mitarbeiter speichern"
End Sub
The testing data I entered into the table by hand fills in without a problem. Inserting, updating an deleting into/from the table by code works perfect.
On DataGrivView_CellDoubleClick I read some data of the the GridView into the TextBoxes to edit them:
Private Sub DataGridView_Employees_CellDoubleClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView_Employees.CellDoubleClick
If e.RowIndex <> -1 Then
'Loading selected Data
DataGridIndex = e.RowIndex
EmployeeId = Me.DataGridView_Employees.Rows(DataGridIndex).Cells(0).Value
EmployeeNr = Me.DataGridView_Employees.Rows(DataGridIndex).Cells(1).Value
EmployeeName = Me.DataGridView_Employees.Rows(DataGridIndex).Cells(2).Value
'Write to TBs
Me.tbNr.Text = EmployeeNr
Me.tbName.Text = EmployeeName
'Changing btn
Me.btnSaveEmployee.Text = "Ă„nderungen speichern"
End If
End Sub
To prevent the User from using the nr twice I wanted to check if the nr is already saved in the Table. However this is where the problems begin. The SQLCommand only finds the row which i double clicked in the GridView. Which is strange as there should be no connection between them. Hereafter my try at checking for the nr:
Private Function EmployeeNrInUse(id As Integer, nr As String) As Boolean
Dim Query As String = String.Empty
Dim Result
Dim Response As Boolean = True
'Checking for nr
'---------------------------------------
Query = "SELECT * FROM employees WHERE nr=#nr"
Using Conn = New SqlConnection(My.Settings.DBConnEmployees)
Using Comm = New SqlCommand()
With Comm
.Connection = Conn
.CommandType = CommandType.Text
.CommandText = Query
.Parameters.AddWithValue("#nr", nr)
End With
Try
Conn.Open()
Result = Comm.ExecuteScalar
Response = Not IsNothing(Result)
Catch ex As SqlException
MsgBox(ex.Message.ToString, vbOKOnly + vbCritical)
End Try
End Using
End Using
'---------------------------------------
'Return
Return Response
End Function
The Result is always returning nothing, unless I double clicked a dataentry before, then it finds it's own row (if the nr matches) but only that, no other matching nr is found.
If I forgot to mention crucial data, please inform me as this is my first question ever in a forum :) (Also please excuse any spelling mistakes etc. as English isn't my native language) Thanks in Advance for your help!
Edit:
This is how the Function EmployeeNrInUse is called (Called on Button_Clicked):
Private Sub SaveEmployeeToDB(id As Integer, nr As String, name As String)
Dim Query As String = String.Empty
'Adding new Employee / Editing existing
'---------------------------------------
If EmployeeNrInUse(id, nr) Then
MsgBox("Nr. bereits in verwendung.", vbOKOnly + vbExclamation)
Exit Sub
End If
If EmployeeId = 0 Then
Query = "INSERT INTO employees (nr, name) VALUES (#nr, #name)"
Else
Query = "UPDATE employees SET nr=#nr, name=#name WHERE id=#id"
End If
Using Conn As New SqlConnection(My.Settings.DBConnEmployees)
Using Comm As New SqlCommand()
With Comm
.Connection = Conn
.CommandType = CommandType.Text
.CommandText = Query
.Parameters.AddWithValue("#id", id) 'Wird nur bei änderung verwendet
.Parameters.AddWithValue("#nr", nr)
.Parameters.AddWithValue("#name", name)
End With
Try
Conn.Open()
Comm.ExecuteNonQuery()
UpdateGridView()
If EmployeeId = 0 Then
MsgBox("Neuen Mitarbeiter gespeichert.", vbOKOnly + vbInformation)
Else
MsgBox("Bestehenden Mitarbeiter aktualisiert.", vbOKOnly + vbInformation)
End If
NewEmployee()
Catch ex As SqlException
MsgBox(ex.Message.ToString, vbOKOnly + vbCritical)
End Try
End Using
End Using
'---------------------------------------
End Sub
The problem was caused by entering the values into the Database by hand. While copying the nr, a linebreak sneaked itself into the values so a check just for the nr instead the nr and the linebreak resulted in nothing. Properly entering the data has fixed the problem.

MysqlDataReader.Read stuck on the last record and doesnt EOF

i confused why mySqlDataReader.Read stuck on the last record and doesnt EOF ..
Here's my private function for executeSql :
Private Function executeSQL(ByVal str As String, ByVal connString As String, ByVal returnRecordSet As Boolean) As Object
Dim cmd As Object
Dim objConn As Object
Try
If dbType = 2 Then
cmd = New MySqlCommand
objConn = New MySqlConnection(connString)
Else
cmd = New OleDbCommand
objConn = New OleDbConnection(connString)
End If
'If objConn.State = ConnectionState.Open Then objConn.Close()
objConn.Open()
cmd.Connection = objConn
cmd.CommandType = CommandType.Text
cmd.CommandText = str
If returnRecordSet Then
executeSQL = cmd.ExecuteReader()
executeSQL.Read()
Else
cmd.ExecuteNonQuery()
executeSQL = Nothing
End If
Catch ex As Exception
MsgBox(Err.Description & " #ExecuteSQL", MsgBoxStyle.Critical, "ExecuteSQL")
End Try
End Function
And this is my sub to call it where the error occurs :
Using admsDB As MySqlConnection = New MySqlConnection("server=" & rs("server") & ";uid=" & rs("user") & ";password=" & rs("pwd") & ";port=" & rs("port") & ";database=adms_db;")
admsDB.Open()
connDef.Close()
rs.Close()
'get record on admsdb
Dim logDate As DateTime
Dim str As String
str = "select userid, checktime from adms_db.checkinout in_out where userid not in (select userid " &
"from adms_db.checkinout in_out join (select str_to_date(datetime,'%d/%m/%Y %H:%i:%s') tgl, fid from zsoft_bkd_padang.ta_log) ta " &
"on ta.fid=userid and tgl=checktime)"
Dim rsAdms As MySqlDataReader = executeSQL(str, admsDB.ConnectionString, True)
Dim i As Integer
'This is where the error is, datareader stuck on the last record and doesnt EOF
While rsAdms.HasRows
'i = i + 1
logDate = rsAdms(1)
'save to ta_log
str = "insert into ta_log (fid, Tanggal_Log, jam_Log, Datetime) values ('" & rsAdms(0) & "','" & Format(logDate.Date, "dd/MM/yyyy") & "', '" & logDate.ToString("hh:mm:ss") & "', '" & logDate & "')"
executeSQL(str, oConn.ConnectionString, False)
rsAdms.Read()
End While
'del record on admsdb
str = "truncate table checkinout"
executeSQL(str, admsDB.ConnectionString, False)
End Using
i'm new to vbnet and really have a little knowledge about it,, please help me,, and thank you in advance..
The issue is that you're using the HasRows property as your loop termination expression. The value of that property never changes. Either the reader has rows or it doesn't. It's not a check of whether it has rows left to read, so reading has no effect.
You are supposed to use the Read method as your flag. The data reader begins without a row loaded. Each time you call Read, it will load the next row and return True or, if there are no more rows to read, it returns False.
You normally only use HasRows if you want to do something special when the result set is empty, e.g.
If myDataReader.HasRows Then
'...
Else
MessageBox.Show("No matches found")
End If
If you don't want to treat an empty result set as a special case then simply call Read:
While myDataReader.Read()
Dim firstFieldValue = myDataReader(0)
'...
End While
Note that trying to access any data before calling Read will throw an exception.

Updating 3 Rows (fixed) Using 1 UPDATE Statement

So far I have this code updating only 1 row but is there a way to specify the three rows? (3 different ID's)
Public Shared Sub UpdatePrice(ByVal NewPrice As Decimal, ByVal id As Integer)
Dim dtoffenseinfo As New DataTable
If Not DBConnection.State = ConnectionState.Open Then
'open connection
DBConnection.Open()
Else
End If
cmd.Connection = DBConnection
cmd.CommandText = "UPDATE tblStockPrice " & _
" SET Price=" & NewPrice & " WHERE id=" & id & ""
cmd.ExecuteNonQuery()
DBConnection.Close()
End Sub
I assume I need 2 more parameters for the other two rows and that would be fine.
You can use one UPDATE statement with an appropriate WHERE clause to affect multiple records but, if you want to affect each record differently, calling ExecuteNonQuery once is not a very good option. Just create one command with appropriate parameters and then you can set the Value of each parameter multiple times to affect multiple records, e.g.
Using connection As New SqlConnection("connection string here"),
command As New SqlCommand("UPDATE MyTable SET Price = #Price WHERE Id = #Id", connection)
Dim priceParameter = command.Parameters.Add("#Price", SqlDbType.Money)
Dim idParameter = command.Parameters.Add("#Id", SqlDbType.Int)
Dim prices = {12.45, 132.67, 9.8}
Dim ids = {1, 19, 56}
connection.Open()
For i = 0 To 2
priceParameter.Value = prices(i)
idParameter.Value = ids(i)
command.ExecuteNonQuery()
Next
End Using

How to Trigger Code with ComboBox Change Event

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