SSRS 2008 Conditional data driven sum - reporting-services

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
)

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

SSRS #Error in combination with IIF and Cdbl

hope someone more experienced can give me answer/solution to my problem.
In a database I have two columns, one to control do we show data and the data to be shown is in the second column.
I have data and expression as below:
ShowPriceOnMatrix | RSP
-------------------------------
0 | 1.48
1 | 10.26 euro -> This one fails with #Error
1 | 4.59
0 | 7.12
=IIF(Fields!ShowPriceOnMatrix.Value = 1, CDbl(Fields!RSP.Value), "")
This expression sometimes gives me #Error.
The problem is that the RSP field was defined as nvarchar and I cant change it now so I'm trying to convert to number and show as. Some users when input price on the filed they also type a text ex. "12.45 euro" or similar. When the expression hits a value with text the whole IIF fails with an #Error even if the first column is stated not to show the price.
The problem with IIF is that it is not skipping the second parameter if the first one evaluates to false - and therefore produces #Error in my case.
I've tried to use
IsNumeric(Cdbl(Fields!RSP.Value))
and
IsError(Cdbl(Fields!RSP.Value))
but both of them give an #Error also. From SSRS explanation for those functions, they should return a Boolean value but somehow I'm getting #Error :)
Just convert the field to numeric using
VAL(Fields!RSP.Value)
Also, you might want to consider using SWITCH instead of IIF. SWITCH stops at the first expression which evaluates to True, whereas IIF will evaluate all expressions regardless of if they will be used or not.
In your case, with a single IIF, SWITCH is not relevant but in cases where nested IIFs are used or situations where you may get a divide by zero error, SWITCH is often easier to read/debug. So something like this where we have a hypothetical situation that we want to test for divide by zero and return zero or if the thing we are dividing by is negative we want to return -1, otherwise do the calc...
=IIF(Fields!MyDivisor.Value = 0, 0, IIF(Fields!MyDivisor.Value <0, -1, Fields!MyNumber.Value/ Fields!MyDivisor.Value))
would become
=SWITCH (
Fields!MyDivisor.Value =0, 0,
Fields!MyDivisor.Value <0, -1,
True, Fields!MyNumber.Value/ Fields!MyDivisor.Value
)
each expression/result pair is evaluated in order until it hits the first True expression, so if MyDivisor was zero it would return 0 and stop, if it was negative, it would return -1 and stop. The final True acts like an else (as True always returns True ! ) so it would only do the calculation if all other expressions returned false.
You can use this expression to extract your numeric values:
=System.Text.RegularExpressions.Regex.Replace(Fields!RSP.Value, "[^0-9,]", "")
But you have to take care of the . in 1.48. With , and the language DE it worked for me. With . it would be:
=System.Text.RegularExpressions.Regex.Replace(Fields!RSP.Value, "[^0-9.]", "")

using IIF in msaccess report

I currently have this formula in my report
=(Sum([Final]*[Units]))/Sum([Units]))
Final - Mostly Integer but has the NG mixed in the records
Units - Integer
Re-Exam - Contains Integer
Now, with my current formula, if [Final] encounters the value NG, the report gives an error, I want to determine the if the value of [Final] is NG, [Re-Exam] will be checked if it contains a value else 0 will be added to the Sum[Final] and if [Re-Exam] contains a value, [Re-Exam]*[Units] will be added to Sum[Final]
the final result displays the result in general number format
I am thinking of using IIF but can't generate the correct formula at the moment and that's what i need to fix
Try using Val which returns 0 for a non-numeric string.:
=Sum(IIf(Val([Final])=0,Val([Re-Exam]),Val([Final]))*[Units])/Sum([Units])

SSRS Count or Sum expression

I cannot work out why these Total expressions don't work...
I am trying to add any cells that have a date later than today, with any cells that have "Not Reqd", and then divide that by the number of rows, to get a percentage.
All I'm getting is #Error.
These are the expressions I've tried:
=SUM(IIf(Fields!Jetter_Trng.Value >Today OR
Fields!Jetter_Trng.Value = "Not Reqd",1,0)))/(Count(Fields!Jetter_Trng.Value)
and
=Count(IIf(Fields!Jetter_Trng.Value >Today OR
Fields!Jetter_Trng.Value = "Not Reqd",1,Nothing)))/(Count(Fields!Jetter_Trng.Value)
The "Not Reqd" string has come from an expression that changes a date (01/01/1950) to "Not Reqd". Maybe this is messing things up:
=iif(Fields!Jetter_Trng.Value = "01/01/1950", "Not Reqd", Fields!Jetter_Trng.Value)
The current working expression (not looking for "Not Reqd") is:
=COUNT(IIF(Fields!Jetter_Trng.Value>Today,1,Nothing)))/(Count(Fields!Name.Value))
I'm a bit lost...
A couple of notes on your expression as it stands at present
Jetter_Trng appears to be a string representing either a date or “Not Reqd”. You can’t compare strings to dates without casting them to a date type first using CDATE()
The number of braces (( and )) do not match
The root of your problem though is that you are using Jetter_Trng to return either a Date, or the value “Not Reqd”.
When SSRS attempts to evaluate an expression it does it all at the same time. It doesn’t follow a path to find the answer, and ignore other paths. Therefore, when you are attempting to compare
Fields!Jetter_Trng.Value >Today
This is comparing a string to a date, and throwing the error, as this mean nothing
"Not Reqd" > Today
You won’t be able to do all that you want to using only one Field of type string.
Your options are to
Use two fields – the date and a flag indicating not required, or
Use one field – but have an “invalid date” (01/01/2100 perhaps) that you could then treat as the “Not Reqd” value, and check if the current date is less than that (which it always will be)
Using the second option here you could then use the following expression to create the desired calculation
=sum(iif(CDate(Fields!Jetter_Trng.Value) > Today, 1, 0)) /
Count(Fields!Jetter_Trng.Value)
Which would evaluate this dataset as follows

SSRS Conditional Summing

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.