创建 Sales_Order_Detail_2008R2 报表 (SSRS)

本教程帮助您基于 AdventureWorks 2008R2 示例报表生成 Sales_Order_Detail_2008R2 报表。

此报表是详细信息报表,用作 Employee_Sales_Summary_2008R2 报表中针对 SalesOrderNumber 字段的钻取操作的目标。此报表显示一系列连续销售订单的销售表头和销售行项明细。详细信息包括订单号、商店名称、开票地址和发货地址、销售人员联系信息,以及 AdventureWorks2008R2 数据库中可提供的其他详细信息。有关全套报表及报表间关系的详细信息,请参阅教程:创建 AdventureWorks 2008R2 示例报表 (SSRS)

学习内容

在本教程中,您将执行以下任务:

  • 添加一个数据集和查询,用于检索一系列销售订单的销售订单明细数据。

  • 为这一系列销售订单中的第一个和最后一个销售订单号配置报表参数。

  • 向页面添加以下信息:

    • 页面名称。如果将报表导出到 Excel,则工作表的选项卡名称将基于页面名称。

    • 整个报表的页数。

    • 每个销售订单中的页数。

    • 指导报表用户如何返回到主报表的说明。

  • 添加一个列表,其中只有一个基于 SalesOrderID 的行组。向此列表中添加以下内容:

    • 一个作为容器的嵌套矩形,帮助控制销售订单表头和详细信息的布局。

    • 多个用于显示销售订单表头信息的文本框。

    • 一个子报表,用于显示多个商店联系人的电话号码。

    • 一个用于显示销售订单中每个行项的详细信息的表。

  • 添加自定义代码,以计算页总计及后续页的累加页总计。

  • 定义一个报表变量以简化累加总计表达式。

  • 对详细信息行定义一个自定义的组表达式,以便每隔 25 行开始一个新页面。

本教程的预计学时:30 分钟。

提示

销售订单详细信息报表是一种自由格式报表,它使用数据区域、矩形、嵌套数据区域和嵌套文本框来组织数据。这些项的包含层次结构至关重要。请查看报表设计提示(Report Builder 3.0 和 SSRS)中的提示,然后使用以下提示来帮助生成此报表:

  • 建议打开示例报表 Sales_Order_Detail_2008R2,并在本教程中随时查看该报表。打开 Sales_Order_Detail_2008R2 后,在“文档大纲”窗格中查看报表项的层次结构。生成报表的过程中,请检查 Tablix 报表项和矩形之间的包含关系。

    注意注意

    若要打开“文档大纲”窗格,请从“视图”菜单中单击“其他窗口”,然后单击“文档大纲”

  • 列表是自由格式的 Tablix 布局。默认情况下,列表包含一个 Tablix 单元,该单元又包含一个矩形。在本报表中,您将添加以下内容:

    • 一个附加的嵌套矩形,其中包含徽标、销售订单号和销售订单表头信息。

    • 一个用于显示销售订单中每行的详细信息的表。

  • 比起从头创建报表项和布局,您可能会发现在原始报表和您的副本之间复制和粘贴数据区域或矩形容器更为简便。您可以在打开报表的各个选项卡式视图之间复制和粘贴报表项。复制了某一报表中的项后,单击要复制到的报表的选项卡,然后单击要将这些项粘贴到的位置。粘贴操作是与上下文相关的。例如,不能将数据区域粘贴到页眉中。

打开项目并制作报表的副本

  1. 在 Business Intelligence Development Studio 中,打开报表服务器项目 AdventureWorks 2008R2。

  2. 在解决方案资源管理器中,执行下列操作:

    1. 右键单击报表 AdventureWorks2008R2_Base.rdl,然后单击**“复制”**。

    2. 右键单击项目节点,然后单击**“粘贴”**。

    3. 将复制的报表重命名为 Sales_Order_Detail_2008R2.rdl。

