SSRS Count or Sum expression - reporting-services

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

Related

Change Case in SSRS 2013

I am using a parameter to change the background color of my field when the field string contains the parameter string .
I have used IndexOf, Contains, and instr. All three work, however they are all case sensitive. (i.e. when I search 'Dol' Dollar Tree and Doldrum are highlighted but not Sandolski etc.)
It is not the stored procedure, the correct records display, however the SSRS functions are what is my challenge.
I have tried toLowerInvariant but was receiving an error Help please.
As I was writing this I checked my error and learned the issue..
I assumed the syntax was to pass my string as a parameter:
toLowerInvariant(Parameters!Param1.Value)
However the correct toLowerInvariant syntax is (in ssrs):
Parameters!Param1.Value.toLowerInvariant()
An explaination on toLowerInvariant can be found here: string.ToLower() and string.ToLowerInvariant()
And also I have found that this comparison is best done with a Switch (if you are comparing multiple parameters to the field).
I have not noticed a performance impact between Field.IndexOf(#Param), Field.Contains(#Param), or Field.Instr(#Param)
My final code:
=switch(
instr(Fields!Client.Value.toLowerInvariant(),Parameters!Client_Firm.Value.toLowerInvariant()) >= 1, "Cornsilk",
instr(Fields!Client.Value.toLowerInvariant(),Parameters!KeyWord.Value.toLowerInvariant()) >= 1, "Cornsilk"
)

SSRS Iif always true when false part contains expression

I've got a report outputting to an Excel file, with some fields in a database being empty.
I'm trying to filter these null values out using the following Iif expression in a cell:
=Iif(
IsNothing(Fields!START_DATETIME.Value),
0,
Fields!START_DATETIME.Value
)
This doesn't work, I get "#VALUE" in the cells where the data was null, and the time value of the cell where there was data.
If I use the same expression without an expression as the third parameter:
=Iif(
IsNothing(Fields!START_DATETIME.Value),
0,
1
)
I get 1s where there is a date in the table and 0s where there is nothing.
I'm sorry if this is a duplicate, I couldn't find anything that worked for me...
Edit:
I'm using VisualStudio Professional 2013
Update
What I've got for each entry in the database is: a datetime for authorization time, another for start time and another for stopped time. There is always an entry for authorization time, but not always for start and stopped.
I've split the date and time out from the various datetimes into columns like so:
Authorized date
Authorized time
Start time
Stop time
The idea is that if no start and stop time are present, just use the authorized time
The following expressions are put in the Start time column. Sorry, I don't have enough rep to post images or more than 2 links. I've put program output in this album:
http://imgur.com/a/zJSAY
Doing:
=Iif(Fields!START_DATETIME.Value is Nothing,
DateAdd(DateInterval.Day,693594,TimeValue(Fields!AUTH_DATETIME.Value)),
DateAdd(DateInterval.Day,693594,TimeValue(Fields!AUTH_DATETIME.Value))
)
Outputs the authorized time, so that works fine.
However, doing:
=Iif(Fields!START_DATETIME.Value is Nothing,
DateAdd(DateInterval.Day,693594,TimeValue(Fields!AUTH_DATETIME.Value)),
DateAdd(DateInterval.Day,693594,TimeValue(Fields!START_DATETIME.Value))
)
Outputs the start time where there is an entry, and #VALUE! (null or some such) when there isn't anything.
And doing:
=Iif(Fields!START_DATETIME.Value is Nothing,
DateAdd(DateInterval.Day,693594,TimeValue(Fields!START_DATETIME.Value)),
DateAdd(DateInterval.Day,693594,TimeValue(Fields!AUTH_DATETIME.Value))
)
Outputs the authorized time where there is an entry in start time, and #VALUE! when there isn't anything.
I can't figure this out. I understand (1) and (3), but what I need is for (2) to display the correct start time while there is one, and the authorized time when there isn't.
Update 2
It turns out that Iif() evaluates each conditions even if it is not selected, and any error encountered is passed on regardless. See comments to Why isn't my iif statement evaluating true when the condition is correct?
To fix this I did:
=DateAdd(
DateInterval.Day,
693594,
TimeValue(
Iif(
Fields!START_DATETIME.Value is Nothing,
Fields!AUTH_DATETIME.Value,
Fields!START_DATETIME.Value
)
)
)
This seems to work for me, and should have been the common sense way to do this in the first place...
Thanks again for your help guys.
Excel will guess the type of a column based on the first few cells. If there's typical DATETIME values in those, it'll guess the column is a date column, and it will error with "#VALUE! on values that don't match the type, such as "0".
You should ask yourself what you want to display in Excel for NULL values:
If you just want an empty cell, don't use an expression at all. Just Fields!START_DATETIME.Value will render a NULL value as an empty cell.
If you want a "baseline" datetime, make sure to use that instead of "0". Easiest is probably in your query with something like ISNULL(START_DATETIME, GETDATE()).
If you really want a "0", make sure it appears in one of the first few cells by ordering. Excel will see the "0" and not set the column type to date/time.

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
)

