SSRS Conditional Summing - reporting-services

I have an SSRS report that displays several pages of rows. In each row is a "TYPE" field. In that TYPE field there is either an "M" for the value or a "P" for the value. At the end of the report I want to summ up all the price values for the "P" TYPES. I tried this but it prioduced an #Error:
=Sum(iif(Fields!TYPE.Value = "P",Fields!EXT_QTY.Value * Fields!PRICE.Value ,0))
this summed all rows
=iif(Fields!PART_TYPE.Value = "P" , Sum(Fields!EXT_QTY.Value * Fields!PRICE.Value ), 0 )
I'm sure this is do-able. Any ideas? Thanks

Found the answer....
=SUM(IIF(Fields!PART_TYPE.Value ="P",CDbl(Fields!EXT_QTY.Value * Fields!PRICE.Value), CDbl(0.0)))

The SUM fails due to type comparison - you can't Sum values of different types, being the expression (probably a Double) with 0, an Integer. MikeTWebb's answer does explicit type conversion to get around this error. This is fine for this specific example, being a Sum, however this doesn't produce an accurate result if you want an average (being Sum / Count) of the values where the Type is P. That is because 0 is a value and would be included in the averaging calculation when you actually want those values excluded from the calculation.
Another option is to use Nothing instead of 0:
=Sum(IIF(Fields!TYPE.Value = "P", Fields!EXT_QTY.Value * Fields!PRICE.Value, Nothing))
This solves the type comparison error without needing explicit typecasting and is a better solution when you are using aggregations where whether the value exists or not is significant to the result, like Average.

Related

How to get group total inside a row in a rdl report?

How do I get the total of the group inside a row item?
I have tried Fields!Sales.Value/SUM(Fields!Sales.Value) but it returns 1 instead of the row_amount/group_total the report returns row_amount/row_amount
PS: Data comes from a SSAS cube. I made picture bellow1 to summarize what I wanna do
You could potentially just compare the values by the ReportItems. That is, you can specify a name for the sales textbox and for the totalsales textbox and do the comparison using those values. The following expression would likely work as intended.
= (ReportItems!SalesTextbox.Value / ReportItems!SalesTotalTextbox.Value) * 100.0
The other thing to consider with this is that if your result is 1, you may be dealing with integer division from your data. Make sure the data being returned is coming in with a double or decimal datatype, not an integer. It may work as you have it currently if you get the datatype corrected.
You also need to handle "divide by Zero' errors. Using an "=IIf (denominator = 0, 0, numerator/denominator) doesn't work since an "IIf" function evaluates both the "then" and the "else" and will still return an error. We use a bit of custom code that I found on SO (I wish I could remember where it came from so I could give credit where it's due).
Public Function HandleDivideByZero(ByVal numerator As Decimal, denominator As Decimal) As Decimal
If denominator = 0 Then
Return 0
Else
Return numerator / denominator
End If
End Function

Need to exclude zero values from SSRS SSDT Report calculations in Field expression window

I have Productivity calculation as TotalMinutes/(TotalHours*60)
Some of my TotalHours values=0 and I need to exclude them from calculation.
How do I write it in Field Expression window?
My current expression is
(I am also setting zeros to "99" values in this field):
=IIf(Fields!TotalHours.Value=0,99,
Sum(Fields!TotalMinutes.Value/(Fields!TotalHours.Value*60)))
Thank you for help
This is untested but should work...
The problem is that IIF will evaluate both expressions even if one is never used so to avoid a divide by zero we need to swap the potential zero for a 1. This won't affect the result as it will never be used as the final output.
=SUM(
IIF(Fields!TotalHours.Value=0,99
, IIF(Fields!TotalHours.Value=0,0, Fields!TotalMinutes.Value)
/ IIF(Fields!TotalHours.Value=0, 1, Fields!TotalHours.Value * 60)
)
)
So what happens here is that if TotalHours is zero we do a 0/1 in the False part of the outer IIF just to satisfy the IIF statement (it will never actually be used)

SSRS Expression how to compare value from two different datasets?