为个人销售创建数据集

  • 在“报表数据”窗格中,添加名为 SalesOrder 的嵌入数据集。使用 AdventureWorks2008R2 共享数据源及以下查询:

    SELECT SOH.SalesOrderNumber, S.BusinessEntityID, S.Name, 
      SOH.SalesOrderID, SOH.SalesPersonID, SOH.TotalDue,
      SOH.OrderDate, SOH.PurchaseOrderNumber,
      SOH.BillToAddressID, SOH.ShipToAddressID, SOH.ShipMethodID,
      SM.Name AS ShipMethod, BA.AddressLine1 AS BillAddress1, BA.City AS BillCity, 
      BA.PostalCode AS BillPostalCode, BSP.Name AS BillStateProvince, 
      BCR.Name AS BillCountryRegion, 
      SA.AddressLine1 AS ShipAddress1,SA.City AS ShipCity, SA.PostalCode AS ShipPostalCode, 
      SSP.Name AS ShipStateProvince, SCR.Name AS ShipCountryRegion,
      e.JobTitle, per.[FirstName] + N' ' + per.[LastName] AS [SalesPerson], 
      ph.PhoneNumber,
      SD.SalesOrderDetailID, SD.OrderQty, SD.UnitPrice, 
      CASE WHEN SD.UnitPriceDiscount IS NULL THEN 0 ELSE SD.UnitPriceDiscount END 
         AS UnitPriceDiscount, 
      SD.LineTotal, SD.CarrierTrackingNumber, P.Name as ProductName, P.ProductNumber
      FROM [Sales].[SalesOrderHeader] SOH 
        INNER JOIN Sales.Customer C ON SOH.CustomerID = C.CustomerID
        INNER JOIN Sales.Store S ON C.StoreID = S.BusinessEntityID
        INNER JOIN Person.Address SA ON SA.AddressID = SOH.ShipToAddressID -- Shipping address
        INNER JOIN Person.StateProvince SSP ON SA.StateProvinceID = SSP.StateProvinceID 
        INNER JOIN Person.CountryRegion SCR ON SSP.CountryRegionCode = SCR.CountryRegionCode 
        INNER JOIN Person.Address BA ON SOH.BillToAddressID = BA.AddressID -- Billing Address
        INNER JOIN Person.StateProvince BSP ON BA.StateProvinceID = BSP.StateProvinceID 
        INNER JOIN Person.CountryRegion BCR ON BSP.CountryRegionCode = BCR.CountryRegionCode 
        INNER JOIN Purchasing.ShipMethod SM ON SOH.ShipMethodID = SM.ShipMethodID 
        INNER JOIN [Sales].[SalesPerson] sp ON sp.[BusinessEntityID] = SOH.[SalesPersonID]  
        INNER JOIN [HumanResources].[Employee] e ON SOH.[SalesPersonID] = e.[BusinessEntityID] 
        INNER JOIN [Person].[Person] per ON per.[BusinessEntityID] = sp.[BusinessEntityID]
        INNER JOIN Person.PersonPhone ph ON per.[BusinessEntityID] = ph.[BusinessEntityID]
        INNER JOIN Sales.SalesOrderDetail SD ON SD.SalesOrderID = SOH.SalesOrderID
        INNER JOIN Production.Product P ON SD.ProductID = P.ProductID 
    WHERE (SOH.SalesOrderID BETWEEN (@SalesOrderIDStart) AND (@SalesOrderIDEnd))
    

该数据集查询返回一定范围内的多个销售订单的数据。

配置报表参数 @SalesOrderIDStart

  1. 打开 @SalesOrderIDStart 的**“参数属性”**。

  2. 将**“提示”**改为 First Order ID?

  3. 将**“数据类型”改为“整数”**。

  4. 在**“默认值”**上,添加一个值并将其设置为 57030。

配置报表参数 @SalesOrderIDEnd

  1. 打开 @SalesOrderIDEnd 的**“参数属性”**。

  2. 将**“提示”**改为 Last Order ID?

  3. 将**“数据类型”更改为“整数”**。

  4. 在**“默认值”**上,添加一个值并将其设置为 57032。

向页眉添加名称和编号

添加页名称

  1. 在页眉中,向包含 [&ReportName] 的文本框在一个新行上添加以下文本:页面名称:。

  2. 在“报表数据”窗格中,展开**“内置字段”,然后将“页面名称”**拖至您刚添加的文本旁边。

  3. 单击报表背景以便在“属性”窗格中显示**“报表属性”**。

  4. 在**“InitialPageName”**中,键入 SalesOrder。

  5. 在“分组”窗格中,单击 SalesOrderID 组。验证“Tablix 成员”属性出现在“属性”窗格中。

  6. 展开**“组”,找到“PageName”**,然后键入 =Fields!SalesOrderNumber.Value。

