基本的に、レイアウトとして以下のスクリーンショットがあります。
私の行列列はDCG1とDCG2です。
マトリックスの最後に、私はトータルグループを持っています。しかし、私はグループの最初と最後の値の違いを見つけたいと思っています。 ReportItemsからすべてを試しました!値に。 SSRSにこれらの値を認識させることができません。
したがって、基本的には以下のスクリーンショットにあります。スクリーンショット1はマトリックス構造です。 Test1という列グループがあり、Test1の最初の値とTest 1の最後の値が必要で、それを赤いボックスに配置します。
スクリーンショット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)、 合計DECIMAL(10、2)、 Test1 NVARCHAR(50) ) INSERT INTO #tmpHoldingTable(dcs1、 dcs2、 Total、 Test1) VALUES( 'Contract'、 '違反契約 '、 500.00、 ' 01/01/2013-12/31/2013 ')、 ('契約 '、 '契約違反 ' 、 300.00、 '01/01/2014-12/31/2014 ')、 (' Employment '、 ' Discrimination '、 500.00、 '01/01/2013-12/31/2013 ')、 (' Empl oyment '、 '差別 '、 300.00、 '01/01/2014-12/31/2014')、 ( '雇用'、 '調査'、 500.00、 '01/01/2013-12/31/2013 ')、 ('雇用 '、 'Research'、 300.00、 '01/01/2014-12/31/2014 ') SELECT * FROM #tmpHoldingTable;
はい、これは可能ですが、ご覧のとおり、少し複雑です。
これをより一般的な答えにするために、列を簡略化してデータを増やした独自の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)
各grp/dtの組み合わせには2つの値があり、grp 1
はdtgrp 2
より。
これに基づいて簡単なマトリックスを作成しました。
SQL Server 2012を使用しているため、LookupSet
関数を使用して、行グループごとの最初/最後の値を取得できます。
First行グループ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"
)
)
私のサンプルデータに基づいて、これは私の必要な結果を与えています:
2番目の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
これは this 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"
)
LookupSet
は次のパラメータを取ります。
LookupSet(source_expression, destination_expression, result_expression, dataset)
この式では、現在のdt
スコープの最初のgrp
に一致するすべての値をDataSet1
から取得する必要があります。
source_expression
の場合:
First(Fields!dt.Value, "grp").ToString & Fields!grp.Value.ToString
これにより、行スコープの最初のdtが取得され("grp"
は行グループの名前)、これが現在のgrpに追加されます。 。これにより、DataSet1
で検索するときに同様の式に一致する式が作成されます。
つまり、destination_expression
:
Fields!dt.Value.ToString & Fields!grp.Value.ToString
最後に、Fields!val.Value
をresult_expression
として、DataSet1
をdataset
パラメーターとして指定します。
Fields!val.Value
内の一致するすべてのDataSet1
値は、LookupSet
によって配列に構築され、次にCode.SumLookup
によって集約されます。
最後の値の式を更新します
LastTextBoxの式は実質的に同じです。 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"
)
)
違いを得る
最後に、これらの差を取得するには、DifferenceTextBoxで一方の式を他方から減算するか、ReportItems
値を参照します。 :
=ReportItems!Last.Value - ReportItems!First.Value
ここで、Last
とFirst
はTextBoxの名前です。
結論
明らかに、特定のケースに合わせて更新する必要がありますが、これが実行できることがわかります。
レポートでこれを行う価値はありますか?多くの手順が含まれていることがわかります。一般に、DataSetを生成するときに対処する方が簡単です。しかし、それが選択肢ではない場合は、このLookupSet
アプローチが役立つことを願っています。
AFAIKこれはSSRSだけでは不可能です。私が試したと信じてください。幸い、SQLデータソースがあるので、データを形成および操作するための(ほぼ)無制限の権限がある場合に、この要件を解決します。
たとえば、最終的な選択を次のように置き換えます。
; WITH CTE_Base AS ( SELECT * FROM #tmpHoldingTable ) , CTE_Test1 AS ( SELECT Test1 , ROW_NUMBER () OVER ( ORDER BY Test1 ) AS Column_Number_Test1 FROM CTE_Base GROUP BY Test1 ) SELECT CTE_Base.* , CTE_Test1.Column_Number_Test1 , CASE WHEN CTE_Test1.Column_Number_Test1 = 1 THEN Total WHEN CTE_Test1.Column_Number_Test1 = ( SELECT MAX ( Column_Number_Test1 ) FROM CTE_Test1 ) THEN 0 - Total ELSE 0 END AS [Difference] FROM CTE_Base INNER JOIN CTE_Test1 ON CTE_Base.Test1 = CTE_Test1.Test1
これにより、[Difference]列が追加され、最初の列に[Total]のコピーが追加され、最後の列に0- [Total]が追加されます。
SQLはおそらくより効率的にすることができますが、うまくいけば、SQLをCTEに分割する方が簡単です。
次に、SSRSデザイナで、[Test1]列グループの外に[Difference]列を追加し、合計することができます(デフォルト)。
ところで、テストデータは少し単純に見えます。2列しか生成されず、すべてのセルに値があります。しかし、DDLとDMLを投稿したことは素晴らしいことです。データとコードを拡張し、これをテストするのが簡単になりました。