So I've searched for this specifically but cannot find an example or answer anywhere.
I'm trying to compare a value of one dataset to the value of another dataset but it's not working.
Here's my expression:
=IIF((Fields!IC_ADV.Value + Fields!OC_ADV.Value) > 0, Max(Fields!AMOUNT.Value, "Data_bucket_info") > 15, nothing)
All I get is "True". If I remove the '> 15' then I get a value but it's not the right value. I've tried replacing Max with First, Min, Sum; without the '>15' I again get a value but not the right one and with the '>15' I get "True" or "False".
If I have Max in, I'm expecting to get the Max value for AMOUNT for all amount > 15; if I have Min in, I'm expecting to get the Min value for AMOUNT for all amount > 15.
So for example:
AMOUNT is in increments of 5; so 5, 10, 15, 20, 25....etc.
If (Fields!IC_ADV.Value + Fields!OC_ADV.Value) = 24 then what I want is for AMOUNT to display 25. If (Fields!IC_ADV.Value + Fields!OC_ADV.Value) = 3 then I want AMOUNT to display 5.
The warning I keep getting in SSRS is 'The Value expression for the textrun 'Textbox12.Paragraphs[0].TextRuns[0]' uses a numeric aggregate function on data that is not numeric. Numeric aggregate functions (Sum, Avg, StDev, Var, StDevP, and VarP) can only aggregate numeric data.'
But the AMOUNT field is a numeric value.
It is not lot clear from your description what you are trying to achieve. But for what I understand you want to match the sum of IC_ADV and OC_ADV with some value and depending on that you want to get the value. for that you can set the expression as below,
=IIF((Fields!IC_ADV.Value + Fields!OC_ADV.Value) = 24,Max(Fields!AMOUNT.Value, "Data_bucket_info"),IIF((Fields!IC_ADV.Value + Fields!OC_ADV.Value) = 3,Min(Fields!AMOUNT.Value, "Data_bucket_info"),Nothing)
But if you want to match match value of one dataset to another datasets value based on some common field then you should take a look at the LookUp. Here is more info.
In this scenario, I think it's better to make it in Math way. Try the expression below:
=((Fields!IC_ADV.Value + Fields!OC_ADV.Value)\5+1)*5

SSRS 2008 Conditional data driven sum

The matrix's odd rows contain strings, representing integer numbers. The even rows contain strings, representing dates in mm/dd/yyyy format. The order is not guaranteed, it could be the other way around if someone changed the category names.
The grand total row has to be added to this matrix, but the following expressions throw an #Error:
=Sum(Iif(IsDate(Fields!Data.Value), 0, CInt(Fields!Data.Value)))
=Sum(Iif(InStr(Fields!Data.Value, "/"), 0, CInt(Fields!Data.Value)))
Converting 0 and field value to some other numeric data types did not work too.
Interesting enough, the expressions partially work for the grand total column, i.e. they calculate the numbers' row total, but #Error on the dates rows.
Protecting the row grand total as follows did not help either:
=Iif(Fields!Results.Value = "# of items", CStr(Sum(CInt(Fields!Data.Value))), "")
What is the correct way to implement data driven conditional totals?
I could do this in plain SQL and dump into a tablix in a heartbeat but this has to be wrapped in SSRS and used with an existing matrix which must not be changed otherwise.
The #ERROR you get on the date rows is due to the CInt conversion failing.
This is because IIF is a function, not a language construct so both the true and false parameters get evaluated before being passed to the function regardless of the value of the boolean condition parameter. This means that:
=Sum(Iif(IsDate(Fields!Data.Value), 0, CInt(Fields!Data.Value)))
will always attempt the conversion to integer regardless of the result of the IsDate function.
Try using Val instead of CInt. The problem with CInt is it errors when the string to be converted is an inappropriate form; Val doesn't have that problem - it simply grabs whatever numbers it can. So you can use the expression:
=Sum(Iif(IsDate(Fields!Data.Value), 0, Val(Fields!Data.Value)))
and then simply format it like an integer.
Note that the Val function is still being run even when the field is not numeric but this expression succeeds because the Val function doesn't raise errors like Cint. We simply make the calculation and discard the result when the field is a date.
This expression, combining the tips from both answers with additional protection, works:
=Iif(
IsNumeric(Fields!Data.Value),
Sum(Val(Iif(InStr(Fields!Data.Value, "/"), "", Fields!Data.Value))),
0
)

SSRS Avg function returns result that is different than expected

Currently I am trying to average a set of numbers, but with certain conditions.
Is it possible to use an iif() within an avg() and return the correct result?
Furthermore, as of now my computations return a decimal returned to a power (8.9267....E -05).
I tried circumventing the AVG function by conditionally summing and then dividing by a conditional count but it gives me the same results.
Can someone explain why this is returned and offer help?
Currently I have:
=avg(iif((This_case) AND (That_case) AND (This_conditional)
, Fields!ResponseRate.Value
, 0))
Essentially I want the average ResponseRate if certain conditions are met.
The sum function works fine for the conditions but the average doesn't.
You can definitely use IIf within Avg and get the correct results.
Do you want to exclude the False values from the calculation entirely?
In your example you're still including them, just setting them to 0 and hence still including them in the calculation. This might explain your unexpected results.
If you want to exclude them entirely use Nothing instead of 0.
Edit after comment
You can nest an expression in another IIf statement and check for NULL values using IsNothing.
Say your condition average expression is:
=Avg(IIf(Fields!ID.Value > 5, Fields!value.Value, Nothing))
You can return 0 for NULL values with something like:
=IIf(IsNothing(Avg(IIf(Fields!ID.Value > 5, Fields!value.Value, Nothing)))
, 0.0
, Avg(IIf(Fields!ID.Value > 5, Fields!value.Value, Nothing)))
I'd like to add my two cents to this one, a little late, but also valuable. I was able to use the above code to Average out a data set if another record appears X number of times.
=AVG(IIF(Count(Fields!AcctNo.Value, "AcctNo1") = 2, Fields!Limit.Value, Nothing))
So, if the acctno field appears 1 time, avg the limit field for that row group. Ian's example was very helpful