how to save changes from DataSet to physical Database - vb.net

I've been looking at this problem for a while and can't see what I'm doing wrong.
I want to save changes from DataSet(ds.Tables("Login")) to physical Database (Data Source='|DataDirectory|\MyDatabase.accdb). But it doesn't work correctly. Data not saved in physical Database.
Any Ideas how to solve it ??
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles txtUsername.Click
Dim ds As New DataSet()
Dim dt As DataTable
ds.Tables.Add(New DataTable("Login"))
Dim connStr As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='|DataDirectory|\MyDatabase.accdb'"
Dim sqlStr As String = "SELECT * FROM Login"
Dim dataAdapter As New OleDb.OleDbDataAdapter(sqlStr, connStr)
dataAdapter.Fill(ds.Tables("Login"))
dt = ds.Tables("Login")
Dim dr As DataRow
dr = dt.NewRow()
dr("Username") = txtUserName.Text
dr("Password") = txtPassword.Text
dt.Rows.Add(dr)
ds.AcceptChanges()
dataAdapter.Update(ds.Tables("Login"))
End Sub

Look at this article and particularly step 7 which states you will need to set the UpdateCommand.
https://support.microsoft.com/en-us/kb/301248

Related

VB.Net, Problem updating table from DataGridView

This is my first post so forgive me if I goof!
I am trying to update myself from VBA to VB.Net. Using loads of help from Google etc I am doing Ok except when I try to update my table from a DataGridView. It just does not update. What I would like is that a cell is update on change. My code so far is shown (I have tried all sorts of builder, tables etc so my code may have a smattering of these that are redundant):
Imports System.Data.SqlClient
Imports System.IO
Imports Microsoft.SqlServer
Public Class FrmData
Private dsS As DataSet = New DataSet
Private adpS As SqlDataAdapter
Private builder As SqlCommandBuilder
Private bsource = New BindingSource
Private Sub FrmData_Load(sender As Object, e As EventArgs) Handles
MyBase.Load
Dim sqlS = "SELECT [Data].[Date] AS [Date] ,
[Data].[PaidBy] AS [Paid By] ,
[Data].[PaidAmount] AS [Paid Amount (£)],
[Data].[AmountLeft] AS [Amount Left (£)]
FROM [Data] WHERE [Data].[Name]= '" & strName & "'
ORDER BY [Data].[Date] DESC"
Dim adpS As SqlDataAdapter
adpS = New SqlDataAdapter(sqlS, connection)
builder = New SqlCommandBuilder(adpS)
Dim dTable As New DataTable
bsource.DataSource = dTable
bsource.EndEdit()
adpS.Fill(dTable)
connection.Close()
DataGridView1.DataSource = dTable
End Sub
Private Sub DataGridView1_CellEndEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit
DataGridView1.EndEdit()
Dim dt As DataTable
dt = TryCast(DataGridView1.DataSource, DataTable)
Dim x As Integer = 0
If dt.GetChanges() Is Nothing Then
MessageBox.Show("The table contains no changes to save.")
Else
Dim builder = New SqlCommandBuilder(adpS)
Dim rowsAffected As Integer = adpS.Update(dt)
If rowsAffected = 0 Then
MessageBox.Show("No rows were affected by the save operation.")
Else
MessageBox.Show(rowsAffected & " rows were affected by the save operation.")
End If
End If
End Sub
End Class
Any help would be appreciated.
This is for SQL Server, right. Try it like this.
Imports System.Data.SqlClient
Public Class Form1
Dim sCommand As SqlCommand
Dim sAdapter As SqlDataAdapter
Dim sBuilder As SqlCommandBuilder
Dim sDs As DataSet
Dim sTable As DataTable
Private Sub load_btn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles load_btn.Click
Dim connectionString As String = "Data Source=.;Initial Catalog=pubs;Integrated Security=True"
Dim sql As String = "SELECT * FROM Stores"
Dim connection As New SqlConnection(connectionString)
connection.Open()
sCommand = New SqlCommand(sql, connection)
sAdapter = New SqlDataAdapter(sCommand)
sBuilder = New SqlCommandBuilder(sAdapter)
sDs = New DataSet()
sAdapter.Fill(sDs, "Stores")
sTable = sDs.Tables("Stores")
connection.Close()
DataGridView1.DataSource = sDs.Tables("Stores")
DataGridView1.ReadOnly = True
save_btn.Enabled = False
DataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect
End Sub
Private Sub new_btn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles new_btn.Click
DataGridView1.[ReadOnly] = False
save_btn.Enabled = True
new_btn.Enabled = False
delete_btn.Enabled = False
End Sub
Private Sub delete_btn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles delete_btn.Click
If MessageBox.Show("Do you want to delete this row ?", "Delete", MessageBoxButtons.YesNo) = DialogResult.Yes Then
DataGridView1.Rows.RemoveAt(DataGridView1.SelectedRows(0).Index)
sAdapter.Update(sTable)
End If
End Sub
Private Sub save_btn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles save_btn.Click
sAdapter.Update(sTable)
DataGridView1.[ReadOnly] = True
save_btn.Enabled = False
new_btn.Enabled = True
delete_btn.Enabled = True
End Sub
End Class
After two days working on this, I finally got it right for myself! Also, I had an eye on #ryguy72 codes as well. these are the steps you can take to get there:
Step 1: Drag and drop DataGridView into your form
Step 2: In the App.config add this between configuration:
<connectionStrings>
<add name="ehsanConnection" connectionString="Data Source=XXX
; User= XX; Password= XXX" ProviderName="System.Data.SqlClient"/>
</connectionStrings>
Step 3: The code below shows how you can get the DataGridView programmatically right, it worked perfectly fine for me.
Dim sCommand As SqlCommand
Dim sAdapter As SqlDataAdapter
Dim sBuilder As SqlCommandBuilder
Dim sDs As DataSet
Dim sTable As DataTable
Dim connStr As String =
ConfigurationManager.ConnectionStrings("ehsanConnection").ToString
Dim connStri = New SqlConnection(connStr)
Dim sql As String = "SELECT * FROM [Ehsan].[dbo].[Data]"
sCommand = New SqlCommand(sql, connStri)
sAdapter = New SqlDataAdapter(sCommand)
sBuilder = New SqlCommandBuilder(sAdapter)
sDs = New DataSet()
sAdapter.Fill(sDs, "Data")
sTable = sDs.Tables("Data")
connStri.Close()
DataGridView1.DataSource = sDs.Tables("Data")
The main point here was that I had to use [Ehsan].[dbo].[Data] not only the name of the table, "Data". Actually, it didn't work for me that way and it kept complaining!
Step 4: If you want to update your database after you changed some of the records in datagridview, use this code :
sAdapter.Update(sDs.Tables(0))
Main important point is that: "you have to set a primary key in your table first otherwise it won't work!"

Updating records requires a valid InsertCommand when passed DataRow collection with new rows

I'm trying to add data from a form back into an Access table but I keep getting this error message:
Update requires a valid InsertCommand when passed DataRow collection
with new rows.
And for the life of me I can't work out what I need to do.
Here's the code for the button click that's supposed to update the records.
Public Class Orders
Dim ClientOrderConnection As New OleDb.OleDbConnection
Dim Provider As String
Dim dbSource As String
Dim sqlQuery As String
Dim dsClientOrder As New DataSet
Dim daClientOrder As New OleDb.OleDbDataAdapter
Dim dtOrders As New Data.DataTable
Dim Booking As New ArrayList
Dim RowNumber As Integer
Dim Counter As Integer = 0
Dim NumberOfRows As Integer
Private Sub Orders_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Provider = "PROVIDER=Microsoft.ACE.OLEDB.12.0;"
dbSource = "Data Source = A2ComputingDatabase.accdb"
ClientOrderConnection.ConnectionString = Provider & dbSource
ClientOrderConnection.Open()
sqlQuery = "SELECT * FROM TblClientOrder"
daClientOrder = New OleDb.OleDbDataAdapter(sqlQuery, ClientOrderConnection)
daClientOrder.Fill(dsClientOrder, "ClientOrder")
ClientOrderConnection.Close()
NumberOfRows = dsClientOrder.Tables("ClientOrder").Rows.Count
Private Sub btnSubmit_Click(sender As System.Object, e As System.EventArgs) Handles btnSubmit.Click
If RowNumber <> -1 Then
Dim cbClientOrder As New OleDb.OleDbCommandBuilder
Dim dsClientNewRow As DataRow
dsClientNewRow = dsClientOrder.Tables("ClientOrder").NewRow()
dsClientNewRow.Item("ClientOrderNumber") = txtOrderNo.Text
dsClientNewRow.Item("ClientTelNo") = txtClientTelNo.Text
dsClientOrder.Tables("ClientOrder").Rows.Add(dsClientNewRow)
daClientOrder.Update(dsClientOrder, "ClientOrder")
MsgBox("New Reocrd added to the Database")
End If
End Sub
Any help is much appreciated.
You actually have to instantiate the OledbCommandBuilder from your DataAdapter:
cbClientOrder = New OleDb.OleDbCommandBuilder(daClientOrder)
Dim cbClientOrder with your DataAdapter then put that somewhere after the daClientOrder.Fill() call and you should be good to go. And of course get rid of the other declaration of cbClientOrder in your btnSubmit_Click event.

Filtering Data within a DataGridView in VB.NET

How would I add a filtration function to my program so when I begin typing into a text box, it filters the results in the DataGridView? Just to clarify, this code loads a linked Access database into the DataGridView on form load and allows me to add, remove and update the data contained with in.
I'm relatively new to Visual Basic and I have ran out of ideas in regards to what to in order to get it to work. Thank you in advance for any help provided!
Imports System.Data.OleDb
Public Class frmDatabase
Dim con As New OleDbConnection
Dim ds As New DataSet
Dim dt As New DataTable
Dim da As New OleDbDataAdapter
Private Sub frmDatabase_Load(sender As Object, e As EventArgs) Handles MyBase.Load
con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Joe\Documents\Visual Studio 2012\Projects\school database viewer\school database viewer\dbSchoolDatabase.mdb"
con.Open()
ds.Tables.Add(dt)
da = New OleDbDataAdapter("Select * from tableStudentDetails", con)
Dim cb = New OleDbCommandBuilder(da)
cb.QuotePrefix = "["
cb.QuoteSuffix = "]"
da.Fill(dt)
dgvStudentDetails.DataSource = dt.DefaultView
con.Close()
End Sub
Private Sub cmdSave_Click_1(sender As Object, e As EventArgs) Handles cmdSave.Click
da.Update(dt)
End Sub

Why is my DataGridView in VB.Net doubling in size every time I access the Access Database?

I have some basic code here that calls in an Access Database ("Houses") and that's about all. However, every time I click the button, the size of the DataGridView doubles. What I mean is that if the actual Access database has 5 rows, the DataGridView shows the correct database initially, but after each click of the button it goes up to 10 rows (they repeat), then 15, then 20 etc. Unfortunately I can't place this in the Form_Load area.
I tried placing "dt.rows.clear()" before "dgv.DataSource = dt", but it wipes everything. Also tried "DirectCast(Dgv.DataSource, DataTable).Rows.Clear()" and "Dgv.Datasource = Nothing"
Public Class frmHouses
Dim dt As DataTable = New DataTable()
Dim connStr As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Houses.accdb"
Dim sqlStr As String = "SELECT * FROM Property"
Private Sub btnRecord_Click(sender As Object, e As EventArgs) Handles btnRecord.Click
Dim dataAdapter As OleDb.OleDbDataAdapter = New OleDb.OleDbDataAdapter(sqlStr, connStr)
dataAdapter.Fill(dt)
dataAdapter.Dispose()
dgv.DataSource = dt
End Sub
Thanks!
Public Class frmHouses
Dim connStr As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Houses.accdb"
Dim sqlStr As String = "SELECT * FROM Property"
Private Sub btnRecord_Click(sender As Object, e As EventArgs) Handles btnRecord.Click
Dim dt As DataTable = New DataTable()
Dim dataAdapter As OleDb.OleDbDataAdapter = New OleDb.OleDbDataAdapter(sqlStr, connStr)
dataAdapter.Fill(dt)
dataAdapter.Dispose()
dgv.DataSource = dt
End Sub
OR you can
Public Class frmHouses
Dim dt As DataTable = New DataTable()
Dim connStr As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Houses.accdb"
Dim sqlStr As String = "SELECT * FROM Property"
Private Sub btnRecord_Click(sender As Object, e As EventArgs) Handles btnRecord.Click
dt.clear()
Dim dataAdapter As OleDb.OleDbDataAdapter = New OleDb.OleDbDataAdapter(sqlStr, connStr)
dataAdapter.Fill(dt)
dataAdapter.Dispose()
dgv.DataSource = dt
End Sub
Public Class frmHouses
Dim dt As DataTable = New DataTable()
Dim connStr As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Houses.accdb"
Dim sqlStr As String = "SELECT * FROM Property"
Private Sub btnRecord_Click(sender As Object, e As EventArgs) Handles btnRecord.Click
Dim dataAdapter As OleDb.OleDbDataAdapter = New OleDb.OleDbDataAdapter(sqlStr, connStr)
dataAdapter.Fill(dt)
dataAdapter.Dispose()
IF dgv.Rows.Count > 0 Then
dgv.Rows.Clear()
End IF
dgv.DataSource = dt
End Sub

vb.net load record data in a text field

im fairly new to databases in vb.net and i have just learned how to use datagridview. im gonna show some of my code for the connection and datagridview display
Public Class Form1
Dim con As New OleDb.OleDbConnection
Dim dbProvider As String
Dim dbSource As String
Dim ds As New DataSet 'holds table data
Dim da As OleDb.OleDbDataAdapter 'connection to database connectionobject
Dim sql As String
Dim inc As Integer
Dim MaxRows As Integer
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
dbProvider = "PROVIDER=Microsoft.Jet.OLEDB.4.0;"
dbSource = "Data Source = C:/AddressBook.mdb"
con.ConnectionString = dbProvider & dbSource
'alternative way of connection
'Dim fldr As String
'Environment is the user profile
'fldr = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) & "/AddressBook.mdb"
'dbSource = "Data Source = " & fldr
con.Open()
MsgBox("Database is now Open")
sql = "select * from tblContacts"
da = New OleDb.OleDbDataAdapter(sql, con)
da.Fill(ds, "Addressbook")
con.Close()
MsgBox("Database is now Closed")
MaxRows = ds.Tables("AddressBook").Rows.Count
inc = -1
MsgBox(MaxRows)
TextBox1.Text = inc
DataGridView1.DataSource = ds
DataGridView1.DataMember = "AddressBook"
End Sub
End Class
i want to display in a textfield the first name based on where is the pointer is positioned after i clicked Button1, how do i do this? thank you for the replies!
You need to get that value from the data grid itself, and then show it on the form. There are other ways, but try this (and add null checks!):
Dim row as DataRow = CType(DataGridView1.CurrentRow.DataBoundItem, DataRowView).Row
myTextBox.Text = row["firstName"].ToString();
C#
var row = ((DataRowView)dataGridView1.CurrentRow.DataBoundItem).Row;
myTextBox.Text = row["firstName"].ToString();
Alternately:
If you use a DataSource, and bind the grid to that first, then fill the DataSource with the data, you can use the .Current property to get the selected row.
Edit:
Mistake in code. It should be "DataBoundItem". Not "DataItem". From memory... Also, you need to cast to string, ctype(...,string) or call .ToString().
If you bind to a list of objects, then you won't need to call the .Row, the DataBoundItem will be the actual object type, eg Customer