【问题标题】:Is it possible to display distinct record from dataset in RDLC report是否可以在 RDLC 报告中显示来自数据集的不同记录
【发布时间】:2013-05-31 03:49:33
【问题描述】:

快速搜索并找不到我一直在寻找的答案。 所以我有一个 vb.net windows 应用程序,它使用 RDLC 生成发票、交货单、价目表和其他文件。为了尽可能减少服务器负载,信息只会从服务器中提取一次,其中包括订单商品、价格和其他必要的数据。

一旦数据被提取(在 xml 中),它将被填充到一个数据集中,该数据集将用于生成各种报告。请注意,在多个 RDLC 报告中使用相同的数据集来显示不同的信息。

所以我的问题是我不能从 SQL 级别执行 SELECT DISTINCT,因为相同的数据集也将用于生成发票,但我还需要显示来自同一数据集的价目表,仅包括不同的订单项。

所以我有以下选择:

  1. 让 RDLC 显示不同的行,但我不知道如何实现。

  2. 否则,我可能需要使用现有数据集在我的 xsd 文件中创建另一个数据表,将数据集分成 2 个。同样,我对执行的细节知之甚少。

非常感谢任何输入。谢谢!

【问题讨论】:

  • 我不确定我是否理解您的问题,但我会告诉您我通常会做什么。我创建了多个 DataSet 以将我的信息拆分为更清晰、更小的 DataTable。然后,我只需创建多个报表数据源并将数据集链接到它们。如果这是您正在寻找的东西,我可以为您提供一些关于我是如何做到的代码。
  • 是的,我相信这正是我一直在寻找的。目前,我的应用程序只有一个数据集(和一个数据源)与服务器返回的 xml 文件的架构相匹配。用于绑定数据的代码类似于 xml.ReadXml(New XmlTextReader(New StringReader(xmlString))) _ delivery_order_itemBindingSource.DataSource = xml xml 是 xsd

标签: .net sql vb.net dataset rdlc


【解决方案1】:

经过几次实验后,我设法找到了一个更好(也更简单)的解决方案。这可能是迄今为止最优雅的解决方案。所以我想我把它贴在这里给遇到同样问题的其他人。

这是报表在设计器中的外观 绿色标记显示相应的行组和 tablix 行。相同的 item_id 可能存在于超过 1 行/行中,我需要将它们显示为不同的。这可以通过使用行组属性下的分组功能来完成。 在组表达式下,添加一个新条目并选择需要区分显示的字段。它也支持表达式,非常非常有用。

