Thread Freezes Loading Data via Backgroundworker - vb.net

The following code seems to freeze my thread when executing, which defeats the purpose of a progress which I'd like to add. Is there something I need to adjust to eliminate this? My assumption is that it has something to do with the shear amount of fields in the data I'm loading, in this particular example it's well over 150 fields (header row and 1 data row).
Private Sub BackgroundWorker1_DoWork(sender As Object, e As ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim file As String = "<<file>>"
Dim path As String = "<<path>>"
Dim ConStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='<<source>>';Extended Properties='text';"
Dim SQL = "SELECT * FROM " & path & file
tbl = New DataTable
' USING will close and dispose of resources
Using cn As New OleDbConnection(ConStr),
cmd As New OleDbCommand(SQL, cn)
cn.Open()
Using da As New OleDbDataAdapter(cmd)
da.Fill(tbl)
End Using
End Using ' close and dispose
' FIND the sequence column for this session
For n = 0 To tbl.Columns.Count - 1
If tbl.Columns(n).ColumnName.ToLowerInvariant = "sequence" Then
SeqColIndex = n
Exit For
End If
Next
End Sub

Related

Duplicate bindings error when trying to go to next row in DB

I am new to this whole binding thing but basically when i press next button on my form it is meant to scroll through my database displaying each row but the code i will supply below is just a temp as i want to make sure it all works before adding more code to it.
When i load the section i have it so it preloads the first row into my form so when you press next it will bring you to row 2 and next again will bring you to row 3 etc but when i hit next to go to row 3 from row 2 i receive the error: This causes two bindings in the collection to bind to the same property.
Code:
Private Sub click()
sql = "Select * from tbl"
Using dbcon As New OleDbConnection(ACEConnStr)
Using cmd As New OleDbCommand(sql, dbcon)
dbcon.Open()
dtSample = New DataTable
dtSample.Load(cmd.ExecuteReader)
End Using
End Using
' initialize BS from DT
bsSample = New BindingSource(dtSample, Nothing)
TxtCI.DataBindings.Add("Text", bsSample, "CustomerID")
End Sub
Next button:
Private Sub BtnNext_Click(sender As Object, e As EventArgs) Handles BtnNext.Click
click()
DataBindings.Clear()
bsSample.MoveNext()
BtnNext.Enabled = (bsSample.Count - 1 > bsSample.Position)
End Sub
This code block:
Private Sub nclick()
sql = "Select * from tblcustomer"
Using dbcon As New OleDbConnection(ACEConnStr)
Using cmd As New OleDbCommand(sql, dbcon)
dbcon.Open()
dtSample = New DataTable
dtSample.Load(cmd.ExecuteReader)
End Using
End Using
' initialize BS from DT
bsSample = New BindingSource(dtSample, Nothing)
TxtCI.DataBindings.Add("Text", bsSample, "CustomerID")
TxtName.DataBindings.Add("Text", bsSample, "Title")
ChkSales.DataBindings.Add("Checked", bsSample, "SalesCustomer")
End Sub
...needs to run once, but only once. Move the whole lot of it to the form load. Then:
Private Sub BtnNext_Click...
bsSample.MoveNext()
BtnNext.Enabled = (bsSample.Count - 1 > bsSample.Position)
End Sub
I am not sure if this is a Find dialog or what, but it should be noted that the DataTable for all customers can have application-wide uses - such as checking if customer #30 exists before trying to delete them.

VB.net Query wont retrieve data from access database

I have created a query using vb.net with parameters which should allow the query to retrieve data from my access database but however when I click on the button it only shows blank fields but no rows are retrieved from the database. Could you please help me what I am currently doing wrong.
Imports System.Data.OleDb
Public Class RouteToCruise
Private Sub RouteToCruise_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Route_Btn_Click(sender As Object, e As EventArgs) Handles Route_Btn.Click
Try
Dim row As String
Dim connectString As String = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\DeepBlueTables.mdb"
Dim cn As OleDbConnection = New OleDbConnection(connectString)
cn.Open()
Dim CruiseQuery As String = "SELECT Route.RouteName + ', ' + Cruise.CruiseID As CruiseRoute FROM Route INNER JOIN Cruise ON Route.RouteID = Cruise.RouteID WHERE CruiseID = ?"
Dim cmd As New OleDbCommand(CruiseQuery, cn)
'cmd.Parameters.AddWithValue("CruiseID", OleDbType.Numeric).Value = Route_Txt.Text
cmd.Parameters.AddWithValue(("CruiseID"), OleDbType.Numeric)
Dim reader As OleDbDataReader = cmd.ExecuteReader
'RCTable.Width = Unit.Percentage(90.0)
RCTable.ColumnCount = 2
RCTable.Rows.Add()
RCTable.Columns(0).Name = "CruiseID"
RCTable.Columns(1).Name = "RouteName"
While reader.Read
Dim rID As String = reader("RouteID").ToString()
cmd.Parameters.AddWithValue("?", rID)
row = reader("CruiseID") & "," & ("RouteName")
RCTable.Rows.Add(row)
End While
reader.Close()
cn.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
End Class
If the user enters route name in the text box then the rows should show cruise ID and route name for each of the selected routes. for example if users enters Asia in the text box, clicks on the button then the query should return the cruiseID for the cruises which are going to Asia.
Your use of parameters makes no sense. First you call AddWithValue and provide no value, then you execute the query and then you start adding more parameters as you read the data. Either you call AddWithValue and provide a value, or you call Add and then set the Value on the parameter object created. Either way, it MUST be before you execute the query or it's useless.
myCommand.Parameters.AddWithValue("#ParameterName", parameterValue)
or
Dim myParameter = myCommand.Parameters.Add("#ParameterName", OleDbType.Numeric)
myParameter.Value = parameterValue

Data binding to Textboxes

Dim myconn As New SqlConnection("Server=server,Trusted_Connection=True,Database=database")
'selects from mt table linking the current pc to a row
Dim sql As String = "SELECT * from idset " & vbcrlf &
"Where pcname= '" & pcname & "'"
Dim ds As New DataSet
Dim da As New SqlDataAdapter(sql, myconn)
da.Fill(ds, "Setup")
txtClientID.DataBindings.Add("text", ds.Tables("idset"), "CLID")
I don't know why its not working for some reason its not filling the data set did I declare something wrong?
The reason why it don't work is because you specify that the incoming table should be mapped to a table named Setup. Your data set doesn't contain a table named Setup, so the incoming table will be named... well, Setup.
Try this instead:
da.Fill(ds, "idset")
Also, I strongly suggest you:
Set option strict on
Always use parameterized/prepared SQL queries.
Always use the Using statement when working with disposable objects.
Seriously.
The best way to debug bindings is to use a BindingSource and handle the BindingComplete event.
Private bs As BindingSource
Private ds As DataSet
Private Sub Initialize(pcname As String)
Me.ds = New DataSet()
Using connection As New SqlConnection("Server=server,Trusted_Connection=True,Database=database")
connection.Open()
Using command As New SqlCommand()
command.Connection = connection
command.CommandText = "SELECT * from [idset] Where [pcname] = #pcname;"
command.Parameters.AddWithValue("#pcname", pcname)
Using adapter As New SqlDataAdapter(command)
adapter.Fill(Me.ds, "idset")
End Using
End Using
End Using
Me.bs = New BindingSource(Me.ds, "idset")
AddHandler bs.BindingComplete, AddressOf Me.HandleBindingCompleted
Me.txtClientID.DataBindings.Add("Text", Me.bs, "CLID")
End Sub
Private Sub HandleBindingCompleted(sender As Object, e As BindingCompleteEventArgs)
If (Not e.Exception Is Nothing) Then
Debug.WriteLine(e.ErrorText)
End If
End Sub

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.

Update a Single cell of a database table in VB.net

I am using MS Access Database. Now I have to update a particular cell value. Here is my code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim str As String
Dim Presc As New System.Text.StringBuilder
Dim prs As String(), j As Integer
prs = Split(txtPrescription.Text, vbCrLf)
For j = 0 To prs.Length - 1
Presc.Append(prs(j))
Presc.Append(",")
Next
Try
str = Trim(lsvCase.SelectedItems(0).Text)
'MessageBox.Show(str)
Dim con As System.Data.OleDb.OleDbConnection
Dim ds As New DataSet
Dim rea As System.Data.OleDb.OleDbDataReader
con = New OleDb.OleDbConnection
Dim da As New System.Data.OleDb.OleDbDataAdapter
con.ConnectionString = "Provider = Microsoft.ACE.OLEDB.12.0; Data Source= F:\Sowmya Laptop Backups\sowdb1.accdb;"
con.Open()
Dim cmd As OleDb.OleDbCommand = con.CreateCommand
cmd.CommandText = "UPDATE Casehistory set Prescription =' " & Presc.ToString() & "'"
rea = cmd.ExecuteReader
cmd.ExecuteNonQuery()
da.FillSchema(ds, SchemaType.Mapped)
da.Update(ds, "Casehistory")
con.Close()
Catch ex As Exception
Finally
End Try
End Sub
This code updates all the cells in that column. I want to update only the particular cell having Case_ID = str
Where I have to add the WHERE clause (WHERE Case_ID = " & str & "
I would use command parameters, neater and prevents the SQL injection issue. Something like:
cmd.CommandText = "UPDATE Casehistory set Prescription =#Presc WHERE Case_ID = #CaseID"
cmd.Parameters.AddWithValue("#Presc", Presc.ToString())
cmd.Parameters.AddWithValue("#CaseID",str)
As an aside, having all this code in the button click event is less than ideal. You might want to investigate structuring your app in a more maintainable way - perhaps with a Data Layer for example.
The Where clause should be appended to the end of the OleDbCommmand.CommandText, where you define the Update statement.