Sum Lookup field from a different dataset - reporting-services

I have 2 datasets that I need to populate one table. Dataset 1 contains values that Dataset 2 may not contain. Dataset 2 contains multiple values that I need to get the Sum of. Dataset 2 will always have a matching value (Division_Code) that is contained in Dataset 1.
I need the full list of data from DataSet1, even if no data exists in Dataset2.
Dataset 1 fields:
Division_Code,
Long_Name
Dataset 2 fields:
Division_Code,
TotalBillable,
Date
i.e. Dataset 1:
Division_Code
Long_Name
01
Health
02
Safety
03
Finance
04
Tax
i.e. Dataset 2:
Division_Code
TotalBillable
Date
01
$200
06/01/2022
01
$100
06/08/2022
01
$200
06/12/2022
02
$800
06/01/2022
04
$100
06/05/2022
I need results like this:
Division_Code
Long_Name
Sum(TotalBillable)
01
Health
$500
02
Safety
$800
03
Finance
0
04
Tax
$100
I have tried a variety of Lookups and SumLookup expressions and all result in errors. Can anyone offer guidance on how to write an expression that would accomplish what I need? Thanks in advance.

Use this Custom Code in Report Builder Properties:
Function SumLookup(ByVal items As Object()) As Decimal
If items Is Nothing Then
Return Nothing
End If
Dim suma As Decimal = New Decimal()
Dim ct as Integer = New Integer()
suma = 0 ct = 0
For Each item As Object In items
suma += Convert.ToDecimal(item)
ct += 1
Next
If (ct = 0) Then return 0 else return suma
End Function
Then use the following expression in your report field
=Code.SumLookup(LookupSet(Fields![LookupDataset1FieldName].Value, Fields![LookupDataset2FieldName].Value, Fields![ResultField].Value, "DataSet2"))

Related

Display Measure depending on Date, combine two measure from different dates

Background:
I am preparng a dataset for a report.
To simplify lets say it is two measures, one Category and a time dimension.
The main Report Parameter is todays date.
I would like to see the first Measure from yesterday (Value 000) and the second measures
from the day before yesterday (Value 001). Because previous days data is not available yet for Value 001.
Lets assume 2020-04-27 is today (passed on from the Reporting Tool SSRS).
AS-IS
SELECT {[Measures].[Value 000], [Measures].[Value 001]} ON COLUMNS
, ( {[DIM Category].[Category].&[1], [DIM Category].[Category].&[2]},
[DIM Date].[Y-M-D ISO].[Date].[2020-04-27].LAG(2): [DIM Date].[Y-M-D ISO].[Date].[2020-04-27].LAG(1)
)
ON ROWS
FROM [My_Cube]
Output:
[Value 000] [Value 001]
Category 1 2020-04-25 88 16
Category 1 2020-04-26 89 (null)
Category 2 2020-04-25 90 14
Category 2 2020-04-26 92 (null)
I tried two MDX-Queries for each date and combined the Sets in the Reporting tool but I am wondering if there is a comfortable way to do that in one MDX query.
The following would be the desired output.
To-Be
Output:
[Value 000] [Value 001]
Category 1 89 16 (Value from day before, for Value 0001)
Category 2 92 14
The Date doesn't need to be shown in the output (but can be)
You can solve the issue by using calculated measures. Follwoing example is based on adventureworks . I want to rebuild your senario for Jan 23 2013
The initial query is there to show values for yesterday abd day before
with
member measures.Yesterday
as
sum([Date].[Date].currentmember.lag(1),[Measures].[Internet Sales Amount])
member measures.DayBefore
as
sum([Date].[Date].currentmember.lag(2),[Measures].[Internet Sales Amount])
select
{
[Measures].[Internet Sales Amount],measures.Yesterday ,measures.DayBefore
}
on columns,
{
([Product].[Category].[Category],[Date].[Date].&[20130120]:[Date].[Date].&[20130123])
}
on rows
from
[Adventure Works]
where [Date].[Date].&[20130123]
Result
Now lets remove the date from the rows and put it in where
with
member measures.Yesterday
as
sum([Date].[Date].currentmember.lag(1),[Measures].[Internet Sales Amount])
member measures.DayBefore
as
sum([Date].[Date].currentmember.lag(2),[Measures].[Internet Sales Amount])
select
{
[Measures].[Internet Sales Amount],measures.Yesterday ,measures.DayBefore
}
on columns,
{
([Product].[Category].[Category])
}
on rows
from
[Adventure Works]
where [Date].[Date].&[20130123]
Result