如果将此文件导出到 Excel,则选项卡名称将基于页面名称。

添加页码

  1. 在页眉中,添加具有以下文本的文本框:

    • 销售订单页:第 [&PageNumber] 页,共 [&TotalPages] 页

    • 报表页:第 [&OverallPageNumber] 页,共 [&OverallTotalPages] 页

  2. 在“分组”窗格中,单击 SalesOrderID 组。

  3. 在“属性”窗格中,确认已选定某个**“Tablix 成员”。依次展开“组”**和 PageBreak,并将 ResetPageNumber 设置为 true。

逐页浏览该报表时,将同时显示针对组的页码和针对整个报表的页码。

添加报表用户说明

添加指导报表用户返回到主报表的说明

  1. 就在此页眉之下,添加一个文本框,用来包含指导最终用户如何返回到主报表的说明。添加以下文本:

    使用浏览器的“后退”按钮返回父报表。

  2. 按需设置文本框的格式。

添加并配置列表

添加具有组行的列表

  1. 在应用场景切换文本说明中,插入一个**“列表”**。

    默认情况下,列表在一个详细信息行中包含一个 Tablix 单元。在步骤 2-6 中,您将添加一个组行并删除详细信息行,以便列表在一个组行中包含一个 Tablix 单元。

  2. 从 SalesOrder 数据集,将 [SalesOrderID] 拖到“分组”窗格中的“行组”,并将其放到详细信息组上方。

  3. 在“分组”窗格中,右键单击“详细信息”组,然后单击**“删除组”**。

  4. 在**“删除组”对话框中,单击“删除组以及相关的行和列”**。

  5. 在所选列表中,验证行句柄显示一个方括号,这指示单一行组。

  6. 右键单击第一列的行控点,然后单击**“删除列”**。

  7. 在**“删除列”对话框中,单击“仅删除列”**。

    Tablix 现在具有一个单元,该单元包含一个矩形并按 [SalesOrderID] 分组。此矩形是针对有关单个销售订单的信息的容器。在后面的步骤中,您将向此容器添加销售订单表头和销售订单明细。

  8. 右键单击该单元,然后单击**“矩形属性”**。

  9. 将名称更改为 OrderHeader_Contents。

  10. 在“分组”窗格中,右键单击 SalesOrderID 组,然后打开**“组属性”**。

  11. 在**“分页符”上,选择“在组的各实例之间”**。

  12. 在设计上,每个销售订单都以新页开始。

验证列表配置

  1. 单击列表中的空单元,在工具栏上将**“背景色”设置为“烟白色”**。当您处理矩形中嵌套的项时,这有助于您看到容器。

  2. 若要验证列表配置,请执行以下操作:

    1. 从数据集 SalesOrder 中,将 SalesOrderID 和 TotalDue 拖到矩形中。

    2. 右键单击 SalesOrderID,指向**“汇总方式”,然后单击“第一个”**。

      由于这是一个组行,应对表达式中的字段使用聚合函数。

    3. 将 TotalDue 的格式设置为货币。

    4. 运行报表。

    对于每个销售订单实例,该列表都显示在新的一页上并显示销售订单号和销售总额。总共应该有三页,分别对应销售订单 57030、57031 和 57032。逐页浏览该报表时,页眉值将随之变化。

    使用此报表提供单个销售订单的详细信息时,请将 @SalesOrderIDStart@SalesOrderIDEnd 设置为同一 SalesOrderID。

  3. 在“设计”视图中,从列表中删除文本框。

生成订单表头布局

您将在两个单独的矩形容器中生成订单表头布局,然后组合它们,并向列表添加外层矩形。

  1. 一个父矩形容器,其中包含徽标、订单号以及 OrderHeaderData 矩形。

  2. 一个名为 OrderHeaderData 的矩形容器,用于订单表头数据字段。当您生成此布局时,这可帮助您设计以下三个垂直部分中的信息:

    1. 结算和装运信息

    2. 商店联系人信息

    3. 其他信息:日期、销售人员、采购订单号和装运方式

