程序化RDLC报告

时间:2016-08-19 15:23:38

标签: vb.net tsql reporting-services rdlc

我在这里有点傻眼了。我见过的大多数教程都是使用向导或内置(或现成的)数据集创建报告。我在运行时使用查询构建数据集,所以我不太清楚如何采用我迄今为止所看到的数据集。

通常,当我创建报告时,它是一个记录报告,RDLC文件中的字段可以使用参数轻松填充。我尝试在下面尝试的操作类似于进行SELECT查询。所以,这就是我想要做的事情,我试图制作一个如此显示的报告:

Status: Approved
PID  |  Name   | Address
1    |  Name 1 | Address 1
2    |  Name 2 | Address 2
===========================
Status: Denied
PID  |  Name   | Address
3    |  Name 3 | Address 3
4    |  Name 4 | Address 4

我有几个问题:

  1. 我的RDLC报告存储在" \ Reports"带有.vb / .resx文件的文件夹内的文件夹。当我使用Application.StartupPath& " \ Reports \ myReport.rdlc",它无法在那里找到它(显然)。有没有办法让我将报告文件嵌入到程序中(即:使用相对文件夹名称,我应该在哪里放置RDLC文件夹/文件)?我不认为我应该将RDLC文件传输到Debug文件夹,只是为了使其工作(因此完整的目录列表)。

  2. 使用上述代码尝试创建报告的好方法是什么?我在想,如果我沿着我的数据集循环并将值从那里传递给RDLC文件作为参数,它将填充报告(就像之前我的单记录报告一样),但这似乎不是案件。

  3. 刷新报表查看器也会给我

      

    尚未为数据源提供数据源实例'数据集1'。

    我在RDLC文件中创建了一个虚拟数据集,只是为了能够使用Tablix,就像我读过的几个线程中所建议的那样。如果我可以使用我从头开始制作的数据集而不是使用向导,那我真的更喜欢。

    Private Sub btnGenerateReport_Click(sender As Object, e As EventArgs) Handles btnGenerateReport.Click
        Dim query As String
    
        query = BuildQuery()
        SQLControl = New SQLControl
    
        Try
            If Not query = String.Empty Then
                SQLControl.QueryParams(query)
                If SQLControl.SQLDS.Tables(0).Rows.Count > 0 Then
                    FetchData()
    
                End If
            End If
        Catch ex As Exception
            MsgBox(ex.Message, MsgBoxStyle.Exclamation, "Report Maker")
        End Try
    End Sub
    
    Private Sub FetchData()
        Dim dataSource As ReportDataSource
        Dim PID As Integer
        Dim Name As String
        Dim ApplicationStatus As String
        Dim Address As String
    
        rvPreview.Reset()
        rvPreview.LocalReport.ReportPath = "C:\Users\xxx\Documents\Visual Studio 2015\Projects\My Project 1\My Project 1\Reports\myReport.rdlc"
        rvPreview.LocalReport.DataSources.Clear()
        dataSource = New ReportDataSource()
        _rparams = New List(Of ReportParameter)
    
        With SQLControl.SQLDS.Tables(0)
            For x As Integer = 0 To .Rows.Count - 1
                PID = .Rows(x).Item("PID")
                Name = .Rows(x).Item("LName") & ", " & .Rows(x).Item("FName")
                ApplicationStatus = .Rows(x).Item("ApplicationStatus")
                Address = .Rows(x).Item("StreetAddress") & ", " & .Rows(x).Item("City")
    
                _rparams.Add(New ReportParameter("PID", PID))
                _rparams.Add(New ReportParameter("Name", Name))
                _rparams.Add(New ReportParameter("ApplicationStatus", ApplicationStatus))
                _rparams.Add(New ReportParameter("Address", Address))
    
                For Each param As ReportParameter In _rparams
                    rvPreview.LocalReport.SetParameters(_rparams)
                Next
            Next x
    
            rvPreview.RefreshReport()
        End With
    End Sub
    

1 个答案:

答案 0 :(得分:0)

开始时我不得不提到我使用C#的RDLC报告,但是在vb.net中解决方案应该非常相似。

  1. 我通常将每个报告准备为单独的项目(因此我为每个报告都有单独的DLL)并在此项目中使用单独的类来处理我需要对报告执行的所有操作。我在项目下添加Every RDLC文件(主报告文件和子报告文件)。在我的情况下,我可以像使用项目命名空间和RDLC文件名一样读取每个RDLC文件,如下面的示例代码所示

    Assembly assembly = Assembly.GetExecutingAssembly();
    Stream stream = assembly.GetManifestResourceStream("[Some project namespace].[Some report filename].rdlc"); 
    

    然后我使用这样的代码将该流与报表查看器连接(此代码中的stream与上面的对象相同,但此代码位于另一个可访问报表查看器对象的类中)

    ReportViewerControl.LocalReport.LoadReportDefinition(new StreamReader(stream));
    
  2. 您可以非常简单的方式为报告提供DataSet。您可以将System.Data.DataTable类的对象用于表(我在下面的代码中将此对象称为yourTableObject)和System.Data.DataRow类用于该表中的行。当您将所有数据放入表格中时,您可以使用此类代码将其提供给报告

    //I use DataSet1 as dataset name because you use this name in your report definition
    ReportDataSource rds = new ReportDataSource("DataSet1", yourTableObject);
    ReportViewerControl.LocalReport.DataSources.Add(rds);
    

    当前提供的表应该与报表定义中的数据集具有相同的字段。

  3. 您必须为报告提供有效的DataSet。解决方案在第2点上面。