汇总 SSRS 中的表达式

Totaling an expression in SSRS

我有一个表达式可以计算文本框中的值。我想,在报告的最后,该文本框中所有字段的总和。但是,该表达式使用查询中的命名字段,这些字段也被合计。

=SUM(Fields!Total_Defective__.Value) / SUM(Fields!sales_Dollars.Value)

Total_Defective__ 和 sales_Dollars 在报告末尾合计。因此,当我将该表达式放在该列的总计字段中时,它会计算其他列的总计。这会产生不正确的结果,因为它基于其他字段的总计。我想做的是对列求和。我试过 Use a summary field in an expression in SSRS reports 但这只给了我总数上面的行,你不能用它来聚合。

所以报告看起来像这样:

COQ 总计列计算的是次品美元/销售额的总和。我希望它添加列 (COQ) 为 $0.39

查询如下所示:

    --Prod Qty
SELECT Division as 'division', SUM(prodtable.qtysched)as 'qty',rtrim(Ltrim(itemgroupid)) as 'itemGroup'
into #SCHED
FROM MiscReportTables.dbo.PlantDivisions 
inner join prodtable on prodtable.dimension2_ = MiscReportTables.dbo.PlantDivisions.Division  
WHERE PlantID IN (@plantid)
and SCHEDDATE between @start and @end   
Group by itemgroupid,MiscReportTables.dbo.PlantDivisions.Division

--sales qty
Select Division as 'Division', SUM(SALESQTY) as 'salesQTY',rtrim(Ltrim(salesline.itemgroupid)) as 'itemGroup'
into #salesQty
FROM MiscReportTables.dbo.PlantDivisions 
inner join prodtable on prodtable.dimension2_ = MiscReportTables.dbo.PlantDivisions.Division
inner join SalesLine on SalesLine.InventrefId = ProdTable.ProdiD
WHERE PlantID IN (@plantid)
and SCHEDDATE between @start and @end
Group By Division,salesLine.itemgroupid

--SALES Dollars
Select Division as 'Division',
 (SUM(SALESQTY) - REMAINSALESFINANCIAL) * (SalesPrice / PriceUnit) as 'sales$',
 rtrim(Ltrim(salesline.itemgroupid)) as 'itemGroup'
into #salesDollars
FROM MiscReportTables.dbo.PlantDivisions 
inner join prodtable on prodtable.dimension2_ = MiscReportTables.dbo.PlantDivisions.Division
inner join SalesLine on SalesLine.InventrefId = ProdTable.ProdiD
WHERE PlantID IN (@plantid)
and SCHEDDATE between @start and @end
Group By Division,salesLine.itemgroupid,REMAINSALESFINANCIAL,SalesPrice,PriceUnit