【讨论】:

    【解决方案2】:

    此示例将包含 三个 DataSets。由于我们有三个 DataSet,我将在 one Report.rdlc 中使用 three DataSources。该场景将是一条简单的生产线。我们将有启动机器、正在组装的机器以及即将发货的机器。

    我假设您知道如何创建数据集 (.XSD) 文件。我会将代码分成几个部分,并在这篇文章中向您展示最终结果。

    对您的问题而言,重要的是我如何将三个数据源分配给一份报告。


    声明

    我有三个自定义类,clsAssemblyStateclsExpeditionStateclsStartState,它们保存从数据库收集的信息。这些只是我用作对象的自定义类。您将数据与 XML 绑定,我以编程方式分配它,您将在下面的“Filling DataTables Programmatically”部分中看到。

    Dim ds1 As New dsAssemblies 'Link to my DataSet called dsAssemblies'
    Dim ds2 As New dsExpeditions 'Link to my DataSet called dsExpeditions'
    Dim ds3 As New dsStarts 'Link to my DataSet called dsStarts'
    Dim sReportDataSource1 As ReportDataSource 'First datasource'
    Dim sReportDataSource2 As ReportDataSource 'Second datasource'
    Dim sReportDataSource3 As ReportDataSource 'Third datasource'
    Dim AssemblyStates As List(Of clsAssemblyState) = clsAssemblyState.GetAll() 'List that contains all my machines being assembled'
    Dim ExpeditionStates As List(Of clsExpeditionState) = clsExpeditionState.GetAll() 'List that  contains all my machines in shipping'
    Dim StartStates As List(Of clsStartState) = clsStartState.GetAll() 'List of all my machines being started (paper work)'
    

    重置报告

    在分配新数据源之前清除报表数据源是一种很好的做法。

    'Reset the viewer'
    rv.Reset()
    rv.LocalReport.ReportEmbeddedResource = "YourProjectName.YourReportName.rdlc"
    rv.LocalReport.DataSources.Clear()
    sReportDataSource1 = New ReportDataSource()
    sReportDataSource2 = New ReportDataSource()
    sReportDataSource3 = New ReportDataSource()
    

    以编程方式填充数据表

    这将填充我的 dsAssemblies 的 DataTable,其他两个 DataTable 也是如此,但在这里写出来对我来说是多余的。

    'Fill datatables'
    If AssemblyStates.Count > 0 Then
        For Each asmState As clsAssemblyState In AssemblyStates
            Dim asm As New clsAssembly(asmState.FK_Assembly)
            Dim Machine As New clsMachine(asm.FK_Machine)
            Dim Client As New clsClient(Machine.FK_Client)
            Dim State As New clsState(asmState.FK_State)
    
            ds1.dtAssembly.Rows.Add(Machine.MachineNo, Machine.Description, Client.Nom, State.State, asm.DateTransfer.ToString("yyyy-MM-dd"))
        Next
    Else
        'No information was retrieved from my GetAll(), therefor no rows ... I add a row with values of "N/A" notifying the user that there is nothing in that particular DataTable'
        ds1.dtAssembly.Rows.Add("N/A", "N/A", "N/A", "N/A", "N/A")
    End If
    

    将数据表分配给数据源

    sReportDataSource[i].Name 是我分配给其各自数据集的每个数据表的名称。我将在代码下方显示数据集的图片。

    sReportDataSource1.Name = "Assembly_DataSet"
    sReportDataSource2.Name = "Expedition_DataSet"
    sReportDataSource3.Name = "Start_DataSet"
    sReportDataSource1.Value = ds1.dtAssembly
    sReportDataSource2.Value = ds2.dtExpedition
    sReportDataSource3.Value = ds3.dtStart
    rv.LocalReport.DataSources.Add(sReportDataSource1)
    rv.LocalReport.DataSources.Add(sReportDataSource2)
    rv.LocalReport.DataSources.Add(sReportDataSource3)
    rv.RefreshReport()
    Me.Show()
    

    在这里您可以看到三个 DataSet 及其 DataTables


    完整报告代码

    此方法将使用三个数据源生成报告。当然,您必须将这些 DataSet 分配给您的 .rdlc 中的某个内容,例如三个不同的 tablix。

    Private Sub GenerateStatusProduction()
        Dim ds1 As New dsAssemblies
        Dim ds2 As New dsExpeditions
        Dim ds3 As New dsStarts
        Dim sReportDataSource1 As ReportDataSource
        Dim sReportDataSource2 As ReportDataSource
        Dim sReportDataSource3 As ReportDataSource
        Dim AssemblyStates As List(Of clsAssemblyState) = clsAssemblyState.GetAll()
        Dim ExpeditionStates As List(Of clsExpeditionState) = clsExpeditionState.GetAll()
        Dim StartStates As List(Of clsStartState) = clsStartState.GetAll()
    
        'Reset the viewer'
        rv.Reset()
        rv.LocalReport.ReportEmbeddedResource = "YourProjectName.YourReportName.rdlc"
        rv.LocalReport.DataSources.Clear()
        sReportDataSource1 = New ReportDataSource()
        sReportDataSource2 = New ReportDataSource()
        sReportDataSource3 = New ReportDataSource()
    
        'Fill datatables'
        If AssemblyStates.Count > 0 Then
            For Each asmState As clsAssemblyState In AssemblyStates
                Dim asm As New clsAssembly(asmState.FK_Assembly)
                Dim Machine As New clsMachine(asm.FK_Machine)
                Dim Client As New clsClient(Machine.FK_Client)
                Dim State As New clsState(asmState.FK_State)
    
                ds1.dtAssembly.Rows.Add(Machine.MachineNo, Machine.Description, Client.Nom, State.State, asm.DateTransfer.ToString("yyyy-MM-dd"))
            Next
        Else
            ds1.dtAssembly.Rows.Add("N/A", "N/A", "N/A", "N/A", "N/A")
        End If
    
        If ExpeditionStates.Count > 0 Then
            For Each expdState As clsExpeditionState In ExpeditionStates
                Dim Expd As New clsExpedition(expdState.FK_Expedition)
                Dim Machine As New clsMachine(Expd.FK_Machine)
                Dim Client As New clsClient(Machine.FK_Client)
                Dim State As New clsState(expdState.FK_State)
    
                ds2.dtExpedition.Rows.Add(Machine.MachineNo, Machine.Description, Client.Nom, State.State, Expd.DateTransfer.ToString("yyyy-MM-dd"))
            Next
        Else
            ds2.dtExpedition.Rows.Add("N/A", "N/A", "N/A", "N/A", "N/A")
        End If
    
        If StartStates.Count > 0 Then
            For Each strtState As clsStartState In StartStates
                Dim Strt As New clsStart(strtState.FK_Start)
                Dim Machine As New clsMachine(Strt.FK_Machine)
                Dim Client As New clsClient(Machine.FK_Client)
                Dim State As New clsState(strtState.FK_State)
    
                ds3.dtStart.Rows.Add(Machine.MachineNo, Machine.Description, Client.Nom, State.State, Strt.DateTransfer.ToString("yyyy-MM-dd"))
            Next
        Else
            ds3.dtStart.Rows.Add("N/A", "N/A", "N/A", "N/A", "N/A")
        End If
    
        sReportDataSource1.Name = "Assembly_DataSet"
        sReportDataSource2.Name = "Expedition_DataSet"
        sReportDataSource3.Name = "Start_DataSet"
        sReportDataSource1.Value = ds1.dtAssembly
        sReportDataSource2.Value = ds2.dtExpedition
        sReportDataSource3.Value = ds3.dtStart
        rv.LocalReport.DataSources.Add(sReportDataSource1)
        rv.LocalReport.DataSources.Add(sReportDataSource2)
        rv.LocalReport.DataSources.Add(sReportDataSource3)
        rv.RefreshReport()
        Me.Show()
    End Sub
    

    注意:rv 是我的报表查看器控件名称,而不是 ReportViewer1

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-13
      相关资源
      最近更新 更多