在矩形容器中生成订单表头

  1. 在列表外部,插入一个**“矩形”**。

  2. 将徽标从页眉移到矩形。

  3. 添加一个文本框以及以下文本:

    1. 销售订单

    2. 订单号:[SalesOrderNumber]

  4. 将徽标拖到容器的左侧,并将文本框拖到右侧。按需设置格式。

为订单表头数据字段添加一个矩形

  1. 在列表外部,插入一个**“矩形”**,然后将名称更改为 OrderHeaderData。

  2. 在页上展开矩形,以便提供空间来容纳所有销售订单表头信息。

向此矩形添加在下面各过程中介绍的每个垂直信息部分。

生成结算和装运信息部分

  1. 添加文本框。在编辑模式中,键入 Bill to:

  2. 添加显示以下文本行的文本框:

    1. [Name]

    2. [BillAddress1]

    3. [BillCity], [BillStateProvince] [BillPostalCode]

    4. [BillCountryRegion]

  3. 添加文本框。在编辑模式中,键入 Ship to:

  4. 添加显示以下文本行的文本框:

    1. [Name]

    2. [ShipAddress1]

    3. [ShipCity], [ShipStateProvince] [ShipPostalCode]

    4. [ShipCountryRegion]

  5. 使这些文本框的顶部对齐。

生成商店联系人信息部分

  1. 添加文本框。在编辑模式中,键入 Contact:

  2. 插入**“子报表”**,并执行以下操作:

    1. 在**“常规”**页上,选择子报表 Store_Contacts_2008R2。

    2. 在**“参数”**页上,添加一个参数。

    3. 将**“名称”设置为 StoreID,将“值”**设置为 [BusinessEntityID]。

  3. 使文本框和子报表的顶部对齐。

生成其他信息部分

  1. 添加显示以下文本行的文本框:

    1. 日期

    2. 占位符文本。将标签设置为 ProcessedDate,将值设置为 [&ExecutionTime]。

  2. 添加显示以下文本行的文本框:

    1. Order Date

    2. [OrderDate]

  3. 添加显示以下文本行的文本框:

    1. Sales Person

    2. [SalesPerson], [JobTitle]

    3. [PhoneNumber]

  4. 添加显示以下文本行的文本框:

    1. Purchase Order

    2. [PurchaseOrderNumber]

  5. 添加显示以下文本行的文本框:

    1. Shipment Method

    2. [ShipMethod]

  6. 将这些文本框的顶部对齐并按需调整其宽度。

合并订单表头信息并将其移到列表中

  1. 抓住 OrderHeaderData 矩形,并将其拖至徽标之下。

  2. 将销售订单表头矩形拖至列表。

  3. 包含徽标的矩形将扩展以包括订单数据。

    此列表单元将扩展以包含销售订单表头信息。

生成销售订单明细布局

显示行项,包括每个销售订单的行项编号。

添加用于显示行项的表

  1. 在列表中,抓住行控点并扩展行高度。

  2. 在您刚创建的空间中的销售订单表头之下,插入一个**“表”**。

  3. 在表中,将以下数据从 SalesOrder 数据集拖到详细信息行:

    1. [OrderQty]

    2. [ProductNumber]

    3. [ProductName]

    4. [CarrierTrackingNumber]

    5. [UnitPrice]

    6. 添加占位符文本。将标签设置为 [Subtotal],将值设置为以下表达式:=Fields!OrderQty.Value * Fields!UnitPrice.Value

    7. 添加占位符文本。将标签设置为 [Discount],将值设置为以下表达式:=0 - Fields!UnitPrice.Value * Fields!OrderQty.Value * Fields!UnitPriceDiscount.Value

    8. [LineTotal]

      注意注意

      请注意此文本框名为 ItemTotal。稍后,当您编写表达式来为页上的所有项计算总计时,将使用此文本框名称。

  4. 在表的开头插入一列。

  5. 在列标题中,键入 Line。

  6. 在行中的文本框中,键入 =RowNum("OrderDetail")

  7. 按需设置格式。

