Update grid from a query - sql

I have a Visual Basic 2010 application that uses a DataGridView to display a list of frequencies from a Microsoft Access 2010 database. The application uses the BindingNavigationPostionItem to allow navigation though the table.
The Move Next and Move Previous buttons move you up and down the list. The cool thing is, as you do this, I have code that sends the Frequency and Mode to my Yeasu radio and the radio then is set to that freq/mode.
This works great but, if I try to filter the DataGridView by the Service field, the ID field becomes blank and navigation does not work.
Here is the code that runs after you select what you want to filter by and you click the filter button:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim cmbox1 As String
cmbox1 = ComboBox1.Text
MyConn = New OleDbConnection
MyConn.ConnectionString = connString
ds = New DataSet
tables = ds.Tables
da = New OleDbDataAdapter("Select * from HFUtil where service = '" & cmbox1 & "'", MyConn) '
da.Fill(ds, "HFUtil")
Dim view As New DataView(tables(0))
source1.DataSource = view
DataGridView1.DataSource = view
BindingNavigator1.BindingSource = source1
DataGridView1.Refresh()
BindingNavigator1.Refresh()
'=========================================================
ListBox1.Items.Clear()
ListBox1.Text = ""
For Each dr As DataRow In ds.Tables(0).Rows
Dim sItemTemp As String
sItemTemp = String.Format("{0} {1} {2}", dr("freq"), dr("mode"), dr("desc"))
ListBox1.Items.Add(sItemTemp)
Next
ComboBox2.Items.Clear()
ComboBox2.Text = ""
For Each dr As DataRow In ds.Tables(0).Rows
Dim sItemTemp As String
sItemTemp = String.Format("{0} {1} {2}", dr("freq"), dr("mode"), dr("desc"))
ComboBox2.Items.Add(sItemTemp)
Next
End Sub
The only difference between this code and the code that runs on form load is - where clause in the data adapter.
What am I doing wrong?

I don't see in your code where you apply your filter. So, lets pretend for a second that you load your whole table into DataSet. Then next thing, you either use DataSet.DefaultView or create your custom DataView and assign this to DataSource property - you did this.
Now, all you have to do is apply row filter to the data view you use
view.RowFilter = "service = '" & cmbox1 & "'"
At this point you should only see subset of records and nothing should happen to your Id field. Because your data doesn't change.
I have suspicion, you changing your view somewhere and this is why you have problems.

Related

Is paging in DataGridView possible?

Is paging in DataGridView possible in VB.NET?
I've successfully connected to a database and is able to import the data into the DataGrid, but the problem is that the table i have is huge with over 10mil rows. So showing in all in one view is either slowing down the loading time, or if i choose to add more columns of data the application will turn out to be an error.
For example, this line would work
cmd.CommandText = "SELECT primaryTitle, startYear, runtimeMinutes, genres, FROM Basics"
but this line would throw me an error called System.OutOfMemoryException
cmd.CommandText = "SELECT primaryTitle, startYear, runtimeMinutes, genres, directors, writers FROM Basics, Crew"
Any help would be appreciated.
This is my current code. The only thing i've done is importing the data into the DataGridView, nothing more since i can't proceed anymore.
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim con As New SqlClient.SqlConnection
con.ConnectionString = "Data Source=DESKTOP-7SOUE1N\SQLEXPRESS;Initial Catalog=IMDb MOVIE DATABASE SYSTEM;Integrated Security=True"
con.Open()
Dim cmd As New SqlClient.SqlCommand
cmd.Connection = con
cmd.CommandText = "SELECT primaryTitle, startYear, runtimeMinutes, genres, directors, writers FROM Basics, Crew"
Dim rdr As SqlClient.SqlDataReader = cmd.ExecuteReader
Dim dt As New DataTable
dt.Load(rdr)
rdr.Close()
DataGridView1.DataSource = dt
con.Close()
End Sub
End Class
Yes, certainly is. This is how I usually do it.
Prerequisities:
DataGridView DataGridView1
ToolStrip ToolStrip1
TextBox PageNo
Label PageCount
Button btnPageBack
Button btnPageNext
Label TotalShown
Label OutOfTotalRecords
(some labels like "Page", " from ", "Total shown ", " out of ", " records")
Dim RowsPerPage as Int16 = 40 ' set
This is how the ToolStrip bellow DataGridView footer looks in designer:
Fetching or updating the list SQL (wrapped in LoadListOfRecords() sub):
"SELECT
...
ORDER BY " & dgwSortCol & " " & dgwSortOrder & " " &
OFFSET " & ((IIf(Me.PageNo.Text = "", 1, CInt(Me.PageNo.Text)) - 1) * RowsPerPage) & "
ROWS FETCH NEXT " & RowsPerPage & " ROWS ONLY; "
You might skip ORDER at first. But notice OFFSET xx ROWS, which tells where in database it should start to read records (by how many records to offset it from beginning) and FETCH NEXT xx ROWS ONLY, which tells how many rows to read and load to a "page". I skipped stuff like creating DataSet, reading DataTable, assigning it to DataGridView's DataSource and such.
Button Back (I won't put Next, it's nearly identical, just changed limiting condition and iteration):
Private Sub btnPageBack_Click(sender As System.Object, e As System.EventArgs) Handles btnPageBack.Click
If CInt(Me.PageNo.Text) > 1 Then
Me.PageNo.Text = CInt(Me.PageNo.Text) - 1
End If
Call LoadListOfRecords()
End Sub
Manual entry of page number (go to particular page), following Enter key stroke:
Private Sub PageNo_KeyDown(sender As System.Object, e As System.Windows.Forms.KeyEventArgs) Handles PageNo.KeyDown
Call LoadListOfRecords()
End Sub
And that's about it. Simple, easy to use by users, works as charm, proven by time. No clutter of 3rd party controls and libraries.

