SSRS如何获取矩阵行组的第一个和最后一个值?

8 matrix reporting-services ssrs-2012

我基本上将截图作为我的布局.

我的矩阵列是DCG1和DCG2.

在Matrix结束时,我有一个Total Group,它可以找到.但我想找到我的第一个和最后一个价值组之间的差异.我已经尝试过ReportItems的所有内容!价值观.我不能让SSRS识别这些值.

所以基本上在下面的屏幕截图中.屏幕截图1是矩阵结构.我有一个名为Test1的列组,我想要Test1的第一个值和Test 1的最后一个值,并将其放在Red框中.

在屏幕截图2中,您可以看到我想要比较的值.表分组的名称与列+组相同.所以dcs1group/dcs2group

在此输入图像描述

在此输入图像描述

好的,这里是数据源的DDL和DML

http://pastebin.com/1ySN701D

已删除了pastebin.为什么,不确定如此,它在下面.

IF EXISTS
      (SELECT [name]
         FROM tempdb.sys.tables
        WHERE [name] LIKE '%tmpHoldingTable%')
   BEGIN
      DROP TABLE #tmpHoldingTable;
   END;


CREATE TABLE #tmpHoldingTable
(
   dcs1    NVARCHAR (50),
   dcs2    NVARCHAR (50),
   Total   DECIMAL (10, 2),
   Test1   NVARCHAR (50)
)

INSERT INTO #tmpHoldingTable (dcs1,
                              dcs2,
                              Total,
                              Test1)
VALUES ('Contract',
        'Breach of Contract',
        500.00,
        '01/01/2013-12/31/2013'),
       ('Contract',
        'Breach of Contract',
        300.00,
        '01/01/2014-12/31/2014'),
       ('Employment',
        'Discrimination',
        500.00,
        '01/01/2013-12/31/2013'),
       ('Employment',
        'Discrimination',
        300.00,
        '01/01/2014-12/31/2014'),
       ('Employment',
        'Research',
        500.00,
        '01/01/2013-12/31/2013'),
       ('Employment',
        'Research',
        300.00,
        '01/01/2014-12/31/2014')

SELECT * FROM #tmpHoldingTable;

Ian*_*ton 7

是的,这是可能的,但你可以看到它有点复杂.

为了使这个更通用的答案,我创建了自己的DataSet,其中包含简化列但更多数据:

select grp = 1, val = 100, dt = cast('01-jan-2015' as date)
union all select grp = 1, val = 110, dt = cast('01-jan-2015' as date)
union all select grp = 1, val = 200, dt = cast('02-jan-2015' as date)
union all select grp = 1, val = 210, dt = cast('02-jan-2015' as date)
union all select grp = 1, val = 300, dt = cast('03-jan-2015' as date)
union all select grp = 1, val = 310, dt = cast('03-jan-2015' as date)
union all select grp = 1, val = 400, dt = cast('04-jan-2015' as date)
union all select grp = 1, val = 410, dt = cast('04-jan-2015' as date)
union all select grp = 1, val = 500, dt = cast('05-jan-2015' as date)
union all select grp = 1, val = 510, dt = cast('05-jan-2015' as date)
union all select grp = 2, val = 220, dt = cast('02-jan-2015' as date)
union all select grp = 2, val = 230, dt = cast('02-jan-2015' as date)
union all select grp = 2, val = 320, dt = cast('03-jan-2015' as date)
union all select grp = 2, val = 330, dt = cast('03-jan-2015' as date)
union all select grp = 2, val = 420, dt = cast('04-jan-2015' as date)
union all select grp = 2, val = 430, dt = cast('04-jan-2015' as date)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

请注意,每个grp/dt组合都有两个值,grp 1对于dt而言,这个值的范围更长grp 2.

我基于此创建了一个简单的Matrix:

在此输入图像描述

由于您使用的是SQL Server 2012,因此可以使用该LookupSet函数获取每行组的First/Last值.

第一行组TextBox中的表达式为:

=Code.SumLookup(
    LookupSet(
        First(Fields!dt.Value, "grp").ToString & Fields!grp.Value.ToString
        , Fields!dt.Value.ToString & Fields!grp.Value.ToString
        , Fields!val.Value
        , "DataSet1"
    )
)
Run Code Online (Sandbox Code Playgroud)

根据我的示例数据,这给出了我所需的结果:

在此输入图像描述

请注意,第二grp行的范围比第一行的范围窄,但其第一列/最后一列对于每个组都是独立的,因此每个列都是正确的grp.这里有很多事情要发生.

用于聚合LookUpSet结果的自定义代码

LookupSet表达被包裹在一个Code.SumLookup自定义函数:

Function SumLookup(ByVal items As Object()) As Decimal
  If items Is Nothing Then
    Return Nothing
  End If

  Dim suma As Decimal = New Decimal()
  suma = 0

  For Each item As Object In items
    suma += Convert.ToDecimal(item)
  Next

  Return suma
End Function
Run Code Online (Sandbox Code Playgroud)

这是从这个 SO问题的答案中得出的.

这假设每个矩阵单元可以是多个值的总和,因此需要总结.LookupSet返回由...聚合的值数组Code.SumLookup.

细节 LookupSet

接下来,LoopupSet表达式本身:

    LookupSet(
        First(Fields!dt.Value, "grp").ToString & Fields!grp.Value.ToString
        , Fields!dt.Value.ToString & Fields!grp.Value.ToString
        , Fields!val.Value
        , "DataSet1"
    )
Run Code Online (Sandbox Code Playgroud)

LookupSet 采用以下参数:

LookupSet(source_expression, destination_expression, result_expression, dataset)
Run Code Online (Sandbox Code Playgroud)

在我们的表达式中,我们希望从DataSet1该匹配dt中获取当前grp范围中的第一个值.

对于source_expression我使用:

First(Fields!dt.Value, "grp").ToString & Fields!grp.Value.ToString
Run Code Online (Sandbox Code Playgroud)

这将获取行范围中的第一个dt("grp"是行组的名称),然后将其附加到当前grp.这会创建一个表达式,以便在搜索时匹配类似的表达式DataSet1.

destination_expression:

Fields!dt.Value.ToString & Fields!grp.Value.ToString
Run Code Online (Sandbox Code Playgroud)

最后,我们确定我们要Fields!val.Value作为result_expressionDataSet1作为dataset参数.

所有匹配的Fields!val.ValueDataSet1都被构造成一个数组LookupSet,然后通过聚合Code.SumLookup.

更新Last值的表达式

Last TextBox 的表达式几乎相同; 只需First改为Last:

=Code.SumLookup(
    LookupSet(
        Last(Fields!dt.Value, "grp").ToString & Fields!grp.Value.ToString
        , Fields!dt.Value.ToString & Fields!grp.Value.ToString
        , Fields!val.Value
        , "DataSet1"
    )
)
Run Code Online (Sandbox Code Playgroud)

获得差异

最后,为了得到这些差异,只需在差异文本框中从另一个中减去一个表达式,甚至引用这些ReportItems值:

=ReportItems!Last.Value - ReportItems!First.Value
Run Code Online (Sandbox Code Playgroud)

LastFirst是文本框的名称.

结论

显然,您需要根据具体情况进行更新,但您可以看到这可以完成.

在您的报告中是否值得这样做?您可以看到涉及许多步骤,并且通常在生成DataSet时更容易解决.但是,如果这不是一个选项,希望这种LookupSet方法是有用的.