Access database too slow populating DatagridView - vb.net

I have an app with several datagridviews, and now, with more than 260 rows, my datagrid is too slow filling up, I don't know how I can lower the time.
Here is my codes:
Public cs As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & Application.StartupPath & "\BD_Estaleiro.accdb"
Public con As New OleDbConnection(cs)
Public cmd As OleDbCommand
Public dr As OleDbDataReader
Public query As String
Reader Function:
Public Function executar_query_Reader(ByVal Instrucao As String) As OleDb.OleDbDataReader
Dim datareader As OleDbDataReader = Nothing
cmd = New OleDbCommand(Instrucao, con)
Try
If con.State = ConnectionState.Open Then
con.Close()
End If
con.Open()
datareader = cmd.ExecuteReader
Catch ex As Exception
MessageBox.Show(ex.Message) 'mensagem de erro, se aplicavel
Finally
End Try
Return datareader 'retornar os dados atraves da variavel datareader
End Function
Populating the Datagrid:
Public Sub carregar_saidas(ByVal DG As DataGridView)
n_rows = 0
DG.Rows.Clear()
query = "Select * from tbl_saidas as s, tbl_produtos as p Where s.Produto=p.Produto Order By s.Data DESC"
dr = executar_query_Reader(query)
While dr.Read
n_rows += 1
Dim n As Integer = DG.Rows.Add()
DG.Rows.Item(n).Cells(0).Value = dr("ID")
DG.Rows.Item(n).Cells(1).Value = dr("s.Produto")
DG.Rows.Item(n).Cells(2).Value = dr("s.Quantidade")
DG.Rows.Item(n).Cells(3).Value = dr("Unidade")
DG.Rows.Item(n).Cells(4).Value = dr("Obra")
DG.Rows.Item(n).Cells(5).Value = Format(dr("Data"), "dd/MM/yyyy")
DG.Rows.Item(n).Cells(6).Value = Format$(CSng(dr("Valor_uni")), "###,####,##0.00") & " €"
DG.Rows.Item(n).Cells(7).Value = Format$(CSng(dr("Total")), "###,####,##0.00") & " €"
End While
con.Close()
End Sub
Thanks for any help

Rather than adding individual Rows and Columns, you want to bind to the grid:
Public Sub carregar_saidas(ByVal DG As DataGridView)
Dim query As String = "Select * from tbl_saidas as s, tbl_produtos as p Where s.Produto=p.Produto Order By s.Data DESC"
Dim dr As OleDbDataReader = executar_query_Reader(query)
DG.DataSource = dr
End Sub
You'll need to have defined the columns on DataGridView to map the fields in the data reader.
You should also look into modifying the executar_query_Reader() method to support parameterized queries.

Related

I want a quick solution about adding a new row to datagraidview

I have a DataGridView and I'm adding a new row. But, when I add the new row it deletes the current row and replaces it.
This is the code
Try
con = New SqlConnection(cs)
con.Open()
cmd = New SqlCommand("SELECT ItemID, RTRIM(DishName),'1',Rate from Dish where ItemID like '" & TextBox1.Text & "' order by DishName", con)
rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection)
DataGridView1.Rows.Clear()
While (rdr.Read() = True)
DataGridView1.Rows.Add(rdr(0), rdr(1), rdr(2), rdr(3))
Dim num1 As Double
num1 = Val(DataGridView1.Rows(0).Cells("Qty").Value) * Val(DataGridView1.Rows(0).Cells("Rate").Value)
num1 = Math.Round(num1, 2)
DataGridView1.Rows(0).Cells("Amount").Value = num1
End While
TotalCalc()
Compute()
con.Close()
Catch ex As Exception
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
I am having a little problem following your question
Suggestion Don't tell us you want a quick solution
If you are changing the value in the DB use Update
Here is some code to add values to a DataGridView with SQLite
The SELECT statement is a little odd due to another issue in my Project
Just use your SELECT also Welcome to Stackoverflow
Private Sub ViewSearches()
Dim intID As Integer
Dim strCodeDesc As String
Dim strUIProject As String
Dim strCodeType As String
Dim rowCount As Integer
Dim maxRowCount As Integer
Using conn As New SQLiteConnection($"Data Source = '{gv_dbName}';Version=3;")
conn.Open()
Using cmd As New SQLiteCommand("", conn)
If gvTxType = "View" Then
cmd.CommandText = "SELECT * FROM CodeTable WHERE cvCodeType = #site"
cmd.Parameters.Add("#site", DbType.String).Value = gvSCT
ElseIf gvTxType = "All" Then
cmd.CommandText = "SELECT * FROM CodeTable"
End If
Using rdr As SQLite.SQLiteDataReader = cmd.ExecuteReader
While rdr.Read()
intID = CInt((rdr("CID")))
strCodeDesc = rdr("cvCodeDesc").ToString
strUIProject = rdr("cvUIProject").ToString
strCodeType = rdr("cvCodeType").ToString
dgvSelCode.Rows.Add(intID, strCodeDesc, strUIProject, strCodeType)
rowCount += 1
End While
dgvSelCode.Sort(dgvSelCode.Columns(3), ListSortDirection.Ascending)
End Using
If rowCount <= 12 Then
maxRowCount = 12 - rowCount
For iA = 1 To maxRowCount
dgvSelCode.Rows.Add(" ")
Next
End If
End Using
End Using
End Sub