SELECT
    dbo.TQMNCR.NCRID,
    dbo.TQMPlantTable.PlantName AS 'Division',
    RTRIM(LTRIM(dbo.INVENTTABLE.ITEMGROUPID)) AS 'Item Process/Group',
    dbo.TQMNCRDEFECTTYPECODES.QTY AS 'Defective Qty',
    CASE CATYPE
        WHEN 0 THEN 
            (CASE WHEN dbo.SALESLINE.SALESID = ''
                THEN ISNULL((PRICE * (PERCENTEXT / 100))  / NULLIF(dbo.INVENTTABLEMODULE.PRICEUNIT, 0), 0) * dbo.TQMNCRDEFECTTYPECODES.QTY
                ELSE ISNULL((SALESPRICE * (PERCENTEXT / 100))  / NULLIF(dbo.SALESLINE.PRICEUNIT, 0), 0) * dbo.TQMNCRDEFECTTYPECODES.QTY END)
        WHEN 2 THEN 
            (CASE WHEN dbo.TQMNCR.SALESID = ''
                THEN ISNULL((PRICE * (PERCENTINT / 100))  / NULLIF(dbo.INVENTTABLEMODULE.PRICEUNIT, 0), 0) * dbo.TQMNCRDEFECTTYPECODES.QTY
                ELSE ISNULL((SALESPRICE * (PERCENTINT / 100))  / NULLIF(dbo.SALESLINE.PRICEUNIT, 0), 0) * dbo.TQMNCRDEFECTTYPECODES.QTY END)
        ELSE 0 END AS 'Total Defective $',
    dbo.PRODTABLE.PRODPOOLID
    ,#SCHED.qty,
    (#SCHED.qty - dbo.TQMNCRDEFECTTYPECODES.QTY) / #SCHED.qty as 'First Pass Yield',
    #salesQty.salesQty as 'Sales Quantity',
    #salesDollars.sales$ as 'sales Dollars'
FROM
    dbo.TQMNCR LEFT OUTER JOIN
    dbo.TQMDISPOSITION ON dbo.TQMNCR.DISPOSITIONID = dbo.TQMDISPOSITION.DISPOSITIONID LEFT OUTER JOIN 
    dbo.TQMCA_TABLE ON dbo.TQMCA_TABLE.NCRID = dbo.TQMNCR.NCRID LEFT OUTER JOIN 
    dbo.TQMNCRDEFECTTYPECODES ON dbo.TQMNCR.NCRID = dbo.TQMNCRDEFECTTYPECODES.NCRID LEFT OUTER JOIN
    dbo.TQMPlantTable ON TQMPlantTable.PlantID  = dbo.TQMNCR.PlantID LEFT OUTER JOIN 
    dbo.INVENTTABLE ON dbo.TQMNCR.ITEMID = dbo.INVENTTABLE.ITEMID LEFT OUTER JOIN 
    dbo.INVENTTABLEMODULE ON dbo.INVENTTABLE.ITEMID = dbo.INVENTTABLEMODULE.ITEMID AND MODULETYPE = 2 LEFT OUTER JOIN 
    dbo.SALESLINE ON dbo.SALESLINE.SALESID = dbo.TQMNCR.SALESID AND dbo.SALESLINE.ITEMID = dbo.TQMNCR.ITEMID LEFT OUTER JOIN 
    dbo.PRODTABLE ON dbo.TQMNCR.PRODID = dbo.PRODTABLE.PRODID
    inner join #sched on #sched.itemGroup = INVENTTABLE.itemgroupid
    inner join #salesQty on #salesQty.itemGroup = INVENTTABLE.itemgroupid
    inner join #salesDollars on  #salesDollars.itemgroup = INVENTTABLE.itemgroupid
WHERE
    SCHEDDATE between @start and @end
    AND
    dbo.TQMNCR.PlantID IN (@plantid)
ORDER BY dbo.INVENTTABLE.ITEMGROUPID, dbo.TQMPlantTable.PlantName


drop table #sched
drop table #SalesQty
drop table  #salesDollars

结果集如下所示:

该报告按 Item_Process、部门、Total_Defective

分组

您可以尝试将 COQ 字段添加为数据集中的新计算字段。这样做将在数据集级别而不是 Tablix 分组级别执行计算。

假设您已将此新字段命名为 "COQ"。

然后在总计行中,将表达式 Sum(Fields!COQ.Value) 作为总计。

这应该先对每一行的COQ进行计算,然后将结果求和到总行中。

编辑:如果您的数据集完全按照您的 table 分组,则以上内容将起作用。如果情况并非如此(正如您所指出的),并且您在 SSRS 中的 table 实际上是从更细化的数据集中分组的,您可以使用以下表达式对您的组进行总计:

=Sum(IIF(Sum(Fields!sales_Dollars.Value,"YOURGROUPNAME") > 0,   
 Sum(Fields!Total_Defective__.Value,"YOURGROUPNAME") / 
 Sum(Fields!sales_Dollars.Value,"YOURGROUPNAME"), 0))

这应该评估 GROUP BY 的每个成员内的计算,然后对整个 table/dataset.

的计算结果求和

你应该可以用

做到这一点
=SUM(Fields!Total_Defective__.Value/Fields!sales_Dollars.Value)

以便它除以每个值,然后求和而不是在除法之前对值求和。

编辑:如果除以零错误,您可以将以下内容添加到报告 - 报告属性 - 代码:

Public Function Quotient(ByVal numerator As Decimal, denominator As Decimal) As Decimal
    If denominator = 0 Then
        Return 0
    Else
        Return numerator / denominator
    End If
End Function

(参考:http://williameduardo.com/development/ssrs/ssrs-divide-by-zero-error/

输入公式为

=SUM(code.Quotient(Fields!Total_Defective__.Value,Fields!sales_Dollars.Value)

那么你应该在你的表达式中用相对较短的代码得到想要的结果。

我相信您的要求超出了 SSRS 的能力范围。我会将分组移动到 SQL 数据集,并且(在你的示例中分组到 9 "detail" 行之后)我会计算该数据集中的 COQ,例如

SELECT *
, Total_Defective / Sales AS COQ
FROM (
  SELECT 
    MyGroupColumns
    , SUM ( Total_Defective ) AS Total_Defective 
    , SUM ( Sales ) AS Sales 
   FROM  MyTable
  GROUP BY
    MyGroupColumns
  ) D1

然后 SSRS 可以仅显示数据集输出的 9 行的详细 COQ,您可以使用 SSRS Sum() 函数获取总计行的 COQ。