问题
I had this code taken from Reza Aghaei’s solution, which had helped me solve the problem for single DataSet using Microsofts Reportviewer Control on Winforms.
Working Part:
Calling Form:
string sql = "SELECT bk_book_details.id, bk_book_details.book_id, bk_book_details.book_no, bk_book_details.book_name, bk_book_details.edition_id, bk_book_details.condition_id, bk_book_details.publication_year, bk_book_details.price, bk_book_details.purchase_price, bk_book_details.reference_no, bk_book_details.book_status, bk_book_details.purchase_id, bk_book_details.purchase_date FROM bk_book_details";
string reportLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\Reports\LMS_Book_Price_Invoice.rdl";
var f = new ReportForm();
f.ReportPath = reportLocation;
DataTable dt = (DataTable)DataAdapter.Current.LoadData(sql, "LoadDataTable");
List<DataTable> lDt = new List<DataTable>();
lDt.Add(dt);
f.ReportData = new List<DataTable>(lDt);
f.ShowDialog();
Report Form:
public List<DataTable> ReportData { get; set; }
public string ReportPath { get; set; }
private void ReportForm_Load(object sender, EventArgs e) {
long numberOfDataSets = this.ReportData.Count();
if (numberOfDataSets == 0)
return;
var rds = new Microsoft.Reporting.WinForms.ReportDataSource("Data", this.ReportData[i]);
this.reportViewer1.LocalReport.DataSources.Add(rds);
reportViewer1.LocalReport.ReportPath = this.ReportPath;
this.reportViewer1.RefreshReport();
}
Which I extended to take multiple DataSets like so:
- Added the same SQL statement 3 times with addition of where condition to 3 tables added to the RDL file with 3 separate DataSets namely: Data, Data1, Data2
code after modification:
Calling Form:
string sql = "SELECT bk_book_details.id, bk_book_details.book_id, bk_book_details.book_no, bk_book_details.book_name, bk_book_details.edition_id, bk_book_details.condition_id, bk_book_details.publication_year, bk_book_details.price, bk_book_details.purchase_price, bk_book_details.reference_no, bk_book_details.book_status, bk_book_details.purchase_id, bk_book_details.purchase_date FROM bk_book_details WHERE bk_book_details.book_id<=2";
string sql1 = "SELECT bk_book_details.id, bk_book_details.book_id, bk_book_details.book_no, bk_book_details.book_name, bk_book_details.edition_id, bk_book_details.condition_id, bk_book_details.publication_year, bk_book_details.price, bk_book_details.purchase_price, bk_book_details.reference_no, bk_book_details.book_status, bk_book_details.purchase_id, bk_book_details.purchase_date FROM bk_book_details WHERE bk_book_details.book_id=4";
string sql2 = "SELECT bk_book_details.id, bk_book_details.book_id, bk_book_details.book_no, bk_book_details.book_name, bk_book_details.edition_id, bk_book_details.condition_id, bk_book_details.publication_year, bk_book_details.price, bk_book_details.purchase_price, bk_book_details.reference_no, bk_book_details.book_status, bk_book_details.purchase_id, bk_book_details.purchase_date FROM bk_book_details WHERE bk_book_details.book_id=5";
string reportLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\Reports\LMS_Book_Price_Invoice_2.rdl";
var f = new ReportForm();
f.ReportPath = reportLocation;
DataTable dt = (DataTable)DataAdapter.Current.LoadData(sql, "LoadDataTable");
DataTable dt1 = (DataTable)DataAdapter.Current.LoadData(sql1, "LoadDataTable1");
DataTable dt2 = (DataTable)DataAdapter.Current.LoadData(sql2, "LoadDataTable2");
List<DataTable> lDt = new List<DataTable>();
lDt.Add(dt);
lDt.Add(dt1);
lDt.Add(dt2);
f.ReportData = new List<DataTable>(lDt);
f.ShowDialog();
Report Form:
public List<DataTable> ReportData { get; set; }
public string ReportPath { get; set; }
private void ReportForm_Load(object sender, EventArgs e) {
long numberOfDataSets = this.ReportData.Count();
if (numberOfDataSets == 0)
return;
this.reportViewer1.LocalReport.DataSources.Clear();
string dataX = "Data";
for (int i = 0 ; i < numberOfDataSets; i++) {
string DataName = dataX;
if (i != 0)
DataName += Convert.ToString(i);
/*For our case the DataName is used to provide DataSet name Data, Data1, Data2*/
var rds = new Microsoft.Reporting.WinForms.ReportDataSource(DataName, this.ReportData[i]);
this.reportViewer1.LocalReport.DataSources.Add(rds);
}
reportViewer1.LocalReport.ReportPath = this.ReportPath;
this.reportViewer1.RefreshReport();
}
After this, the code continues to work for Single DataSet like so:
However for Multiple Datasets, it gives the following error:
Search results:
- When I looked for this error, I got this SO link where I don’t know why the same error occurs:
Can not edit rdl report (2005 defination) in Vs 2008
- I can see a match for the code in the link below as well where the solution seems to be working for them:
http://www.dotnetspider.com/resources/28409-ReportViewer-with-multiple-dataset-report.aspx
At this point I have run out of solutions and need help.
Edit:
What caused the issue in the first place?
In order to extend the problem for additional datasets, I had copied the table in my RDL designer. The designer seems to change the <rd:TypeName>
tag to <TypeName>
.
At this point I am really grateful for StackOverflow for providing this platform for me to post my problems and to @RezaAghaei, who in multiple occasions has gone that extra mile to look at all the details of a problems to give a solution in times of need.
回答1:
As addressed in the exception, the element Field
has invalid child element TypeName
.
You should use rd:TypeName
instead. For example:
<Field Name="id">
<DataField>id</DataField>
<rd:TypeName>System.Int32</rd:TypeName>
</Field>
The problem is with second and next data sets, but first data set is OK.
来源:https://stackoverflow.com/questions/40446644/c-sharp-winform-extending-solution-working-for-single-dataset-to-multiple-data