I created a dataset which contains a table from my SQL Database named "BillHeaders"
Here's what my report viewer looks like, it will contain two reports. One that holds a job number and description, the other that holds a job number, description and contract number.
Here are my buttons that will execute either report
Here are my reports in my "Reports" folder. Both constructed and ready to go.
Unfortuantely when I use this code (respectively for each button):
Private Sub btnJobNoDesc_Click(sender As System.Object, e As System.EventArgs) Handles btnJobNoDesc.Click
'Reset the viewer
frmReportViewer.ReportViewer1.Reset()
'Dim the required datasources. Need a seperate ReportDatasource for each table in the report
Dim ReportDataSource1 As Microsoft.Reporting.WinForms.ReportDataSource = New Microsoft.Reporting.WinForms.ReportDataSource
'Give datasource name and set the specific datatables
ReportDataSource1.Name = "dsBillHeaders_BillHeaders"
ReportDataSource1.Value = frmReportViewer.dsBillHeaders.BillHeaders
'Clear the datasources in the report and add the new ones
frmReportViewer.ReportViewer1.LocalReport.DataSources.Clear()
frmReportViewer.ReportViewer1.LocalReport.DataSources.Add(ReportDataSource1)
frmReportViewer.ReportViewer1.LocalReport.ReportEmbeddedResource = "ReportViewer_Tutorial.rptJobNoDesc.rdlc"
frmReportViewer.ReportViewer1.RefreshReport()
frmReportViewer.Show()
End Sub
I get this result:
What am I doing wrong with my datasource?
For one you are not setting the processing mode to local
Here is code that works, when I create the report I make sure to have the datasource name in the report correspond to the table name of my dataset, not sure if that is required but it keeps things simpler.
_reportViewerNewContracts.ProcessingMode = Microsoft.Reporting.WinForms.ProcessingMode.Local
_reportViewerNewContracts.LocalReport.ReportPath = "Reports\NewContractsReport.rdlc"
Dim reportDataSource1 As New Microsoft.Reporting.WinForms.ReportDataSource()
reportDataSource1.Name = _contractDataset.NewContracts.TableName
'Name of the report dataset in our .RDLC file
reportDataSource1.Value = _contractDataset.NewContracts
Me._reportViewerNewContracts.LocalReport.DataSources.Add(reportDataSource1)
'fill data
_reportViewerNewContracts.RefreshReport()
(I have seen lots of sites that recommend the datasetname underscore tablename but that never worked for me)
Here's what I figured out:
Private Sub btnJobNoDesc_Click(sender As System.Object, e As System.EventArgs) Handles btnJobNoDesc.Click
'Reset the form
Dim rv As New frmReportViewer
'Reset the viewer
rv.ReportViewer1.Reset()
Dim ds As New dsBillHeaders
Dim ta As New dsBillHeadersTableAdapters.BillHeadersTableAdapter
ta.Fill(ds.BillHeaders)
rv.ReportViewer1.LocalReport.ReportEmbeddedResource = "ReportViewer_Tutorial.rptJobNoDesc.rdlc"
rv.ReportViewer1.LocalReport.DataSources.Clear()
Dim sReportDataSource As ReportDataSource
sReportDataSource = New ReportDataSource()
sReportDataSource.Name = "dsBillHeaders"
sReportDataSource.Value = ds.BillHeaders
rv.ReportViewer1.LocalReport.DataSources.Add(sReportDataSource)
rv.ReportViewer1.RefreshReport()
rv.Show()
End Sub
Using this code, I can generate multiple forms just by changing the name of the report on the ReportEmbeddedResource, sReportDataSource.Value and the dataset if necessary.
Related
I am trying to user ReportViewer to run a report with a dataset filled from a datagridview. I can populate the dataset but I when I run the report, it's only showing the first row. I have done countless hours of searching on this and nothing seems to work.
I have make sure =First(...) was removed from my report field expression
I think the problem has something to do with the XML for the dataset but I am not very familiar with it.
This is just an example, once I figure this out I can transfer my knowledge to my actual project.
Here's what I have:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
dgv.Columns.Add("FirstName", "First Name")
dgv.Columns.Add("LastName", "Last Name")
dgv.Rows.Add("John", "Smith")
dgv.Rows.Add("Jane", "Doe")
createData()
End Sub
Private Sub createData()
Dim dt As New DataTable("namesTable")
dt.Columns.Add("FirstName")
dt.Columns.Add("LastName")
For Each row As DataGridViewRow In dgv.Rows
dt.Rows.Add(row.Cells(0).Value, row.Cells(1).Value)
MsgBox(row.Cells(0).Value & " " & row.Cells(1).Value)
Next
MsgBox(dt.Rows.Count)
DataSet1.Tables.Add(dt)
MsgBox(DataSet1.GetXml)
Dim DSReport As New ReportDataSource()
DSReport.Name = "DataSet1"
DSReport.Value = DataSet1.Tables("namesTable")
ReportViewer.ProcessingMode = Microsoft.Reporting.WinForms.ProcessingMode.Local
ReportViewer.LocalReport.ReportEmbeddedResource = "Report1.rdlc"
ReportViewer.LocalReport.DataSources.Clear()
ReportViewer.LocalReport.DataSources.Add(DSReport)
ReportViewer.LocalReport.Refresh()
ReportViewer.RefreshReport()
End Sub
As I'm adding to the dt, my MsgBox message shows me, correctly, my two names.
The MsgBox dt count is 2 so my two names added.
The Dataset XML shows this, which I think is the problem but I don't know how to fix it:
DataSet1 XML
The report then shows:
ReportViewer
Thanks for any help, this is driving me crazy.
Thanks!
It looks like your datasource is not right, why not just use your dataset that you just created. This code works for me:
ReportViewerHeader.LocalReport.DataSources.Clear()
Dim rds As New Microsoft.Reporting.WebForms.ReportDataSource("namesTable", dt)
ReportViewerHeader.LocalReport.ReportPath = "Report1.rdlc"
ReportViewerHeader.LocalReport.DataSources.Add(rds)
ReportViewerHeader.DataBind()
ReportViewerHeader.LocalReport.Refresh()
I am using a datagridview to display table data and changing values of a particular cell. Depending on requirement I may need to change such values for more than one row.
I am trying to use datagridview1.CellValueChanged to populate a Dataset (i.e. create a collection of changes made) and subsequently saving the changes by clicking on a command button.
My problem is that though for each change, the sub is being called ONLY the last change is being saved. I was thinking of using the Dataset to store multiple records where the values are changed and then SAVE all the rows in the Dataset in the database table (using Update).
Could there be some solution to my predicament.
PS. Before trying this (ADO.net dataset) I was updating a temporary table and then using that I was updating the database.
Grateful for a solution please.
Code:::
Private Sub dGridVwCreaCode_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dGridVwCreaCode.CellValueChanged
Dim qryStr_CodeShtText_Changed As String
Dim var_CodeID_Changed As Long
var_CodeID_Changed = dGridVwCreaCode(e.ColumnIndex - 2, e.RowIndex).Value
qryStr_CodeShtText_Changed = "SELECT Code_ID, Code, Code_Descrip FROM Code_SAP " & _
"WHERE (Code_SAP.Code_ID = " & var_CodeID_Changed & ")"
var_CodeShtText_Changed = dGridVwCreaCode(e.ColumnIndex, e.RowIndex).Value.ToString
If Not CatGenieConnPublic.State = ConnectionState.Open Then
CatGenieConnPublic.Open()
End If
da_CodeShtText_Changed = New OleDb.OleDbDataAdapter(qryStr_CodeShtText_Changed, CatGenieConnPublic)
da_CodeShtText_Changed.Fill(ds_CodeShtText_Changed, "Code_SAP")
cb_CodeShtText_changed = New OleDb.OleDbCommandBuilder(da_CodeShtText_Changed)
ds_CodeShtText_Changed.Tables("Code_SAP").Rows(1).Item("Code_Descrip") = var_CodeShtText_Changed
To save the changes (following sub being called from a Button_Click):
Private Sub Save_Changed_CodeShtText()
da_CodeShtText_Changed.Update(ds_CodeShtText_Changed, "Code_SAP")
MsgBox("Changes saved to database....", vbOKOnly + vbInformation)
If CatGenieConnPublic.State = ConnectionState.Open Then
CatGenieConnPublic.Close()
End If
'SET BOOLEAN TO FALSE AS CHANGED VALUES HAVE BEEN SAVED
bool_CellVal_HasChanged = False
End Sub
PS. Somehow I am not able to place all the code lines together, pl pardon me.
What I was missing out on was incrementing the "row" count in the code line:
ds_CodeShtText_Changed.Tables("Code_SAP").Rows(rowNum_Increment - 1).Item("Code_Descrip") = var_CodeShtText_Changed
So every time the user changes data in the particular cell, rows number in incremented by "1" and is collected in the dataset.
I have a datagrid bound to Oracle database. I would like to update my fields through the gridview. I used Update method which was not successful. After advanced diagnose I came up with the following observations when executing this code.
Private Sub MainGridView_ColumnChanged(ByVal Sender As Object, ByVal e As DataColumnChangeEventArgs) Handles DataTable.ColumnChanged
e.Row.AcceptChanges()
e.Row.EndEdit()
DataTable.AcceptChanges()
BindingSource.EndEdit()
End Sub
When I change a row, the value changes in memory. It's checked using break points and Watchs ( e.Row.Item("Field") has a different value )
e.Row.RowState remains Unchanged in the watch in all the steps of the excution.
Here is the code for binding the data to the database:
Public Sub FillForm()
SQL = "SELECT * FROM ARCHITECT.ARCH_TASKS"
Command = New OracleCommand(SQL, Connection)
DataAdapter = New OracleDataAdapter(Command)
DataSet.Tables.Add(DataTable)
DataAdapter.Fill(DataTable)
BindingSource.DataMember = "Table1"
BindingSource.DataSource = DataSet
Me.GridControl1.DataSource = BindingSource
End Sub
Here is a video preview Preview
Is there anything else I should take into consideration ?
Appreciate your help.
So I can fill the combobox I have going in Visual Studio just how I want with ALL results with the following:
Dim pnum As New List(Of String)
For Each polnumber As InsuredDataSet.Claims_InsuredRow In Me.InsuredDataSet.Claims_Insured
pnum.Add(polnumber.Policy_Number)
Next
pnum.Reverse()
Me.Policy_NumberComboBox.DataSource = pnum
Awesome. Now I want to limit the pnum by taking what was input/selected from Insured_NameTextBox on the form and only returning the Policy_Number with a matching Insured_Name. I figure this can be performed with an If statement, but everything I try (stringcompare, InsuredName_TextBox = Me.InsuredDataSet.ClaimsInsured, etc.) either doesn't limit the results OR limits the results entirely so nothing shows up. Any idea where to put the If statement and what should be compared?
UPDATE:
I think there is some confusion so I'm including the entire load sub below:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'IncidentsDataSet.Claims_Incidents' table. You can move, or remove it, as needed.
Me.Claims_IncidentsTableAdapter.Fill(Me.IncidentsDataSet.Claims_Incidents)
'TODO: This line of code loads data into the 'InsuredDataSet.Claims_Insured' table. You can move, or remove it, as needed.
Me.Claims_InsuredTableAdapter.Fill(Me.InsuredDataSet.Claims_Insured)
'textbox autocomplete mode
Dim Iname As New AutoCompleteStringCollection()
For Each insname As InsuredDataSet.Claims_InsuredRow In Me.InsuredDataSet.Claims_Insured
Iname.Add(insname.Insured_Name)
Next
Me.Insured_NameTextBox.AutoCompleteCustomSource = Iname
'combobox autocomplete code (now sorting by last included!)
Dim pnum As New List(Of String)
For Each polnumber As InsuredDataSet.Claims_InsuredRow In Me.InsuredDataSet.Claims_Insured
pnum.Add(polnumber.Policy_Number)
Next
pnum.Reverse()
Me.Policy_NumberComboBox.DataSource = pnum
End Sub
Try something like this:
Me.Policy_NumberComboBox.DataSource = InsuredDataSet.Claims_Insured.Where(Function(r) r.Insured_Name = Insured_NameTextBox.Text).Select(Function(r) r.Policy_Number).Reverse()
We're getting closer. Based on the update to your question, you're running this code when the form loads. However, at the point where the form loads, your textbox will always be empty. What do you do when the value in the textbox changes, to re-filter your data?
This is C#
Me.InsuredDataSet.Claims_Insured.Where(x => x.Insured_Name == Insured_NameTextBox.Text);
When I try to change the datasource of my DataGridView, I am loosing the order of the columns and their type(checkboxes,comboboxes) that i specified at design time.
It's like changing the datasource is generating again the datagridview, why ? and How can I change the datasource without losing these information ?
Please if you know give me help
Thanks in advance
On form load i do something like
Private Sub frmGrid_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim Path as string
Path="C:\......Myfile.xml"
Dim oData as dataset
oData = New DataSet
oData.ReadXml(Path)
oData.AcceptChanges()
DataGridView1.DataSource = oData
DataGridView1.DataMember = oData.Tables(0).TableName
end sub
Till now everything is fine the design mode is preserved.
Then I have in my interface I have a button to save the content of my Grid to an excel file (it's an xml, formatted for excel)
Then i want to import this, on a button action, so i do the following
Private Sub Button13_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button13.Click
Dim MyDs As DataSet
MyDs = New DataSet
Dim InputFileStream As New System.IO.FileStream(Path, System.IO.FileMode.Open)
MyDs = ImportExcelXML(InputFileStream, True, True)
MyDs.ReadXml(Path)
MyDs.AcceptChanges()
DataGridView1.DataSource = MyDs
DataGridView1.DataMember = MyDs.Tables(0).TableName
end sub
Probabily you have set up GenerateColums property to "True"
That means the GridView will generate the columns(name and number of them) againts the data sorce.
If the data source (in you case data table) are different it will come up a different grid.
If the datasource are different you can design the layout of your gridView but after that you have to manually bind the data to the columns as you wish.You can do that into
RowDataBound event.
The datatable you are trying to assign to the DataGridView1.DataSource is structured different from the way you defined the DataGridView at design time. Put a break point in your code right before you reassign the new DataTable to the DataSource and see what is different in the structure. It is most likely that you either have more or less DataColumns in place, or the columns could be in a different order. They might even be named different. If at design time you set your DataGridViewColumn's DataProperty to a specific name, than then name needs to be exact.
You'll just have to check it at that breakpoint and see what the differences are.
I found a solution, your hints helped me to look on the right direction to find a solution !
What i was doing was on form load
MaGrille.DataSource = oData
MaGrille.DataMember = oData.Tables(0).TableName
Then in the button click I do :
MaGrille.DataSource = MyDs
MaGrille.DataMember = MyDs.Tables(0).TableName
The problem is that the grid is rebuild and i loose the formatting, column order etc..
After many tests, I understood that It wasn't working because the names of datatables are differents ! I don't understand why, but it was the error as it seems.
I had the following values
oData.Tables(0) = "DECLARATION"
MyDs.Tables(0) = "Sheet1"
So I noticed that if I rename MyDs.Tables(0) by "DECLARATION" instead of "Sheet1", and i click on the button, this time I don't loose formatting, neither orders ...
This inspired me to find the SOLUTION :
After many tries, I realized that if instead of doing on form load
MaGrille.DataSource = oData
MaGrille.DataMember = oData.Tables(0).TableName
and on button click :
MaGrille.DataSource = MyDs
MaGrille.DataMember = MyDs.Tables(0).TableName
I do :
on form load
MaGrille.DataSource = oData.Tables(0)
and on button click
MaGrille.DataSource = MyDs.Tables(0)
All works fine even if the oData.Tables(0).TableName is different from MyDs.Tables(0).TableName !!
I found the solution Now, but still can't understand the WHY If anyone get an explication, please let me know.
Thanks to all again