Not able read the next record using datareader - vb.net

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.

Related

Displaying multiple records

Private Sub Line_Change2()
Dim cn As New SqlClient.SqlConnection("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
Dim cmd As New SqlClient.SqlCommand
Dim tbl As New DataTable
Dim da As New SqlClient.SqlDataAdapter
Dim reader As SqlClient.SqlDataReader
Try
cn.Open()
Dim sql As String
sql = "select Id,Payroll_Id,ProductCode,Description,Qty from dbo.SmLine where Payroll_Id ='" + Txt1.Text + "'"
cmd = New SqlClient.SqlCommand(sql, cn)
reader = cmd.ExecuteReader
While reader.Read
TextBox1.Text = reader.Item("Id")
Cmb1.Text = reader.Item("ProductCode")
Des1.Text = reader.Item("Description")
Qty1.Text = reader.Item("Qty")
TextBox2.Text = reader.Item("Id")
Cmb2.Text = reader.Item("ProductCode")
Des2.Text = reader.Item("Description")
Qty2.Text = reader.Item("Qty")
TextBox3.Text = reader.Item("Id")
Cmb3.Text = reader.Item("ProductCode")
Des3.Text = reader.Item("Description")
Qty3.Text = reader.Item("Qty")
End While
cn.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
I am new to vb coding just want to help with displaying multiple rows on multiple textboxes. Above code picks up Payroll Id from a textbox from another table and then it goes through dbo.Smline table below. I want to display the multiple records under the same payroll Id in different textboxes. This code doesn't seem to be working properly.
On your form you have three set of controls. Thus, you are able to display just up to three products for each clicked Payroll_id. Your code inserts the same value in all sets. Change your code to the following:
Private Sub Line_Change2()
ResetControls()
Dim cn As New SqlClient.SqlConnection("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
Using cn
cn.Open()
Dim cmd As New SqlClient.SqlCommand
Dim reader As SqlClient.SqlDataReader
Try
Dim sql As String
sql = "select Id,Payroll_Id,ProductCode,Description,Qty from dbo.SmLine where Payroll_Id ='" + Txt1.Text + "'"
cmd = New SqlClient.SqlCommand(sql, cn)
reader = cmd.ExecuteReader
Dim counter as Integer = 1
While reader.Read
CType(me.Controls.Find("TextBox" + CType(counter,String),False)(0),TextBox).Text = reader.Item("Id").ToString()
CType(me.Controls.Find("Cmb" + CType(counter,String),False)(0),ComboBox).Text = reader.Item("ProductCode").ToString()
CType(me.Controls.Find("Des" + CType(counter,String),False)(0),TextBox).Text = reader.Item("Description").ToString()
CType(me.Controls.Find("Qty" + CType(counter,String),False)(0),TextBox).Text = reader.Item("Qty").ToString()
counter += 1
if counter =3 then Exit While
End While
reader.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Using
End Sub
Public Sub ResetControls()
For counter = 1 to 3
CType(me.Controls.Find("TextBox" + CType(counter,String),False)(0),TextBox).Text = ""
CType(me.Controls.Find("Cmb" + CType(counter,String),False)(0),ComboBox).Text = ""
CType(me.Controls.Find("Des" + CType(counter,String),False)(0),TextBox).Text = ""
CType(me.Controls.Find("Qty" + CType(counter,String),False)(0),TextBox).Text = ""
Next
End Sub
The above code exits the reading when it has more than three products for a Payroll_id, because you just have three sets of controls. But if you could have more than three products for each clicked Payroll_id and you want to display all of them, then you have to build your controls dynamically.

Trouble in displaying an image to datagridview

I'm having a trouble in viewing or displaying an image from the database (mysql) to datagriview
The table in my database that I'm trying to retrieve is named as sample with fields ID = Int(10), primary, auto increment and IMG = blob
Anyone who can help me with this? It will be so much appreciated
Sub getData()
Try
Dim Sql = "Select ID, IMG from sample"
connectionOn()
Dim cmd = New MySqlCommand(Sql, ConOn)
Dim dr = cmd.ExecuteReader(CommandBehavior.CloseConnection)
DataGridView1.Rows.Clear()
While dr.Read = True
Dim mybytearray As Byte() = dr.Item("IMG")
Dim myimage As Image
Dim ms As System.IO.MemoryStream = New System.IO.MemoryStream(mybytearray)
myimage = System.Drawing.Image.FromStream(ms)
DataGridView1.Rows.Add(dr(0), myimage)
End While
ConOn.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Below is my code saving the image in the database. But it doesn't save anything. I want to get the image from the datagrid then save it to the database
Try
connectionSync()
Dim a, b As String
Dim Sql = "INSERT INTO SAMPLE (ID, IMG)values(#a,#b)"
For i As Integer = 0 To Me.DataGridView1.Rows.Count - 1
a = Me.DataGridView1.Rows(i).Cells(0).Value.ToString()
Dim cmd As New MySqlCommand(Sql, ConSync)
Dim memorystream1 As New MemoryStream()
Dim filename As String = DataGridView1.Rows(i).Cells(1).Value
Dim bitmaps As New Bitmap(filename)
bitmaps.Save(memorystream1, Imaging.ImageFormat.Jpeg)
Dim pic() As Byte = memorystream1.GetBuffer()
cmd.Parameters.AddWithValue("#a", a)
cmd.Parameters.AddWithValue("#b", bitmaps)
cmd.ExecuteNonQuery()
cmd.Parameters.Clear()
Next
ConSync.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
Since MySql BLOB Type is used to stored SqlServer IMAGE Type I think you can adapt this code using MySql classes (i.e.: MySqlDataAdapter instead of SqlDataAdapter):
Try
Me.DataGridView1.DataSource = Nothing
Dim dgvID As New DataGridViewTextBoxColumn
dgvID.DataPropertyName = "ID"
Dim dgvIMG As New DataGridViewImageColumn
dgvIMG.DataPropertyName = "IMG"
Me.DataGridView1.Columns.Add(dgvID)
Me.DataGridView1.Columns.Add(dgvIMG)
connectionOn()
Dim cmdSample As SqlCommand = ConOn.CreateCommand
cmdSample.CommandText = "SELECT ID, " _
& "IMG " _
& "FROM Sample"
Dim dtSample As New DataTable
Dim daSample As New SqlDataAdapter(cmdSample)
daSample.Fill(dtSample)
Me.DataGridView1.DataSource = dtSample
ConOn.Close()
ConOn.Dispose()
Catch ex As Exception
MsgBox(ex.Message)
End Try

How to refresh form after selecting value from combobox

I would like to know if it is possible to refresh the current windows form I am at after selecting another value from the combo box in order to display the details of that item onto several other textboxes?
So my table looks like
table name : program
program_id program_name program_desc
1 T1 desc1
This is the code i am using atm
Dim connection As New SqlClient.SqlConnection
connection.ConnectionString = "pathway"
Dim dr As SqlDataReader
Dim prognamedesc As String
Dim filetypetxt As String
Dim prognamecombo As String
Dim filetypecombo1 As String
Dim command As New SqlCommand
Dim querycommand As New SqlCommand
connection.Open()
'THIS SECTION LOADS DATA FROM THE TABLES'
Try
command.Connection = connection
command.CommandType = CommandType.Text
command.CommandText = "select program_name,filetype from program order by program_name; select * from filetype"
querycommand.Connection = connection
querycommand.CommandType = CommandType.Text
querycommand.CommandText = "select program_name,program_desc , filetype from program where program_name like" & FiletypeComboBox1.SelectedItem & ""
dr = command.ExecuteReader
While dr.Read()
prognamecombo = dr(0)
Program_nameComboBox.Items.Add(prognamecombo)
End While
dr.NextResult()
While dr.Read()
filetypecombo1 = dr(0)
FiletypeComboBox1.Items.Add(filetypecombo1)
FiletypeComboBox1.SelectedItem = filetypecombo1
End While
dr.NextResult()
While dr.Read()
filetypetxt = dr(0)
FiletypeLabel1.Text = filetypetxt
End While
dr.NextResult()
While dr.Read()
prognamedesc = dr(0)
Program_descTextBox.Text = prognamedesc
End While
Catch ex As Exception
MsgBox(ex.Message)
End Try
connection.Close()
I was wondering if this is doable using the current code?
To implement this you have to do two things, First put all your code inside a method and call it something like RefreshForm()
public void RefreshForm()
{
// your code and binding goes here
}
The second step is by using selected index changed event over combobox you just call the method that includes all your binding code.

Populate ListBox from SQL only items with condition (first character)

I've managed to put all items in a ListBox, also have the first character defined kto, how to insert only those values from List column into Listbox that begin with that character kto.
Just to mention that kto is value from 0 to 9, always a number.
Dim SqlSb As New SqlConnectionStringBuilder()
SqlSb.DataSource = ".\sqlexpress"
SqlSb.InitialCatalog = "Konta"
SqlSb.IntegratedSecurity = True
Using SqlConn As SqlConnection = New SqlConnection(SqlSb.ConnectionString)
SqlConn.Open()
Dim cmd As SqlCommand = SqlConn.CreateCommand()
cmd.CommandText = "SELECT List FROM Konta"
Dim kto = Left(Label1.Text, 1)
'Label3.Text = kto
Using reader As SqlDataReader = cmd.ExecuteReader
While (reader.Read())
Me.ListBox1.Items.Add(reader("LIST"))
End While
End Using
SqlConn.Close()
End Using
Try this
Dim SqlSb As New SqlConnectionStringBuilder()
SqlSb.DataSource = ".\sqlexpress"
SqlSb.InitialCatalog = "Konta"
SqlSb.IntegratedSecurity = True
Using SqlConn As SqlConnection = New SqlConnection(SqlSb.ConnectionString)
SqlConn.Open()
Dim cmd As SqlCommand = SqlConn.CreateCommand()
Dim kto = Left(Label1.Text, 1)
cmd.CommandText = "SELECT List FROM Konta WHERE List LIKE '" & kto.toString & "%'"
ListBox1.Items.Clear
Using reader As SqlDataReader = cmd.ExecuteReader
While (reader.Read())
Me.ListBox1.Items.Add(reader("LIST"))
End While
End Using
SqlConn.Close()
End Using
In your while loop, before adding the item in the listbox check the date type of reader("LIST") and add it only if matches the required type.
You can check the type using the following code:
reader.GetFieldType(0)

ExecuteNonQuery inside of Reader

How can I solve this problem? I do not want to use two connections.
ExecuteNonQuery only works if reader is closed.
oleCnn = New System.Data.OleDb.OleDbConnection
oleCnn.ConnectionString = ConnectionString
oleCmm = New OleDb.OleDbCommand()
oleCnn.Open()
oleStr = "SELECT ID_Process FROM MyProcessTable"
Dim reader As System.Data.OleDb.OleDbDataReader = oleCmm.ExecuteReader()
While reader.Read()
For i = 1 To NumExecutions
oleStr = "INSERT INTO MyOtherProcessTable(reader.getInt32(0))"
oleCmm.ExecuteNonQuery()
Next
End While
reader.Close()
oleCnn.Close()
Thank you
Use a list to store your IDs while reading the DataReader, then for each element of the list you should be able to execute your query with then same connection:
oleCnn = New System.Data.OleDb.OleDbConnection
oleCnn.ConnectionString = ConnectionString
oleCmm = New OleDb.OleDbCommand()
oleCnn.Open()
oleStr = "SELECT ID_Process FROM MyProcessTable"
Dim ids As New List(Of Integer)
Dim reader As System.Data.OleDb.OleDbDataReader = oleCmm.ExecuteReader()
While reader.Read()
ids.Add(reader.GetInt32(0))
End While
reader.Close()
For Each curr_id As Integer In ids
For i = 1 To NumExecutions
oleStr = "INSERT INTO MyOtherProcessTable(" & curr_id.ToString & ")"
oleCmm.ExecuteNonQuery()
Next
Next
oleCnn.Close()
P.S. I don't understand the For i = 1 To NumExecutions for loop, but I added it as you wrote it