how to insert multiple records in Access database using VB.NET

I am trying learn how to use Access within VB.NET so i tried to make a simple application using an Access Database that can be used as a dictionary where someone can add some words int the database and then he can search for them.
My db contains two tables one with Word | Description and another one with Word | Synonym
The issue is that one word may have more than one Synonyms so i was thinking i could type all the synonyms in a textbox and using Regex.Split(" ") to split them and insert them in a loop. Can this be done with OleDbParameters?
This is what i have done so far but it only inserts the last record:
str = "insert into Synonyms ([Word],[Synonym]) values (#word,#synonym)"
cmd = New OleDbCommand(str, myConnection)
cmd.Parameters.Add(New OleDbParameter("Word", CType(txtWord.Text,
String)))
cmd.Parameters.Add("#synonym", OleDbType.VarChar)
Dim syn As String() = Regex.Split(txtSynonyms.Text, " ")
Dim i As Integer = 0
While i < syn.Length()
cmd.Parameters("#synonym").Value = syn(i)
i = i + 1
End While
Try
cmd.ExecuteNonQuery()
cmd.Dispose()
MsgBox("Synonyms for word """ & txtWord.Text & """ added")
txtWord.Clear()
txtSynonyms.Clear()
Catch ex As Exception
MsgBox(ex.Message)
End Try
myConnection.Open()
While i < syn.Length()
cmd.Parameters("#synonym").Value = syn(i)
cmd.ExecuteNonQuery()
i = i + 1
End While
myConnection.Close()
Maybe you will find this helpful.
Imports System.Data.OleDb
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim con As New OleDb.OleDbConnection
Dim dbprovider As String
Dim dbsource As String
Dim ds As New DataSet
Dim da As OleDb.OleDbDataAdapter
Dim sql As String
Dim inc As Integer
dbprovider = "Provider=Microsoft.ACE.OLEDB.12.0;"
dbsource = "Data Source = C:\your_path_here\Nwind_Sample.accdb"
con.ConnectionString = dbprovider & dbsource
con.Open()
sql = "SELECT * FROM [OrderDetails]"
da = New OleDb.OleDbDataAdapter(sql, con)
da.Fill(ds, "OrderDetails")
Dim builder As New OleDbCommandBuilder(da)
Dim dsnewrow As DataRow
dsnewrow = ds.Tables("OrderDetails").NewRow()
dsnewrow.Item(0) = OrderID.Text
dsnewrow.Item(1) = ProductID.Text
dsnewrow.Item(2) = UnitPrice.Text
dsnewrow.Item(3) = Quantity.Text
dsnewrow.Item(4) = Discount.Text
'dsnewrow.Item(6) = True
ds.Tables("OrderDetails").Rows.Add(dsnewrow)
da.Update(ds, "OrderDetails")
End Sub
End Class

datagridview not showing the first row vb.net

hi so i have this list that im currently using on a combobox that's why i have the idcategoria = 0 with the nomeCategoria = "Select your Category"so the combobox default item would be "select your category".
here is the code of the list
Public Shared Function ObterTodosC() As List(Of Ccategoria)
Dim lstTodos As List(Of Ccategoria) = New List(Of Ccategoria)
Dim p As Ccategoria = New Ccategoria()
p.IdCategoria = 0
p.NomeCategoria = "select your category"
lstTodos.Add(p)
Try
Using con As SqlConnection = New SqlConnection()
con.ConnectionString = myDAC._connectionString
Using cmd As SqlCommand = con.CreateCommand()
cmd.CommandText = "select * from Categoria"
con.Open()
Dim dr As SqlDataReader = cmd.ExecuteReader()
While dr.Read()
Dim p As Ccategoria = New Ccategoria()
p.IdCategoria = dr.GetInt32(0)
p.NomeCategoria = dr.GetString(1)
lstTodos.Add(p)
End While
End Using
End Using
Catch ex As SqlException
Throw ex
Catch ex As Exception
Throw ex
End Try
Return lstTodos
End Function
Now i want to use the same list on a datagridview and i wanted to know if there is a way to not show the id = 0 on the datagridview or do i have to create another list without the idCategorie = 0 for the datagridview, any ideas on this? thanks
Create another list from already loaded
Dim newList = lstTodos.Skip(1).ToList()
Skip method will return new collection without first item.
Notice that this approach will work only when - Select your Category - item is a first item in the list.
Or change your method to return list without - Select your Category - item and add it only when you need.
Public Shared Iterator Function ObterTodosC() As IEnumerable(Of Ccategoria)
Using con As SqlConnection = New SqlConnection()
con.ConnectionString = myDAC._connectionString
Using cmd As SqlCommand = con.CreateCommand()
cmd.CommandText = "select * from Categoria"
con.Open()
Dim reader As SqlDataReader = cmd.ExecuteReader()
While reader.Read()
Yield New Ccategoria With
{
.IdCategoria = reader.GetInt32(0),
.NomeCategoria = reader.GetString(1)
}
End While
End Using
End Using
End Function
Then you can create list of categories for datagridview
Dim forDataGridView = ObterTodosC().ToList()
Dim notSelectedCategory As New Ccategoria With
{
.IdCategoria = 0,
.NomeCategoria = "select your category"
}
Dim forComboBox = forDataGridView.ToList()
forComboBox.Insert(0, notSelectedCategory)
With this approach your remove side effect from ObterTodosC method.
So method responsibility will be only load items from database

How to add dynamic Data in to the datagridviewcombobox column?

I am Developing VB.net application.
In that application I take DataGirdView to display data.
I took DataSource property of the datagridview to display 3 columns' data directly from database.
After those columns I add another DataGridViewComboBoxColumn. Then I a want to add dynamic the data into that ComboBoxColumn.
how to do this?
Private Function CreatComboBoxWithEnum() As DataGridViewComboBoxColumn
Dim combo As New DataGridViewComboBoxColumn()
Sqlconn = New SqlConnection
Sqlconn.ConnectionString = "server=.\SQLEXPRESS_2005;Initial Catalog=MachineShopScheduling ;Integrated Security=SSPI;"
Dim adpter As New SqlDataAdapter
Dim ds As New DataTable
Try
Sqlconn.Open()
Dim Query As String
For Each dr As DataGridViewRow In DataGridView1.Rows
Dim val As String = dr.Cells("SrDataGridViewTextBoxColumn").Value.ToString
Query = "select OperationNo from RoutingCalculation where Sr ='" & val & "' "
COMMAND = New SqlCommand(Query, Sqlconn)
adpter.SelectCommand = COMMAND
adpter.Fill(ds)
combo.DataSource = ds
combo.DataPropertyName = "OperationNo"
combo.Name = "OperationNo"
OperationNo.ValueMember = "OperationNo"
OperationNo.DisplayMember = "OperationNo"
Next
Sqlconn.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
Return combo
End Function
Private Sub load_operationNo()
Sqlconn = New SqlConnection
Sqlconn.ConnectionString = "server=.\SQLEXPRESS_2005;Initial Catalog=MachineShopScheduling ;Integrated Security=SSPI;"
Try
op.Name = "OperationNo"
DataGridView1.Columns.Add(op)
Sqlconn.Open()
Dim Query As String
Dim i As Integer = 0
For Each dr As DataGridViewRow In DataGridView1.Rows
Dim OPno As New DataGridViewComboBoxCell
With OPno
Dim adpter As New SqlDataAdapter
Dim dt As New DataTable
Dim val As String = dr.Cells("SrDataGridViewTextBoxColumn").Value.ToString
Query = "select OperationNo from RoutingCalculation where Sr = " & val & " order by sr"
Using cmd As New SqlCommand(Query, Sqlconn)
adpter.SelectCommand = cmd
adpter.Fill(dt)
End Using
.DataSource = dt
.ValueMember = "OperationNo"
.DisplayMember = "OperationNo"
DataGridView1.Rows(i).Cells("OperationNo") = OPno
i = i + 1
End With
Next
Sqlconn.Close()
Catch ex As Exception
'MessageBox.Show(ex.Message)
End Try
End Sub
This is the code to add dynamically add the data into DatagridViewComboboxColumn

Not able read the next record using datareader

I want to retrieve data from multiple tables and want to generate a crystal report. Hence i have created a new table and inserting values in it each time i need to generate the report. So i am using the following code to retrieve the data from those tables.
Code:
Private Sub gen_Report()
Dim dr, dr1, dr2 As OleDb.OleDbDataReader
Dim cmd, cmdDel, comm_inv1, comm_invuser As OleDb.OleDbCommand
If cnnOLEDB.State = ConnectionState.Closed Then
cnnOLEDB.Open()
End If
Dim strDelInsRp As String = ("DELETE FROM Inst_Report")
cmdDel = New OleDb.OleDbCommand(strDelInsRp, cnnOLEDB)
cmdDel.Parameters.AddWithValue("#chlno", cmbChal_no.Text)
cmdDel.ExecuteNonQuery()
Dim strSelIns As String = ("SELECT * FROM Installation_det where Chalan_No=#chlno")
cmd = New OleDb.OleDbCommand(strSelIns, cnnOLEDB)
cmd.Parameters.AddWithValue("#chlno", cmbChal_no.Text)
dr = cmd.ExecuteReader
Try
Do While dr.Read = True
mach_srno = dr("Machine_SrNo")
tft_srno = dr("TFT_SrNo")
chl_no = dr("Chalan_No")
usernm = dr("User_Name")
ins_dt = dr("Date_Of_Installation")
war_perd = dr("Warranty_Period")
war_till = dr("Warranty_Valid_Till")
Dim strSelInv1 As String = ("SELECT * FROM INVOICE_ONE where LAY_NO='VDC' AND CHL_NO=#chn_no ")
comm_inv1 = New OleDb.OleDbCommand(strSelInv1, cnnOLEDB)
comm_inv1.Parameters.AddWithValue("#chn_no", chl_no)
dr1 = comm_inv1.ExecuteReader
If dr1.Read = True Then
doc_no = dr1("DOCU_NO")
code_no = dr1("CODE_NO")
memb_nm = dr1("MEMB_NM")
Dim strSelInvUser As String = ("SELECT * FROM INVOICE_USER where CODE_NO=#code AND LAY_NO='VDC' AND DOCU_NO=#docno")
comm_invuser = New OleDb.OleDbCommand(strSelInvUser, cnnOLEDB)
comm_invuser.Parameters.AddWithValue("#code", code_no)
comm_invuser.Parameters.AddWithValue("#docno", doc_no)
dr2 = comm_invuser.ExecuteReader
If dr2.Read = True Then
User_add = dr2("ILEN2") & dr2("ILEN3") & dr2("ILEN4") & dr2("ILEN5")
End If
dr2.Close()
End If
dr1.Close()
Dim strInsRep As String = "INSERT INTO Inst_Report(Mach_srNo,TFT_srNo,Mem_nm,UserNm,Dt_Inst,War_Per,war_till,User_Address) VALUES (#mach_srno,#tft_no,#mem_nm,#uname,#inst_dt,#war_per,#war_till,#address)"
Dim comm_InsRep As OleDb.OleDbCommand = New OleDb.OleDbCommand(strInsRep, cnnOLEDB)
comm_InsRep.Parameters.AddWithValue("#mach_srno", mach_srno)
comm_InsRep.Parameters.AddWithValue("#tft_no", tft_srno)
comm_InsRep.Parameters.AddWithValue("#mem_nm", memb_nm)
comm_InsRep.Parameters.AddWithValue("#uname", usernm)
comm_InsRep.Parameters.AddWithValue("#inst_dt", ins_dt)
comm_InsRep.Parameters.AddWithValue("#war_per", war_perd)
comm_InsRep.Parameters.AddWithValue("#war_till", war_till)
comm_InsRep.Parameters.AddWithValue("#address", User_add)
comm_InsRep.ExecuteNonQuery()
Loop
dr.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
But the problem is that the datareader only reads for the first record even if I am using 'do While Loop'.
I have another question:
As the number of fields are more I want to generate report in Landscape orientation.
So how to change the orientation of report.
I am using Visual studio 2005 and MS-Access 2007. And programming language is VB.NET.
Regarding your data, I believe the standard way to get data from an OleDbDataReader is to use it to fill a datatable, try this:
Private Function GetDataTableUsingDataReader(ByVal command As OleDbCommand) As DataTable
Dim dataTable As DataTable = New DataTable
Using reader As OleDbDataReader = command.ExecuteReader
dataTable.Load(reader, LoadOption.OverwriteChanges)
End Using
Return dataTable
End Function
To get your crystal report to landscape, right click on the report in the designer, goto design => page setup. From here you can change the orientation.