vb.net 是否可以在 RDLC 报告中显示与数据集不同的记录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16849464/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 13:48:22  来源:igfitidea点击:

Is it possible to display distinct record from dataset in RDLC report

.netsqlvb.netdatasetrdlc

提问by Jeffery Lee

Did a quick search and couldn't find the answer I've been looking for. So I have a vb.net windows application which uses RDLC to generate invoice, delivery order, price list and other documents. To reduce server load as much as possible, information will only be pulled once from the server and it includes order items, price and other necessary data.

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

Once the data is pulled (in xml) it will be filled into a dataset which will be used in generating various reports. Note that this same dataset is used in multiple RDLC reports to display different information.

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

So the problem in my case is that I cannot do a SELECT DISTINCT from the SQL level because the same set of data will also be used generate the invoice, but I also need to display a price list from the same dataset which only include distinct order items.

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

So the options I have:

所以我有的选择:

  1. Have the RDLC to display distinct row, but I have no idea on how it can be achieved.

  2. Failing that, I might need to create another datatable in my xsd file using the existing dataset, separating the dataset into 2. Again, I have little idea on the details of execution.

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

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

Any input is much appreciated. Thanks!

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

采纳答案by Alex

This example will contain threeDataSets. Since we have three DataSets, I'll use threeDataSourcesin oneReport.rdlc. The scenario will be a simple production line. We'll have starting machines, machines that are being assembled and also machines who are getting shipped.

此示例将包含三个DataSets. 既然我们有三个数据集,我将使用3DataSources一个Report.rdlc。该场景将是一条简单的生产线。我们将有启动机器、正在组装的机器以及正在发货的机器。

I'll assume you know how to create DataSets (.XSD) files. I will split up the code into sections and show you the final result in this post.

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

What is important to your question is how I assign three DataSources to one report.

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



Declarations

声明

I have three custom classes, clsAssemblyState, clsExpeditionState, clsStartStatewhich hold information that is gathered from the Database. These are just my custom classes which I use as objects. You bind your data with XML, I assign it programmatically as you'll see below in the "Filling DataTables Programmatically" section.

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

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)'


Reseting the report

重置报告

It is good practice to clear your report datasource before assigning new ones.

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

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


Filling DataTables Programmatically

以编程方式填充数据表

This will fill my dsAssemblies' DataTable, the same is done for the other two DataTables but it would be redundant for me to write this out here.

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

'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


Assign DataTables to DataSources

将数据表分配给数据源

The sReportDataSource[i].Nameare the names that I assigned to each DataTable of it's respective DataSet. I will show a picture of the DataSets below the code.

这些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()

Here you see the three DataSets and their DataTables

在这里您可以看到三个数据集及其数据表

DataSets

数据集



Full Report Code

完整报告代码

This method will generate a report using three datasources. Of course, you must assign those DataSets to something in your .rdlcsuch as three different tablix.

此方法将使用三个数据源生成报告。当然,您必须将这些数据集分配给您的某些内容,.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

Note: rvis my report viewer control name instead of ReportViewer1

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

回答by Jeffery Lee

After a few experiments I've managed to find a better (and easier) solution for the problem. It is probably the most elegant solution so far. So I figured that I post it here for others who ran into the same problem.

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

This is how the report looks in the designer enter image description hereThe green marking shows the respective row group and tablix row. The same item_id may exists in more than 1 line/row and I need to have them shown distinct. This can be done by using the grouping feature under the row group properties. enter image description hereUnder group expressions, add a new entry and select the field which needs to be shown distinct. It supports expressions too which is very very useful. enter image description here

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