How to access counts to calculate the difference in a SSRS matrix with column and row groups

I’m building a report in Visual Studio 2017 (SSRS) and it uses a stored procedure that returns the following data:
PRODUCT_ID TYPE YEAR STATUS
15242 01 1516 ACTIVE
54541 02 1617 ACTIVE
64454 01 1516 INACTIVE
73697 02 1516 INACTIVE
98878 03 1617 ACTIVE
I needed to get the counts per status, per year, per type, so I started building a matrix with STATUS as first column group and YEAR as its child, then, in the row group I only have TYPE. In the data fields I only have the count, so it looks like this:
ACTIVE INACTIVE
1516 1617 1516 1617
01 1 0 1 0
02 0 1 1 0
03 0 1 0 0
My problem is the following. I want add a DIFF column (example below) that calculates the difference between the two years, but the problem is that since all is done dynamically, I don’t know how to access the text boxes with the counts to calculate the difference. I could build a stored procedure that calculates all those numbers, but it would be a slower solution since the field TYPE will grow over time.
ACTIVE INACTIVE
1516 1617 DIFF 1516 1617 DIFF
01 1 0 1 1 0 1
02 0 1 1 1 0 1
03 0 1 1 0 0 0
Any help will be appreciated. Thank you guys in advance.
I don't think you'll be able to make a matrix work the way you want without using a bunch of LookUps that would kill performance.
I would make a regular table and filter the data in the expression to separate the years. You'll have to figure out some logic based on your data to determine which year is the current and which is the last year.
You would use the same grouping for the TYPE as you do now.
Assumeing you have identified the previous can current year:
=SUM(IIF(Fields!YEAR.Value = Parameter!Current_Year.Value, 1, 0)
For the DIFF column, use
=SUM(IIF(Fields!YEAR.Value = Parameter!Current_Year.Value, 1, 0) - SUM(IIF(Fields!YEAR.Value = Parameter!Previous_Year.Value, 1, 0)
You could use a variable or a Field in your query to identify the current year - it doesn't need to be a parameter.
You could still use the matrix for your Statuses (Stati?) for the Active and Inactive.
I have found a way to calculate differences between matrix columns (available from SSRS 2008 and up) using the previous function. Look at my answer to this question. how to subtract adjacent columns in an ssrs matrix
how to subtract adjacent columns in an ssrs matrix

SSRS 2 column groups in matrix, 1 row reads from 1, the rest read from the other? (pls help)

Is there a way in SSRS to have an additional row within your row group, to look at a different column group than the rest of the row group
Let's say I have STATES, SALES, MONTH, and BUCKET_MONTH as my dataset fields BUCKET_MONTH is already calculated for me, based off of the MONTH. I want to show something like this:
SAMPLE DATA LIKE THIS FOR FLORIDA (and other months but BUCKET_MONTH only matters for florida let's pretend)
STATE MONTH SALES BUCKET_MONTH
FL JAN 50 FEB
FL FEB 125 FEB
FL MAR 100 MAY
FL APR 0 MAY
FL MAY 100 MAY
SSRS MATRIX MIGHT LOOK LIKE THIS: ?
| 2 groups ?
| MONTH
| BUCKET_MONTH (I can hide this header)
-----------------------------------
1 col group|
STATE | SALES
BUCKET | SALES <-- this row is only visibile for FL which I know how to do
EXPECTED RESULTS WOULD LOOK LIKE THIS
JAN FEB MAR APR MAY JUN JUL
---------------------------------------------------------------------
CA 100 300 150
FL 50 125 100 0 100
FL BUCKET 175 200 <-- BUCKET_MONTH**
MA 0 200 250 50
BUCKET_MONTH in ds shows FEB for the rows with Jan,Feb MONTH, and shows MAY for Mar,Apr, May MONTH
Is there a way to do this in SSRS? Where one of the rows looks at a different column group to establish what column to put the SUM of SALES in?
Much appreciation in advance!
You have to add BUCKET_MONTH as parent column group in your matrix.
Add BUCKET_MONTH in the Column Groups pane, then delete the created row in the matrix selecting Delete groups only option. Now add MONTH as child group in column groups pane.
Add STATE in rows group pane and add a row for bucket total.
Use this expression for BUCKET TOTAL:
=IIF(
Fields!BUCKET_MONTH.Value=Fields!MONTH.Value,
SUM(Fields!SALES.Value,"BUCKET_MONTH"),
Nothing
)
It should produce:
UPDATE: Expression updated taking in account that MONTH and BUCKET_MONTH fields are actually dates.
=IIF(
UCASE(format(Fields!BUCKET_MONTH.Value,"MMMM yy"))=
UCASE(format(Fields!MONTH.Value,"MMMM yy")),
SUM(Fields!SALES.Value,"BUCKET_MONTH"),
Nothing
)
Let me know if this helps.

SSRS Groups, Aggregated Group after detailed ones

in SSRS, I try to create a group structure as in the example below (months have only 5 days here for simplicity). The tricky issue is the last column "Sales(monthly)": It should be a Row Group, grouping by month, after the more detailed columns "Day" and "Sales(daily)". It would be no problem to have this column as the second one between "Month" and "Day" column.
But after being already on the "detail level" with "Day" and "Sales(daily)", I cannot create another more aggregated group. And if I just set Group Properties, Group On to Month for the 4th column, then "Day" and "Sales(daily)" also appear aggregated with only 1 row per month.
Does anybody know how to solve this? Or is this just not possible in SSRS?
Month Day Sales(daily) Sales(monthly)
Feb 1 100 615
2 150
3 130
4 125
5 110
March 1 100 685
2 150
3 200
4 125
5 110
April 1 100 560
2 150
3 75
4 125
5 110
Many thanks
Mike
There's not a native way to do this in SSRS.
You would need use LookupSet to get the daily sales for the month and then use a custom function (SumLookup) to get the total.
Then you need to use an IIF so that you only display it on DAY 1.
=IIF(Fields!DAY.VALUE <> 1, NOTHING,
Code.SumLookup(LookupSet(Fields!MONTH.Value, Fields!MONTH.Value, Fields!SALES.Value, "Dataset1")))
Function code:
Function SumLookup(ByVal items As Object()) As Decimal
If items Is Nothing Then Return Nothing
Dim suma As Decimal = New Decimal()
Dim ct as Integer = New Integer()
suma = 0
ct = 0
For Each item As Object In items
suma += Convert.ToDecimal(item)
ct += 1
Next
If (ct = 0) Then return 0 else return suma
End Function
SSRS:
Use LookupSet to retrieve a set of values from the specified dataset
for a name-value pair where there is a 1-to-many relationship. For
example, for a customer identifier in a table, you can use LookupSet
to retrieve all the associated phone numbers for that customer from a
dataset that is not bound to the data region.

SSRS - Returning the average where date is 2015

I have been trying to figure this out for a while now and just couldn't find the answer anywhere.
I have a report in SSRS with a column group assigned to "Year", this column expands depending on what parameter the user enters into StartYear. If the user enters "2013" the report will extract all data from 2013 to 2015, this means that there are then 3 columns with the same name ("Cost").
My report looks something like this when entering StartYear as "2013" the value beneath "Year" displays the "Cost" column :
Area | 2013 ("Year") | 2014 ("Year") | 2015 ("Year")
A | 20 | 50 | 25
B | 15 | 65 | 35
C | 40 | 70 | 20
Before the report get built, the reports looks something like this:
Area | [Year]
[Area] | [Cost]
I want to add a column to this report which displays the Average but only for the Year 2015.
This is what I have tried sofar but it brings back the Average for one row and all the year : 20, 50 and 25 instead of 25, 35 and 20:
=Sum(IIF(Fields!Year.Value = 2015, Avg(Fields!Cost.Value), 0))
Any help would be greatly appreciated.
You need an expression like:
=Avg(IIF(Fields!Year.Value = 2015, Fields!Cost.Value, Nothing))
If you are using an IIf expression to get a subset from a DataSet, you must specify Nothing as the False part of the expression, otherwise you just get a bunch of zeroes included in the aggregate, skewing the results.
This assumes the aggregate is running outside any particular Group Scope - you can always add a Scope to the expression to make sure you are checking the entire DataSet:
=Avg(IIF(Fields!Year.Value = 2015, Fields!Cost.Value, Nothing), "DataSet1")
Edit after comment
To expand on the Scope comment above, you can specify the aggregate to run at the Row Group level by adding the Row Group name as a parameter to the expression:
=Avg(IIF(Fields!Year.Value = 2015, Fields!Cost.Value, Nothing), "Area")
Assuming Area is the name of the Row Group.