添加总计行

  1. 右键单击包含 [Qty] 的单元,然后单击**“添加总计”**。

  2. 在最后一行的文本框中,于第四列中键入 Total Discount:。

  3. 在相邻的文本框中,添加占位符文本。

  4. 将标签设置为 Total Discount,将值设置为 =Sum(Fields!UnitPrice.Value * Fields!OrderQty.Value * Fields!UnitPriceDiscount.Value)。

  5. 在最后一行的文本框中,于第八列中键入 Total:。

  6. 在相邻的文本框中,添加占位符文本。

  7. 将标签设置为 Grand Total,将值设置为 [Sum(LineTotal)]。

  8. 按需设置格式。

  9. 删除文本框、表和矩形之间的所有多余空间。

在销售订单明细表中每隔 25 行定义一个分页符

为详细信息组设置每隔 25 行插入一个分页符

  1. 在“分组”窗格中,右键单击 OrderDetails_Details_Group,指向**“添加组”,然后单击“父组”**。

  2. 添加一个组,并使用以下表达式:=Ceiling(RowNumber("OrderDetail")/25)

  3. 在**“分页符”页上,选择“在组的各实例之间”**。

为 RunningTotals 定义报表变量

添加报表变量

  1. 右键单击报表背景,然后打开**“报表属性”**。

  2. 在**“变量”**页上,添加名为 RunningTotal 的报表变量。

  3. 将**“值”**设置为 =0.0

定义自定义代码以计算累加总计

添加自定义代码

  1. 右键单击报表背景,然后打开**“报表属性”**。

  2. 在**“代码”**页上,添加以下代码:

    Public Function AddToVariable(var As Microsoft.ReportingServices.ReportProcessing.OnDemandReportObjectModel.Variable, ByVal increment As Double) As Double 
       var.Value = var.Value + increment
       return var.Value
    End Function 
    
    Public Function GetOrResetVariable(var As Microsoft.ReportingServices.ReportProcessing.OnDemandReportObjectModel.Variable, ByVal executeReset As Boolean) 
       if executeReset then
           var.Value = 0
       end if 
       return var.Value
    End Function
    

添加说明

添加说明

  1. 在页脚中插入一个**“矩形”**。

  2. 将说明文本框移到矩形。

  3. 用下列文本替换说明:

    用途:明细报表。显示一系列订单的明细,并且它是 Employee_Sales_Summary_2008R2 中某个单独销售订单的一个钻取报表。包含自由格式布局、用作列表和表的 Tablix、子报表、用于计算累加页总计的会话变量、自定义代码、图像、基于表达式的分页符(基于明细行的编号)、页面名称、报表和组中的页编码以及有条件隐藏的文本。

  4. 单击报表背景以便在“属性”窗格中显示**“报表属性”**。

  5. 在**“说明”**中,粘贴说明文本。

在页脚中显示累加页总计

添加累加页总计

  1. 添加具有以下文本的文本框:Previous Page Total

  2. 添加具有以下表达式的相邻文本框:

    =Code.GetOrResetVariable(Variables!RunningTotal, Globals!OverallPageNumber = 1)

  3. 添加具有以下文本的文本框:Current Page Total

  4. 添加具有以下表达式的相邻文本框:

    =Sum(ReportItems!ItemTotal.Value)

  5. 添加具有以下文本的文本框:累加页总计

  6. 添加具有以下表达式的相邻文本框:

  7. =Code.AddToVariable(Variables!RunningTotal, Sum(Reportitems!ItemTotal.Value))

添加间隔文本框

说明文本具有条件可见性。当隐藏说明时,页总计文本呈现在页面的左侧。为了使页总计文本的位置保持在右侧,必须添加一个不具有条件可见性的文本框。

添加间隔文本框

  1. 在该矩形中的说明上方添加另一个文本框。

  2. 将该文本框设置为与矩形相同的宽度。

空文本框将在说明不可见时显示累加总计。

预览并验证

部署并检查报表

  • 预览报表并验证以下内容:

    1. 商店标题和详细信息区域按预期呈现。

    2. 子报表显示商店联系信息。

    3. 为当前页和上一页计算页总计。

    4. 无论说明文本是否可见,页总计将呈现在同一个位置。

后续步骤

您已生成了此报表。若要生成其他 AdventureWorks 示例报表,请参阅教程:创建 AdventureWorks 2008R2 示例报表 (SSRS)

请参阅

其他资源

更改历史记录

更新的内容

  • 已将报表更改为基于 AdventureWorks2008R2_Base.rdl