display data from 1 tablet to 2 filtered datagridview in vb net

I have two datagridview controls and one table. I am trying to display data with one filter on dgv1 and multiple filters on dgv2. Basically what i am asking is dgv 1 should display all customers with a cutdate in the month of july, and dgv2 should display all records for customer john in the month of july. both the dgv's are pulling records from the same table.
my problem is that both of these are displaying the same info.
This is what i have so far.
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
dbprov = "Provider = Microsoft.ACE.OLEDB.12.0;"
dbsource = "Data Source = C:\Users\Sonu\Desktop\VB_Projects\database1.accdb"
sql = "SELECT * FROM T_Cutdata"
sqlDelete = "SELECT * FROM T_DeletedData"
con.ConnectionString = dbprov & dbsource
con.Open()
'MsgBox("Open")
da = New OleDb.OleDbDataAdapter(sql, con)
da.Fill(ds, "lawncutdata")
Dim dv_all As DataView = ds.Tables("lawncutdata").DefaultView
DataGridView1.DataSource = dv_all
dv_all.RowFilter = "cutdate>='07/01/2014' and cutdate<='07/10/2014'"
'"CustomerID = '" + s_customerID +"'"
DataGridView1.DataSource = dv_all
Dim dv_one As DataView = ds.Tables("lawncutdata").DefaultView
dGridOneCustomer.DataSource = dv_one
dv_one.RowFilter = "cutday='" + currentday + "' and customer_name='" + custname + "'"
'"CustomerID = '" + s_customerID +"'"
dGridOneCustomer.DataSource = dv_one
I cannot for the life of me figure out why its doing that. I am thinking that i may need to create a new dataset and bind the second dgv to that dataset. Please help, I am stuck.
Thank you in advance
The problem with your code is, that you are referencing the same objects with dv_all.RowFilter and dv_one.RowFilter.
Using Dim dv_one As DataView = ds.Tables("lawncutdata").Copy().DefaultView for your second DataGridView should do the trick.
You're using the same DataView (the default view of the table) in both grids. All you have to do is create two new data views.
Dim dv_all As New DataView(ds.Tables("lawncutdata"))
Dim dv_one As New DataView(ds.Tables("lawncutdata"))
Note that a data view is a reference type.
Dim dv_all As DataView = ds.Tables("lawncutdata").DefaultView
Dim dv_one As DataView = ds.Tables("lawncutdata").DefaultView
In the above code, both dv_all and dv_one will point to the same instance.

Database not updating new row