Format phone number and hide #ERROR when return is null SSRS

I'm having an issue and everything i've tried doesn't work. I have a phone number datafield that returns numbers with no formatting '3055558798' but i want it to look like this '(305)555-8798'. I can get that done with this expression:
= Format(Convert.ToDouble(Fields!MyFieldName.Value), "(###)###-####")
The only issue is that when the return is null i get #ERROR in the space. I found an expression that got rid of the #ERROR but still no luck putting them both together. I would have to dig through my reports to find the expression but hopefully someone can help me. I've been doing reports for a couple of months but i'm still not very good with all the expressions that there are. I just need to format the phone number and if the return is null then not show anything. There's also this on the same site that i found the expression but it doesn't work so i dont know why the guy said it worked for him.
=Iif (Fields!MyFieldName.Value Is Nothing, Nothing,
Format(Convert.ToDouble(Fields!MyFieldName.Value), "(###)###-####"))
That just doesn't work for me, I believe the syntax is wrong but i don't know what to change to fix it. Thanks.
The error you have got is nothing to do with formatting, it is the conversion to Double that is failing. So your expression works perfectly as long as your field consists entirely of numeric characters. However, you have some data with non-numeric characters in it, causing the Convert.ToDouble() function to throw an error.
Unfortunately this can not be solved with an IIF expression 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:
=IIF(IsNumeric(Fields!Phone.Value), Format(Convert.ToDouble(Fields!Phone.Value), "(###)###-####"), Fields!Phone.Value)
will always attempt the conversion to double regardless of the result of the IsNumeric function. There are two ways to solve this:
Use Val instead of ToDouble
The problem with ToDouble 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 now we can use the expression:
=IIF(Fields!Phone.Value Is Nothing,
Nothing,
IIF(IsNumeric(Fields!Phone.Value),
Format(Val(Fields!Phone.Value), "(000)000-0000"),
Fields!Phone.Value)
)
(Use 0 rather than # so that leading zeroes aren't suppressed)
This expression returns Nothing if the field is Null, checks to see if it is numeric and if so converts it to a number and formats it, otherwise it just returns whatever is in the field.
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 ToDouble. We simply make the calculation and discard the result.
Custom code
On the Report menu, click Report Properties... and go to the Code tab. Insert the following code:
Function FormatPhone(Phone AS String) AS String
IF (Phone Is Nothing) Then
Return Nothing
Else If (IsNumeric(Phone)) Then
Return Format(Convert.ToDouble(Phone), "(000)000-0000")
Else
Return Phone
End If
End Function
Use the following expression in your phone number cell:
=Code.FormatPhone(Fields!Phone.Value)

Use a summary field in an expression in SSRS reports

I have the details of my report being summed up in a summary expression, all works fine. The fields are decimal values of hours worked. Thus, the summary value is also a decimal value. I'd like to access the summary value and convert it to hours / minutes. I've labeled the express as "WorkTimeSum", but can't seem to get a handle to it, however. Fields! obviously won't work since it is a summary expression. I was thinking ReportItems! should work, but to no avail. How can I use this expression field (in a summary row) in an expression in the same summary row?
If I've understood correctly, you're asking how to reference the textbox containing the total work hours value so that you can convert it to hours and minutes using an expression in a different textbox?
You can use either ReportItems! e.g.
=ReportItems!Textbox20.Value)
or ReportItems("") e.g.
=ReportItems("Textbox20").Value
to reference the value of another textbox. Be careful with the names as they are case sensitive.
You can use aggregate functions in any expression. For example, in any header rows you can use the following expression to determine the total hours value:
=Floor(Sum(Fields!hours.Value))
Sum(Fields!hours.Value) is just the total hours in whatever context, e.g. the group total if it's a group header row; you can use this expression as an input in any other expression you require.
It sounds like your issue wasn't the conversion itself, so hopefully this points you in the right direction. If you need further information please specify.