New added items on the datagridview cannot be seen at runtime - vb.net

I have a program that inserts data in access database and the user can view the newly added items in a data grid view. After i add new items to the database it cannot be seen in the datagridview while the program is running. I have to stop the program and run it again just to see the changes i made.
Here is how i load the datagridview:
Public Class frmSupplies
Private Sub frmSupplies_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'SuppliesDataSet.product_info' table. You can move, or remove it, as needed.
Me.Product_infoTableAdapter.Fill(Me.SuppliesDataSet.product_info)
End Sub
How can i view the newly added items while the program is still running?

I created a module that will call the "refresh" function for the datagridview. I added a new module to my project and added this codes:
Imports System.Data.OleDb
Module Module1
Dim con As New OleDbConnection("Provider=Microsoft.Jet.Oledb.4.0;Data Source= database path")
Sub REFRESHDGV()
Dim sql As String
sql = "SELECT * FROM [product info]"
Dim adapter As New OleDbDataAdapter(sql, con)
Dim dt As New DataTable("product info")
adapter.Fill(dt)
Form1.dgv1.DataSource = dt
End Sub
End Module
Hope this helps others!

Try wrapping around beginedit ... end edit
gridview.BeginEdit();
----
gridview.EndEdit();

I am not familiar with access (I use oracle). Oracle database can notify you if something has changes in your database, so you can refresh the datagridview. In your case you can have a button (for refresh the datagridView) or a timer and refresh it every x time (you know the time):
'I imagine that you have a bindingSource
bindingSource1.DataSource = Product_infoTableAdapter.GetData()
bindingSource1.ResetBindings(false)
Maybe you want to take a look in DataGridView DataBinding

When you bind an Access table to a grid on a Windows form and then change the data outside that application, the form or the grid simply do not have a way of knowing that data was changed, unless 1) they receive some kind of notification from Access, or 2) the application keep querying the data source to see if changes were made.
Option 1 there is not applicable with MS Access.
Your only option is to put a timer on the form to regularly check for changes (on a fixed interval) and reload the table and refresh the grid if changes were found.

Related

How to edit a record in an access database - visual basic

I want to edit a specific record in an access database but I keep on getting errors
this is the database I want to edit:
Access database
these are flashcards that the user has created and stored in an access database. What I want is that the user is able to edit the difficulty so it appears more/less often
This is the module:
Module Module1
Public Function runSQL(ByVal query As String) As DataTable
Dim connection As New OleDb.OleDbConnection("provider=microsoft.ACE.OLEDB.12.0;Data Source=flashcard login.accdb") 'Establishes connection to database
Dim dt As New DataTable 'Stores database in table called dt
Dim dataadapter As OleDb.OleDbDataAdapter
connection.Open() 'Opens connection
dataadapter = New OleDb.OleDbDataAdapter(query, connection)
dt.Clear() 'Clears datatable
dataadapter.Fill(dt) 'Fills datatable
connection.Close()
Return dt
End Function
End Module
And here is the button that the user can press to edit the database:
Private Sub btnSubmit_Click(sender As Object, e As EventArgs) Handles btnSubmit.Click
Dim sql As String
sql = "UPDATE flashcards set difficulty = '" & TxtDifficulty.Text
runSQL(sql)
End Sub
The difficulty column in the database should be able to be edited by the user through the value they entered in txtDifficulty.text
Good to hear I found the problem with the apostrophe.
I am going to need a where statement but the problem I have is that the user can create as much flashcards as they want so how would I write the where statement?
An INSERT statement does not have a WHERE clause but an UPDATE does and is usually by a primary key.
Look at how I add a new record ignoring mHasException and specifically using parameters. In this case a List is used but with little effort an array of DataRow can be passed instead.
Here is an example for updating a record with a DataRow.
To get other code samples for ms-access see the following repository.
In closing, in the above repository I don't get into all possibilities yet there should be enough there to get you going. And when reviewing code I flip between Add for adding a parameter and AddWithValue while Add is the recommend way but both are shown to see differences. see also Add vs AddWithValue.

Delete record from Access database vb.net

In this project I use Access database which is displayed in DataGridView. I am trying to delete acces row but i my looking for was not successful.
Code to delete record from DataGridView:
Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
Dim index As Integer
index = DataGridView1.CurrentCell.RowIndex
DataGridView1.Rows.RemoveAt(index)
ZoznamBindingSource.RemoveCurrent().
‘Dim da As OledbDataAdapter
‘Dim ds As dataSet
da.Update(ds)
End Sub
The last line of code give me an error: SystemNullReferenceException. I know rhe dataset is problem but i don’t know which code will replace it with.
Any solution?
The whole point of a BindingSource is that it is the one and only point of contact for bound data. You shouldn't have to touch the UI and you shouldn't have to touch the data source.
In your case, you should be calling RemoveCurrent on the BindingSource. That will flag the underlying DataRow as Deleted and then, when you call Update on your data adapter, the corresponding database record will be deleted.

Unable to add rows to datatable, datatable is nothing error