Insert new row inside DataGridView
This answer makes it seem like the database should update with the rows.add
Some other sites have instructions, but form a perspective of creating the database from scratch. I already have a database and just want the stupid thing to accept new data.
Here's what I have done:
Private Sub InitializeDataGridView()
Try
' Set up the DataGridView.
With Me.DataGridView1
' Automatically generate the DataGridView columns.
.AutoGenerateColumns = True
' Set up the data source.
'bindingSource1.DataSource = GetData("SELECT * FROM Places and Stuff")
MyTable = GetData("SELECT * FROM Places and Stuff")
'MyDataSet = bindingSource1.DataSource
'MyTable = MyDataSet.Tables(0)
.DataSource = MyTable
' Automatically resize the visible rows.
.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders
' Set the DataGridView control's border.
.BorderStyle = BorderStyle.Fixed3D
' Put the cells in edit mode when user enters them.
.EditMode = DataGridViewEditMode.EditOnEnter
' Disables Add New Row
.AllowUserToAddRows = False
End With
Catch ex As SqlException
MessageBox.Show(ex.ToString, _
"ERROR", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
System.Threading.Thread.CurrentThread.Abort()
End Try
End Sub
I am binding the DGV to a table. It seems like maybe I need a dataset somewhere to update but I cannot figure out how to populate a dataset with a table that is also a sql database. You can also see where I have played around with other datasets/datatables etc.
I also got my datagridview to add a row but the database is being lazy:
Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click
'Determine Last Row Index
Dim dgvrowCnt As Integer = DataGridView1.Rows.Count - 1
If DataGridView1.Rows.Count > 0 Then
Dim myRow As DataRow = MyTable.NewRow
myRow(0) = DataGridView1.Rows(dgvrowCnt).Cells(0).Value + 1
MyTable.Rows.Add(myRow)
Else
Dim myRow As DataRow = MyTable.NewRow
myRow(0) = 230
MyTable.Rows.Add(myRow)
End If
End Sub
I am a little saddened by not being able to use myRow("<column name here>") = 230 but I'll have to get over it I guess.
I have tried refreshing and checking the table to see if my form needs to be refreshed, but that doesn't seem to be the case.
This page http://support.microsoft.com/kb/301248 has 2 lines and claims it does what I am hoping for:
Dim objCommandBuilder As New SwlCammandBuilder(daAuthors)
daAuthors.Update(dsPubs, "Authors")
I cannot get my table into a dataset as shown in the binding lines of my example.
It seems that you haven't understood a fundamental concept of ADO.NET. The DataTable and other objects like the DataSet are 'disconnected' objects, meaning that adding/updating and removing rows doesn't update/insert/delete the database table.
You need to create an SqlCommand, prepare its command text and then Execute a query to update your db (other methods include using an SqlDataAdapter and its Update method)
For example, to insert a single row in a datatable your code should be something like this
Using con = New SqlConnection(.....constringhere...)
Using cmd = new SqlCommand("INSERT INTO table1 (field1) values (#valueForField)", con)
con.Open()
cmd.Parameters.AddWithValue("#valueForField", newValue)
cmd.ExecuteNonQuery()
End Using
End Using
A more complete tutorial could be found here
Instead this could be a pseudocode to use a SqlDataAdapter and a SqlCommandBuilder to automate the construction of the commands required to store your changes back to the database
' Keep the dataset and the adapter at the global class level'
Dim da As SqlDataAdapter = Nothing
Dim ds As DataSet
Private Function GetData(ByVal sqlCommand As String) As DataSet
ds As New DataSet()
Dim connectionString As String = "Data Source=...."
Using con = New SqlConnection(connectionString)
conn.Open()
Using command = New SqlCommand(sqlCommand, con)
Using da = New SqlDataAdapter(command)
da.Fill(ds)
End Using
End Using
End Using
Return ds
End Function
Use the first table inside the DataSet returned by GetData as Datasource of the grid (or just use the whole dataset)
.DataSource = GetData(.......).Tables(0)
' Add a new button to submit changes back to the database'
Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click
Dim builder = New SqlCommandBuilder(da)
da.UpdateCommand = builder.GetUpdateCommand()
da.InsertCommand = builder.GetInsertCommand()
da.DeleteCommand = builder.GetDeleteCommand()
da.Update(ds)
End Sub
Please, note that I cannot test this code, and I offer it as a pseudocode without any error checking required by a more robust application.

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

How do I add htmltablecell data to database after I click submit

I created an htmltable in .aspx.vb, because I have a lot of rows that come from database and they depend on the querystring. that part is fine. But when someone makes a change in one of the cells how do I save data back to database?
Code -
Dim tr As New HtmlTableRow
Dim td As New HtmlTableCell
td = New HtmlTableCell
Dim txtbox1 As New TextBox
txtbox1.ID = "price_" & rd("id")
txtbox1.Text = rd("price")
td.Controls.Add(txtbox1)
tr.Cells.Add(td)
tb1.Rows.Add(tr)
Now when someone changes the price in the textbox, how do I save it in database?
This is code for submit button -
Protected Sub submit_Click(ByVal sender As Object, ByVal e As EventArgs) Handles submit.Click
Dim sqlcnn As SqlConnection = Nothing, sqlstr As String = "", sqlcmd As SqlCommand
sqlstr = "UPDATE ???"
sqlcmd = New SqlCommand(sqlstr, sqlcnn)
sqlcmd.ExecuteScalar()
End Sub
Please answer in detail.
I would suggest using the built in grid controls. Here is a walkthrough Walkthrough: Editing and Inserting Data in Web Pages with the DetailsView Web Server Control
. It might be better to start with Walkthrough: Basic Data Access in Web Pages.
If you choose to move forward with HTML then here is one way to do it based on what you provided. You can add an update button and try this code in that event:
'Create an update Command with the apropriate paramaters'
Dim sql = ("UPDATE SO_Prices SET Price = #Price WHERE ID = #ID")
Dim Cmd As New SqlCommand(sql, connection)
Cmd.Parameters.Add("#Price", SqlDbType.SmallMoney)
Cmd.Parameters.Add("#ID", SqlDbType.Int)
connection.Open()
'Loop through the fields returned'
For Each Key As String In Request.Form.Keys
'Make sure you only process fields you want'
If Key.StartsWith("price") Then
'Pull the ID out of the field name by splitting on the underscore'
' then choosing the second item in the array'
Dim ID As String = Key.Split("_")(1)
'Update the paramaters for the update query'
Cmd.Parameters("#ID").Value = ID
Cmd.Parameters("#Price").Value = Request.Form(Key)
'Run the SQL to update the record'
Cmd.ExecuteNonQuery()
End If
Next
connection.Close()
Let me know if you need any additional assitance. If not, please mark this as the correct answer.