3

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

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

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

所以我有以下选择:

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

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

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

4

2 回答 2

2

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

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

于 2013-06-12T07:22:37.950 回答
1

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

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

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


声明

我有三个自定义类 , clsAssemblyStateclsExpeditionState它们clsStartState保存从数据库收集的信息。这些只是我用作对象的自定义类。您将数据与 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)'

重置报告

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

'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

数据集


完整报告代码

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

于 2013-06-03T13:40:57.183 回答