C# Winform – Extending solution working for single

2019-07-23 15:05发布

问题:

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:

  1. 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:

  1. 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

  1. 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.