C# Winform – 在 RDL 文件的帮助下将适用于单个数据集的解决方案扩展到 ReportViewer 报告的多个数据集

C# Winform – Extending solution working for single DataSet to Multiple DataSets for ReportViewer Reports with the help of RDL file

我从 中获取了这段代码,它帮助我解决了在 Winforms 上使用 Microsoft 的 Reportviewer 控件的单个数据集的问题。

工作部分:

调用形式:

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();

报表:

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();
}

我将其扩展为采用多个数据集,如下所示:

  1. 添加相同的 SQL 语句 3 次并添加 where 条件为 3 tables 添加到具有 3 个独立数据集的 RDL 文件 即:Data, Data1, Data2

修改后的代码:

调用形式:

        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();

报表:

    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();
    }

在此之后,代码继续为 Single DataSet 工作,如下所示:

但是对于多个数据集,它给出了以下错误:

搜索结果:

  1. 当我寻找这个错误时,我得到了这个 SO link 我不知道的地方 为什么会出现同样的错误:

Can not edit rdl report (2005 defination) in Vs 2008

  1. 我可以在下面的 link 中看到代码的匹配项 解决方案似乎对他们有用:

http://www.dotnetspider.com/resources/28409-ReportViewer-with-multiple-dataset-report.aspx

此时我 运行 没有解决方案,需要帮助。

编辑:

首先是什么导致了这个问题?

为了将问题扩展到其他数据集,我在我的 RDL 设计器中复制了 table。设计者好像把<rd:TypeName>标签改成了<TypeName>

在这一点上,我真的很感谢 Whosebug 为我提供这个平台来解决 post 我的问题和@RezaAghaei,他在很多场合都付出了额外的努力来查看一个问题的所有细节遇到问题及时解决。

如异常中所述,元素 Field 具有无效的子元素 TypeName

您应该改用 rd:TypeName。例如:

<Field Name="id">
  <DataField>id</DataField>
  <rd:TypeName>System.Int32</rd:TypeName>
</Field>

问题出在第二个和下一个数据集上,但第一个数据集没问题。