I am not really sure what went wrong, i declared dt on top as a class variable then declare it as new datatable in fill function used in pageload but when i pressed buttonadd, dt is nothing error pops up.
Private dt As DataTable
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
fill()
End If
End Sub
Protected Sub fill()
dt = New DataTable
dt.Columns.Add("Status", GetType(String))
End Sub
Protected Sub btnadd_Click(sender As Object, e As EventArgs) Handles btnadd.Click
Dim R As DataRow = dt.NewRow
R("Status") = "Pending"
dt.Rows.Add(R)
'dt.Rows.Add("pending")
GridView1.DataSource = dt
GridView1.DataBind()
End Sub
The key concept is that web pages are "state-less".
That means for each event code stub, then the code is starting over from scratch.
And it means for each browser round trip, then the browser code starts from scratch EACH time. So, you only load up the data table one time (first time - this is GOOD!!!).
The problem of course, without a control on the web page. (say a data grid), or say a simple text box? Those controls survive that so called round trip. The MOST important concept, and if were going to learn ONE thing about asp.net web pages?
You must grasp the round trip concept, and the so called page state.
So, what happens in your case?
First time - page loads - code runs server side (often called code behind).
Your form instance class is created, your load event runs, you load up the table. The browser is THEN send down to the client side. The web page is just sitting here. Maybe you close the browser. Maybe you un-plug your computer. The server does not know, or care about this. In fact, the server does NOT even know the web page exists anymore!!!
So, your web page is sitting here, and you click on that button.
The web page is now sent up to the server, and the code behind starts running - but it STARTS FROM FRESH scratch each time!
So your form level variable called "data table" does NOT exist any more and does NOT have a value.
So, there are several solutions here. For starters, we need that "table" to persist and survive the rounds trip. As noted, most controls you drop into that page WILL keep their values. This is called the "viewstate". So, if we want that data table to survive and "exist" the next time the user does something? Then we need to save or persist that table variable.
Another way? You can use what is called the session(). Session() is a attempt and system to allow use to shove values into Session(). And the session() survives round trips.
Now, given your example?
Well, then our code would become this:
Private dt As DataTable
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
fill()
Session("MyCoolTable") = dt
else
' this is a page post back - re-load the active table into our
' forms level dt.
dt = Session("MyCoolTable")
end if
In a lot of cases, I would assume the table that drives the grid is a database. And thus I would add the row to the database, and then re-bind the data grid.
But the above use of session() will persist the dt table for you.

refreshing datagridview after populate existing datatable in vb.net

I am working on a windows form application using VB.net. I have populated a Datagridview1( dataset1.existingtable is the datatable). Now i wish to get distinct values from one column of its datatable and then populate another Datagridview2(dataset2.uniquerecords is the datatable).
PROBLEM: Not able to refresh data in Datagridview2 using design mode. However i am able to refresh data when dynamically creating a datatable at runtime.
The below sub is called after an event after my form has loaded completely.
The below code does NOT work
Private Sub loaddistinctrecords()
uniquerecords = existingtable.DefaultView.ToTable(True, "column_name")
Datagridview2.Refresh()
End Sub
The below code works
Private Sub loaddistinctrecords()
Dim newuniquerecords As New DataTable()
newuniquerecords = existingtable.DefaultView.ToTable(True, "column_name")
Datagridview2.DataSource = newuniquerecords.DefaultView
End Sub
well it looks like one cannot directly assign a datatable to another datatable and expect the datagridview to update automatically if the datatable was created from design mode.
What one can do is simply clear the existing records and then merge records from the source datatable.
Private Sub loaddistinctrecords()
uniquerecords.Clear()
uniquerecords.Merge(existingtable.DefaultView.ToTable(True, "table_name"))
End Sub

Faux Databinding a Recordset to a Datagridview

I am updating a very old vb6 program that includes recordsets bound to an old third party grid control. The recordset functionality is so ingrained into the program that it is not an option to replace them. So, I replaced the unfunctional grid with a datagridview and I fill it using a dataadapter and a dataset. The problem is that the recordset was originally bound to the grid and using a dgv breaks the binding.
So this is what I am trying to do. I have a function that passes in the old recordset and the new dgv, and fills it. I would like to create a dynamic handler to the dgv's selectionchanged event to update the rs with the current position on the dgv (rs.aboluteposition = dgv.row), thus updating the rs cursor to the current position in the dgv, making a sort of faux data binding.
Something like this....
AddHandler dgv.SelectionChanged, AddressOf RefreshRecordset
Public Sub RefreshRecordset()
myRS.AbsolutePosition = dgv.Row
End Sub
A couple things though. I have to track if the event handler was already created, and the associated recordset that goes with this specific datagridview. Also, since this is a global function to update many dgvs with many rs, it needs to have a way to track the recordset. I was thinking of somehow using the tag of dgv? Maybe create a dictionary of all the recordsets then look it up by the name of the dgv?
Below is my original method that worked pretty well. I eventually refined it and put it in a class for each recordset. I also updated it to accept true dbgrids. By wrapping it in a class, I was able to remove the dictionaries. In the New function, I pass in either grid and a recordset. From there, I set up event handlers to handle both the grid row change and also the recordset MoveComplete event. I had to use the MoveComplete because the RecordsetChangeComplete has a bug and doesn't always fire correctly. I just check in the MoveComplete if the record count had changed. If so, refresh the grid. Lastly, I added a removehandler for each of the events in the finalize function.
////// The Original Answer //////
For instance, like this... (I CAN'T believe this worked...)
Public dict as new Dictionary(Of String, ADODB.Recordset)
Public Sub FillGrid(ByRef dgv as DataGridView, ByRef rs as ADODB.RecordSet)
'.... Fill the grid with the tableadapter, blah blah.
If Not dict.ContainsValue(rs) Then
dict.add(dgv.Name, rs)
AddHandler dgv.SelectionChanged, AddressOf RefreshRecordset)
' To make the event fire correctly, I think
dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect
End if
End Sub
Public Sub RefreshRecordset(sender As Object, e As System.EventArgs)
Dim dgv as DataGridView = Ctype(sender, DataGridView)
If dict.ContainsKey(dgv.Name) then
Dim rs as ADODB.Recordset = dict(dgv.Name)
rs.AbsolutePosition = dgv.CurrentCell.RowIndex
End if
End Sub
Now I need to create a handler to the recordset to refresh the dgv everytime the recordset is updated.
And btw, I know there are probably other ways to do this and I would absolutely would love to hear them! Please feel free!
Thanks!