I'm trying to concatenate a string on the end of a sum, but if the sum is nothing, it breaks. It seems like this is due to SSRS evaluating both conditions of the IIf statement, but I can't figure out how to get around this.
I've got....
=IIf(IsNothing(Sum(Fields!Work.Value)), "", Sum(Fields!Work.Value).ToString + " J")
Which will print out the work summary + " J" if there is one, and #Error if not. What's the SSRS workaround?
Update / Clarification
The report in question is grouping on dates and then summing up Work, so it's not the case that Work is null, per se, but that for this particular date for this particular user, there are no rows in the group.. So, there are no rows to sum up in the error causing instance.
Sample Data Set
Name Date Work
Andy 12/1/15 511.30
Andy 12/1/15 549.70
Drew 12/2/15 484.80
Drew 12/2/15 322.36
Sample Report (current)
Name 12/1/15 12/2/15
Andy 1061 J #Error
Drew #Error 807.16 J
Sample Report (expected)
Name 12/1/15 12/2/15
Andy 1061 J
Drew 807.16 J
Have you considered doing the two parts of your desired output in two different expressions in the same Cell?
I assume for the current structure you have used a matrix, with Rows for the Name, and Columns for the date. You can the set the Data to be Sum of Work, as shown here, and in the red text in the image below.
=Sum(Fields!Work.Value)
You then then right click the cell and select "Create Placeholder" to insert a second expression in the same cell.
Set the value of this expression to be as shown here, and in the blue text below
=iif(Sum(Fields!Work.Value) > 0, " J", "")
Then when the report is run, it will always show the Sum if there is one, and if the value of the Sum is greater than zero, it will also display the J as required.
Hopefully this is the behaviour you require. Please let me know if you require further assistance with this solution
Try this:
=IIF(SUM(IIF(Isnothing(Fields!Total.Value),0,Fields!Total.Value)) = 0,
"",
SUM(IIF(Isnothing(Fields!Total.Value),0,Fields!Total.Value)).ToString + " J"
)
Let me know if this can help you
IIF does not short-circuit so this #Error is from SSRS trying to use the ToString function on NULLs.
The workaround is to add another IsNothing check in the false section before using ToString:
=IIF(IsNothing(Sum(Fields!Work.Value))
, ""
, IIF(IsNothing(Sum(Fields!Work.Value)), "", Sum(Fields!Work.Value)).ToString & " J")
To solve this exact problem, because if there is no Work to display then the report should display nothing, instead of using the IIf statement with concatenation, it is simple and sufficient to set a conditional visibility on the cell.
In the cell, use the expression:
Sum(Fields!Work.Value).ToString + " J"
Then for the same cell, select:
Text Box Properties > Visibility > Show or hide based on an expression
and enter:
=IsNothing(Sum(Fields!Work.Value))
While this solves this specific problem, if the solution requires the empty cell to display anything other than blank, then the original IIf short-circuit issue is still an issue.
Related
In Excel you have the option of showing a table below your chart that shows the data used in the chart - I am trying to replicate that behavior in SSRS.
Scenario:
I have one dataset from which I want to populate two (Chart + Table) elements (so two charts and two tables). Each Chart + Table combo needs to use the exact same filter, but I don't want to manually define that exact same filter on each object (if I need to change it, I don't want to have to make the change on two entities).
Yes I know there are other ways to accomplish the same end result, such as perform the filter in the SQL, or to instead define two separate datasets, and then apply the filter on the dataset itself (so it will then cascade down to both the Chart and Table).....or in other words, I'm not asking if this is a good idea, I'm asking if it is possible. :)
Closest thing I can think of to what you want is to define the logic of your filter in custom code, and call the custom code in your two filters.
If the logic ever changes, you would only have to change it in one place.
But it's not possible to define the filter on your tablix, for instance, and then in your chart put in some kind of "use the same filter as my tablix" command.
I would add a Calculated Field that checks your criteria and gives a 1 or 0 depending on whether it meets all the criteria or not.
Field Name: MeetCriteria
=IIF(Fields!AGE.Value < 10 and Fields!status.Value = "PAID", 1, 0)
Then you just need to filter on the new calculated column:
Expression: Fields!MeetCriteria.Value
Type: INTEGER
Operator: =
Value: 1
Not quite what you want but much easier than duplicating the criteria everywhere.
For a multi-value Status parameter, you could do something like:
=IIF(Fields!AGE.Value < 10
AND INSTR("|" & Join(Parameters!Status.Value, "|") & "|", "|" & Fields!Status.Value & "|") > 0,
1, 0)
I am facing very simple issue but not getting solution over it.
I have textbox in my ssrs report, I am passing value "1;prashant" or null to it. Now, if I pass value "1;prashant" to textbox then textbox should show only "prashant" and If I am passing nothing then it should be blank.
I have tried following IIF condition:
=IIF(IsNothing(FieldS!WIAPPORVER.Value),"",Split(Fields!WIAPPORVER.Value,"#")(1).ToString())
But, I above code is giving an error ["#error" shows in textbox] if I am passing blank value.
Please let me know, where I am wrong in this.
Thanks
There are probably better ways of doing this, but this is what my head came up with at the time:
=IIF(
IsNothing(Fields!WIAPPROVER.Value)
,""
,Right(Fields!WIAPPROVER.Value,Len(Fields!WIAPPROVER.Value) -InStr(Fields!WIAPPROVER.Value,";"))
)
I believe SSRS is trying to compute everything in the report at runtime, so in your case it is still trying to fetch index 1 from an array even though there is nothing in it and it crashes.
Edit: Changed parameters to Fields. I created a parameter to remake the issue at my side.
Just get the split out of the iif. Then in your iif, if field is nothing create a string that when split will return ""
=Split(IIF(IsNothing(FieldS!WIAPPORVER.Value),"#", Fields!WIAPPORVER.Value),"#")(1)
You are relying on the IIf expression short circuiting, but SSRS IIf expressions do not short circuit - the expression will try and work out Split(Fields!WIAPPORVER.Value,"#")(1).ToString() for all rows and fail when this value doesn't exist.
You can get this going by using text expressions, which don't get this error.
With test data:
And a simple table:
I have added columns with both your existing expression and a new expression:
=Right(Fields!WIAPPORVER.Value, Len(Fields!WIAPPORVER.Value) - InStr(Fields!WIAPPORVER.Value, "#"))
This new expression works for NULL values, empty strings and strings with no delimiter present:
I have a field like this in the column field in ssrs.
QUINIDINEssssssssssssssssssssssssssssssssssssssssssssssssssssss GL INJ 80MG/ML
FLECAINIDEssssssssssssssssssssssssssssssssss TAB 50MG
TAMBOCORsssssssssssssssssssssssssssssssssssssssssssss TAB 50MG
and how can i align align like this...
QUINIDINEssssssssssssssssssssssssssssssssssssssssssssssssssssss GL INJ 80MG/ML
FLECAINIDEssssssssssssssssssssssssssssssssss(emptyspaceeeeeeeee)TAB 50MG
TAMBOCORsssssssssssssssssssssssssssssssssssssssssssss(emptyspa)TAB 50MG
each part of string align properly...
Any help...
Well, there are two ways to do this that I worked out, and neither is particularly elegant so I'd be surprised if someone doesn't have a better solution.
"t.a" in the code below is your table and column.
The SQL way:
SUBSTRING(t.a,1,CHARINDEX(' ',t.a,1))+REPLICATE('_',20)+REVERSE(SUBSTRING(REVERSE(t.a),1,CHARINDEX(' ',REVERSE(t.a),1)))
Change the value being replicated above from '' to ' ' and you are in business. I left it as '' to illustrate what it's doing.
The SSRS way, which is better from a DB standpoint:
=Mid(Fields!a.Value,1,InStr(Fields!a.Value," "))+StrDup(20,"_")+StrReverse(Mid(StrReverse(Fields!a.Value),1,InStr(StrReverse(Fields!a.Value)," ")))
This is precisely the same formula, executed by SSRS instead of by SQL Server.
I once used Switch to append spaces to a column field, like in the following example:
=Switch(LEN(Fields!FamilyMemberName.Value) = 1, " ",
LEN(Fields!FamilyMemberName.Value) = 2, " ",
LEN(Fields!FamilyMemberName.Value) = 3, " ")
But I didn't have to bother about the expression getting longer, since I know exactly how many spaces I should append and it wasn't more than 15.
You could use Switch in your case too or you could write a VB function in the Code tab of Report Properties window and pass the values, use some loops to generate the spaces you require.
Or it's much easier in MS SQL, all you got to do is append SPACE(NoOfSpacesInInteger) to the field.
I'm very confused by this situation, i've written quite a few IIF statements and always get them to work. I have two columns in my dataset called CATEGORY and PCT, what i'm trying to do is return the PCT value for only one specific value in CATEGORY.
For example, I have the following table of data
Category PCT
A .50
B .75
I have placed a textbox on my report and have written the following expression to return the PCT value if Category = B, like so:
=IIF(Fields!Category.Value = "B", Fields!PCT.Value, " ")
For some reason this expression returns empty every single time. When I just put Fields!Category.Value in the textbox as a test then the value A returns which is as expected.
I'm really thrown-off by this and I know i'm missing something very simple - can someone help?
Its important that we understand the context of the textbox as the expression seems valid.
If you placed a single textbox on your report and used your above expression (with references to the datasets) ONLY the first row of your dataset will be evaluated. In which case the expression will always evaluate to the same result.
Can you confirm that the control you are using is indeed a textbox? If it is then i believe you do need a reference to the dataset and the expression will look more like this:
=iif(First(Fields!Category.Value, "datasetName") = "B", First(Fields!PCT.Value, "datasetName"), " ")
This would only evaluate the first row in your dataset.
If you were to do this in a tablix using your original expression then it should work.
Hi All I need your advice,
1) I have a dynamic string which changes each time.
for example today the string will be "ItemA,ItemB,ItemC" and tomorrow it will be "itemA,ItemB" only.
2) I have an SSRS report which has 3 columns
3) I want to split this string "ItemA,ItemB,ItemC" and want to show split substrings in these 3 columns of ssrs table. the Delimiter is "," (comma)
4) I had used
=Split("ItemA,ItemB,ItemC",",").GetValue(0) in the first column of the report
=Split("ItemA,ItemB,ItemC",",").GetValue(1) in the second column of the report
=Split("ItemA,ItemB,ItemC",",").GetValue(2) in the third column of the report
5) everything works fine until my string is "ItemA,ItemB,ItemC" ,
BUT WHEN MY STRING CHANGES TO "ItemA,ItemB" I am seeing "#Error" in the third column.
I understood the error, for
=Split("ItemA,ItemB,ItemC",",").GetValue(2) we don't have any value because the string now has only 2 values after applying split function.
Is there any way i can avoid #Error in the third column.
NOTE: I have to compulsorily use 3 columns in the ssrs report.
I had tried using =Replace(Split("ItemA,ItemB",",").GetValue(2),"#Error","NULL") in the third column but that also wont worked.
This is similar to the divide by zero issue in using IIF statements. The problem is that IIF is not an expression, it is a function with three parameters:
IIF(Condition, ValueIfTrue, ValueIfFalse)
Accordingly, ALL parameters are evaluated BEFORE being passed to the function, which results in the error because the erroneous expression is still evaluated even when the condition should mean that it isn't.
I can't see a way to use the usual workaround tha solves the problem in the divide by zero case. What we need is a real language that doesn't have this problem. Fortunately, this is availble in the form of custom code.
Do the following:
Right-click on an area of the report surface that has no report objects
Select Report Properties
Click on the Code tab
Insert the following code:
Public Function ExtractCode(Combined As String, Position As Integer) As String
if (Split(Combined, ",").Length >= Position) Then
Return Split(Combined, ",").GetValue(Position-1)
Else
Return ""
End If
End Function
Click OK and go back to the report
Right-click on the cell you want the expression in and click Expression
Insert the following expression:
=Code.ExtractCode(Fields!Combo.Value, 3)
The value 3 is the "column" that you want to extract from the Combo field, so to get the second "column" you would use 2. If there isn't a column at that position, an empty string is returned.
you could change the visibility of the 3rd column to hidden if the name returns an error
You can append a dummy element and then split:
yourText = "ItemA,ItemB"
item0 = Split(yourText & ",", ",").GetValue(0)
item1 = Split(yourText & ",", ",").GetValue(1)
item2 = Split(yourText & ",", ",").GetValue(2)
item0 = ItemA
item1 = ItemB
item2 =