在VS2013报表查看器中创建报表,其中包含使用相同数据集的多个报表

时间:2015-10-08 16:19:15

标签: c# winforms reporting-services report-viewer2012

我需要在VS2013报表查看器(.net 4.5 C#)winforms应用程序中创建一个显示多个报表的单个报表。报告表需要使用相同的SQL存储过程(填充名为“DataSet”的dt),只需更改从先前屏幕中的列表框提示中选择的项目返回的数据。我试图使用本地报告模式(我的winforms应用程序中引用的.net程序集)。下面是单个报告应该如何显示的示例以及我尝试用于生成报告的代码。我有两个rdlc文件,包含页眉和页脚的初始文件是在 ItemsSoldMonthlyReport_Load 方法中链接的文件。另一个rdlc作为子报表嵌入在第一个报表文件的详细信息行中(在报表设计器中)。 ItemsSoldMonthlyReport_Load 方法正确地将 itemType pFromDate pThruDate 参数传递给子报表方法。子报表方法是根据应用于“SoldList”数据集的项目数启动的,这是正确的。对于 itemType 参数中的每个项,使用 CC_SubreportProcessingEventHandler 中的GetData方法,可以成功返回每个表的数据。每个报告表的正确数据都设置为“DataSet” DataTable。但是,似乎“DataSet” DataTable只能设置一次作为ReportDataSource。当我尝试将第二组数据加载的“DataSet”设置为ReportDataSource但第二个表的数据(即:Clothing)未显示在最终报告中时,不会发生错误。相反,第一个数据表(即:Toys)在最终报告显示中显示两次。是否有可能做我正在尝试的事情,如果是这样,我应该采取什么方法?我已经尝试了很多东西并对此进行了大量研究,但我自己找不到答案。如果报告查看器绝对无法生成这样的报告,那么任何人都可以建议一个不太昂贵的替代方案吗?提前谢谢......

报告应该是什么样的......

enter image description here

我最近(也是最接近的尝试)创建此类报告的代码......

namespace StoreProject_Forms
{
    public partial class rptItemsSoldReport : Form
    {
        int x = 0;
        public rptItemsSoldReport()
        {
            InitializeComponent();
        }

        public void CC_SubreportProcessingEventHandler(object sender, SubreportProcessingEventArgs e)
        {
            DataTable dt = new DataTable();
            var mainSource = ((LocalReport)sender).DataSources["SoldList"];
            var itemTypes = e.Parameters["itemType"].Values;
            DateTime sdate = e.Parameters["pFromDate"].Values;
            DateTime edate = e.Parameters["pThruDate"].Values;
            StoreProject1.StoreDataSetTableAdapters.spGetItemsSoldReportTableAdapter commDt = new StoreProject1.StoreDataSetTableAdapters.spGetItemsSoldReportTableAdapter();
            dt.Clear();
            dt = commDt.GetData(sdate, edate, itemTypes[x]);
            e.DataSources.Add(new ReportDataSource("DataSet1", dt));
            x++;
        }


        public void ItemsSoldMonthlyReport_Load(DateTime startDate, DateTime endDate, ListBox.SelectedObjectCollection itemTypesTxt)
        {
            startDate = new DateTime(startDate.Year, startDate.Month, 1);
            endDate = new DateTime(endDate.Year, endDate.Month, 1);
            System.Collections.Generic.List<ReportParameter> paramList = new System.Collections.Generic.List<ReportParameter>();
            string itemTypes = null;
            reportViewer1.LocalReport.DataSources.Clear();
            StoreProject1.StoreDataSetTableAdapters.spGetItemsSoldReportTableAdapter commDt = new StoreProject1.StoreDataSetTableAdapters.spGetItemsSoldReportTableAdapter();
            List<string> itemsA = new List<string>();
            Dictionary<string, int> allItemTypes = new Dictionary<string, int>();
            DataTable ct = new DataTable();
            foreach (KeyValuePair<string, int> item in itemTypesTxt)
            {
                itemsA.Add(item.Key);
                allItemTypes.Add(item.Key, item.Value);
            }
            this.reportViewer1.LocalReport.SubreportProcessing += new SubreportProcessingEventHandler(CC_SubreportProcessingEventHandler);
            ReportParameter itemParam = new ReportParameter("itemType");
            ct = StoreProject1.ItemList.ConvertToDatatable(allItemTypes);
            string[] itemsArray = itemsA.ToArray();
            ReportDataSource _rsource = new ReportDataSource("SoldList", ct);
            reportViewer1.LocalReport.DataSources.Add(_rsource);

            itemParam.Values.AddRange(itemsArray);
            paramList.Add(itemParam);

            string sfdate = startDate.ToString("MM/yyyy");
            paramList.Add(new ReportParameter("pFromDate", sfdate, false));

            string stdate = endDate.ToString("MM/yyyy");
            paramList.Add(new ReportParameter("pThruDate", stdate, false));

            reportViewer1.LocalReport.ReportPath = @"C:/StoreProject1/ItemsSoldReport.rdlc";
            reportViewer1.LocalReport.SetParameters(paramList);
            this.reportViewer1.SetDisplayMode(DisplayMode.PrintLayout);
            this.reportViewer1.LocalReport.Refresh();
        }
    }
}

1 个答案:

答案 0 :(得分:0)

对不起它有点长。对于每个Report,我们有多种方法。正如评论部分所述,我在下面逐步生成相同的(不完全但结果相同)报告:

  1. 创建一个DataSet,其中一个表有7个Column s。
  2. DataSet

    1. 开始新的Report,在其中添加List个完整空间,然后在TextBox内添加7个List es(其中包含Col1到Col 7的数据)。
    2. Report

      1. Visibility es TextBox设置为Show or hide based on an expression,以便在我们传递emty字符串数据时隐藏它们:
      2. TextBox1:=IIF(Fields!Col1.Value="",TRUE,FALSE)

        TextBox2:=IIF(Fields!Col2.Value="",TRUE,FALSE)

        TextBox3到7:=IIF(Fields!Col3.Value & Fields!Col4.Value & Fields!Col5.Value & Fields!Col6.Value & Fields!Col7.Value = "",TRUE,FALSE)

        1. 示例数据结构:
        2. 简单的事情:

          class clsDataStruct
          {
              public class ItemType
              {
                  public string Name { get; set; }
              }
          
              public class Item
              {
                  public string Name { get; set; }
                  public ItemType Type { get; set; }
                  public int Cost { get; set; }
                  public int Prize { get; set; }
              }
          
              public class BillByItem
              {
                  public DateTime DateSold { get; set; }
                  public Item Item { get; set; }
              }
          }
          
          1. Form查看结果:
          2. Form添加ReportViewerForm,将之前创建的Report设置为ReportViewer。然后在Form Load事件中,添加一些代码以生成一些随机数据(这是您获取数据的地方)然后生成我们的Report

                //for data generation
                static Random rdn = new Random();
            
                //some list to hold data
                List<clsDataStruct.ItemType> lstItemType = new List<clsDataStruct.ItemType>();
                List<clsDataStruct.Item> lstItem = new List<clsDataStruct.Item>();
                List<clsDataStruct.BillByItem> lstBill = new List<clsDataStruct.BillByItem>();
            
                //this is what user choose to filter the report
                //user choose to report which item type
                List<clsDataStruct.ItemType> lstItemTypeByUser = new List<clsDataStruct.ItemType>();
                //date begin and end of report
                DateTime dteStart;
                DateTime dteEnd;
            
                private void Form1_Load(object sender, EventArgs e)
                {
                    //create 3 ItemType
                    for (int i = 1; i < 4; i++)
                    {
                        clsDataStruct.ItemType itt = new clsDataStruct.ItemType();
                        itt.Name = "Item Type " + i.ToString();
                        lstItemType.Add(itt);
                    }
            
                    //create 12 Item
                    for (int i = 1; i < 13; i++)
                    {
                        clsDataStruct.Item item = new clsDataStruct.Item();
                        item.Name = "Item " + i.ToString();
                        item.Type = lstItemType[i % 3];
                        item.Cost = rdn.Next(10);
                        item.Prize = item.Cost + rdn.Next(5);
                        lstItem.Add(item);
                    }
            
                    //create 30 BillByItem in next 3 month
                    for (int i = 1; i < 31; i++)
                    {
                        clsDataStruct.BillByItem bill = new clsDataStruct.BillByItem();
                        bill.DateSold = DateTime.Now.AddDays(rdn.Next(90));
                        bill.Item = lstItem[rdn.Next(12)];
                        lstBill.Add(bill);
                    }
                    //set the filters
                    //add 2 random type to the filter
                    lstItemTypeByUser.Add(lstItemType.Where(s => !lstItemTypeByUser.Contains(s)).ToList()[rdn.Next(lstItemType.Where(s => !lstItemTypeByUser.Contains(s)).ToList().Count)]);
                    lstItemTypeByUser.Add(lstItemType.Where(s => !lstItemTypeByUser.Contains(s)).ToList()[rdn.Next(lstItemType.Where(s => !lstItemTypeByUser.Contains(s)).ToList().Count)]);
                    //date start and end is one month from date we have data
                    dteStart = DateTime.Now.AddDays(rdn.Next(60) - 30);
                    dteEnd = DateTime.Now.AddMonths(3).AddDays(rdn.Next(60) - 30);
            
                    this.reportViewer1.LocalReport.DataSources.Clear();
                    dsReports.dtLyLichTrichNgangDataTable dtLyLichTrichNgang = new dsReports.dtLyLichTrichNgangDataTable();
            
                    //Simple title, replace with yours
                    dtLyLichTrichNgang.Rows.Add("ITEM INVENTORY SOLD " + dteStart.ToShortDateString() + " - " + dteEnd.ToShortDateString(), "", "", "", "", "", "");
                    //empty row
                    dtLyLichTrichNgang.Rows.Add(" ", "", "", "", "", "", "");
            
                    DateTime dteFirstOfCycle;
                    DateTime dteLastOfCycle;
                    //cycle through months and fill data to datatable, maybe week or quarter
                    for (dteFirstOfCycle = new DateTime(dteStart.Year, dteStart.Month, 1); dteFirstOfCycle < dteEnd; dteFirstOfCycle = dteFirstOfCycle.AddMonths(1))
                    {
                        dteLastOfCycle = dteFirstOfCycle.AddMonths(1).AddDays(-1);
            
                        //take BillByItem in each month
                        var billMonth = lstBill.Where(s => s.DateSold >= dteFirstOfCycle && s.DateSold <= dteLastOfCycle).OrderBy(s => s.DateSold);
            
                        dtLyLichTrichNgang.Rows.Add("FROM " + dteFirstOfCycle.ToShortDateString() + " TO " + dteLastOfCycle.ToShortDateString(), "", "", "", "", "", "");
                        //empty row
                        dtLyLichTrichNgang.Rows.Add(" ", "", "", "", "", "", "");
            
                        //cycle through each item type
                        foreach (clsDataStruct.ItemType itt in lstItemTypeByUser)
                            //have sold something
                            if (billMonth.Where(s => s.Item.Type == itt).Count() != 0)
                            {
                                //itemtype
                                dtLyLichTrichNgang.Rows.Add(itt.Name.ToUpper(), "", "", "", "", "", "");
                                //detail header
                                dtLyLichTrichNgang.Rows.Add("", "", "Name", "Cost", "Prize", "Profit", "Date Sold");
                                //cycle through each bill
                                foreach (clsDataStruct.BillByItem bill in billMonth)
                                    dtLyLichTrichNgang.Rows.Add("", "", bill.Item.Name, bill.Item.Cost, bill.Item.Prize, bill.Item.Prize - bill.Item.Cost, bill.DateSold.ToShortDateString());
                                //total row
                                dtLyLichTrichNgang.Rows.Add("", "", "TOTAL", billMonth.Sum(s => s.Item.Cost), billMonth.Sum(s => s.Item.Prize), billMonth.Sum(s => s.Item.Prize - s.Item.Cost), "");
                            }
                            //sold nothing
                            else
                            {
                                dtLyLichTrichNgang.Rows.Add(itt.Name.ToUpper(), "", "", "", "", "", "");
                                dtLyLichTrichNgang.Rows.Add("Nothing sold", "", "", "", "", "", "");
                                //empty row
                                dtLyLichTrichNgang.Rows.Add(" ", "", "", "", "", "", "");
                            }
                        //empty row
                        dtLyLichTrichNgang.Rows.Add(" ", "", "", "", "", "", "");
                    }
            
                    this.reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("dsLyLichTrichNgang", (DataTable)dtLyLichTrichNgang));
                    this.reportViewer1.RefreshReport();
                }
            
            1. 结果:
            2. Final Report

              通过对TextBox BorderStyle进行一些调整,您可以获得所需的Report