I have been working on this for days without being able to solve yet. It's probably simple if you know what you're doing. I'm simply trying to make a standalone formula that is not in a tablix or anything, it's just in a textbox.
Here is an example of my Dataset called Dataset1:
What I am trying to get is a sum of the Actual Cost when the Category is Labor from Dataset1. My current expression is:
=Sum(iif(Fields!Category.Value="Labor", Fields!ActualCost.Value, 0), "Dataset1")
I refer to Dataset1 as my scope because otherwise, I get an error about using an aggregate expression without a scope.
The report runs but shows #Error in the textbox that has my expression in it. When I replace Fields!ActualCost.Value with a 1, I get the answer, 5, which is the correct number of rows with Labor as the Category. But it won't let me sum the numbers in the ActualCost column where Category is Labor.
Any ideas as to what I'm doing wrong? I feel like it's something to do with aggregating, but I'm not sure. Thanks!
It may have to do with the datatype of fields!ActualCost.Value. If that field is a decimal (regardless of how you have it formatted), try using cdec(0) instead of just 0 in your expression.
I created a matrix with two column groups (year and quarter).
The expression for the quarter label (the expression under [year]) is:
"Q " & CStr(Fields!quarter.Value)
So in the report I get Q1, Q2, Q3 and Q4 as quarter labels.
We have a international team so I need the others labels to be in german or in english, depending on the user. So I created a dataset with all translations which is filled from a translation table in the database. To get the correct translation for the label I use the LOOKUP() function.
When I use LOOKUP() to get the correct translation for the "amount Rest" textbox (located in the year group) it works fine:
=LOOKUP(11, Fields!ID.Value, Fields!description.Value, "ds_Labels")
The result:
But when I try to use LOOKUP() to get the translation for the "amount" textbox, which is located in the quarter group, the correct translation appears but the year label also starts with 2014 instead of 2008 and the quarter and year labels repeat:
=LOOKUP(17, Fields!ID.Value, Fields!description.Value, "ds_Labels")
The result:
I've no idea what kind of bug this is and how I can get rid of it. Maybe someone can help me :)
UPDATE
Like I mentioned in the comments, the LOOKUP() function works in the first three columns of the quarter group. The report goes crazy if I try to use LOOKUP() in the fourth textbox of the quarter group (see the second last screenshot). But I still don't understand why...
UPDATE 2
When I deploy the report on a SSRS 2008R2 the report works completely fine. But I need it to run on SSRS 2012. Maybe it is a SSRS2012 bug?
Have you made sure that only one record is being returned when you look up the record(s) associated with id 17? The function is designed to be used for 1 -to- 1 relationships
I believe it's a bug. Running Lookup() / LookupSet() queries against the same dataset that is being currently rendered in a tablix causes duplicates.
The only workaround I found is to pass a copy of the dataset and run Lookup() queries against that copy. This way everything works fine.
I have a report where users can select items from various location. And I have 3 datasets performing calculations where the third dataset takes the sum where item number is 4942200 and then calculates the values (as shown below):
=SUM(IIf(Fields!masterno.Value= "4942200",Fields!Owned.Value,0))+SUM(IIf(Fields!masterno.Value= "4942200",Fields!Subbed.Value,0))
This is returning error for some reason. The subbed column is toggled based on parameter (visibility). But before I add the toggle functionality, I want to make sure this is working. Can anyone help. I have also tried:
=SUM(IIf(Fields!masterno.Value= "4942200",Fields!Owned.Value+Fields!Subbed.Value,0))
This seems to fail as well. Help would be greatly appreciated.
I would wrap a CDec around Owned, 0 and Subbed, e.g.
=SUM(IIf(Fields!masterno.Value= "4942200",CDec ( Fields!Owned.Value) ,CDec (0 ) ))+SUM(IIf(Fields!masterno.Value= "4942200",CDec (Fields!Subbed.Value ) ,CDec ( 0 )))
If Owned and Subbed are already Decimals, those CDec's may be redundant. On the other hand SSRS doesnt expose this info and they can change at the whim of the data source.
Hope your well.
I am working on a report and seem to get a #error. Seems like it is a divide by zero error but I can not work out a solution. The expression:
=( Sum(Fields!Line_Sell.Value) - Sum(Fields!Line_Cost.Value) ) / Sum(Fields!Line_Sell.Value)
I am relatively new to RS but have tried
ISNULL( )
but with no success.
Any help, I would be greatful.
Thanks
Let's say you have an expression set to x / y, where y has the potential to be zero. As you experienced, SSRS will change this value to #ERR (or sometimes NaN).
Your first instinct would be to test for zero
=Iif(y = 0, 0, x/y)
Unfortunately, this can result in a debugger warning that says you are attempting to divide by zero. This is because SSRS attempts to evaluate the entire statement during compilation.
As a result, we need to provide SSRS with a value that it can evaluate
=x * y ^ -1
This is the same as dividing by your y value, but SSRS sees this as dividing by infinity, and therefore can make an evaluation.
As a final step, you will want to make sure your code can properly export to Excel. Under 2012 SSRS (and possibly later, I haven't tested), SSRS has an issue where possible zero values export to Excel as 0.000000000000000 and cause loss of data errors.
To correct this, we explicitly output the value of zero
=Iif(x = 0 OR y = 0, 0, x * y ^ -1)
The expression in your comment doesn't look complete, so I can't tell what you tried next that didn't work. You definitely want to test for zero before performing division.
You can try this:
=iif( Sum(Fields!Line_Sell.Value) = 0, 0, (Sum(Fields!Line_Sell.Value) - Sum(Fields!Line_Cost.Value)) / Sum(Fields!Line_Sell.Value))
Or to check for an empty value also, you can try this:
=iif( (Sum(Fields!Line_Sell.Value) = 0 or IsNothing(Sum(Fields!Line_Sell.Value)), 0,Sum(Fields!Line_Sell.Value) - Sum(Fields!Line_Cost.Value)) / Sum(Fields!Line_Sell.Value))
If that's still not yielding results, break down the expression and run the report. Try Sum(Fields!Line_Sell.Value) by itself, run the report and see what you get. To be more efficient create a table with one column for Fields!Line_Sell.Value and another for Fields!Line_Cost.Value. In the table, include detail rows and add a total row so that you get the Sum function with each of those fields individually. You need to look at the detail records to try to extrapolate why the aggregate function isn't working. Bottom line - decompose your expression and test it piece by piece. The answer is in there somewhere.
I'm working on a rather complex report in Sql Server Reporting Services. My SP returns a dynamic number of columns each of which are dynamically named.
Basically think of a time keeping application. Each column that is dynamic represents a time bucket that time was charged to for that team. If no time was charged to that bucket for the period of time the report covers it doesn't show. Each bucket has its own identifier which i need to be the column headers.
I have an SP that returns this all. It does it by doing a bit of dynamic SQL with an exec statement (ugly i know but I'm on SQL 2000 so a PIVOT option wouldn't work)
I can have an indefinite number of buckets and any or all might show.
I found this - http://www.codeproject.com/KB/reporting-services/DynamicReport.aspx - which is helpful but in the example he has a finite number of columns and he just hides or shows them according to which ones have values. In my case i have a variable number of columns so somehow i need the report to add columns.
Any thoughts?
As long as you know a maximum number of columns, it's possible to do this after a fashion.
First, name the columns with a result from your query, so you can either pass it in to the query or derive it there. Second, just build out the report as if it had the maximum number of columns, and hide them if they are empty.
For example, I had to build a report that would report monthly sales numbers for up to a year, but the months weren't necessarily starting in January. I passed back the month name in one column, followed by the numbers for my report. On the .rdl, I built out 12 sets of columns, one for each possible month, and just used an expression to hide the column if it were empty. The result is the report appears to expand out to the number of columns needed.
Of course, it's not really dynamic in the sense that it can expand out as far as you need without knowing the upper bound.
This can be done. I did this and it works fine.
You don't have to know the maximum number of columns or show and hide columns in my approach. Use a matrix and modify your sp to return dynamic data to the structure mentioned in this blog post http://sonalimendis.blogspot.com/2011/07/dynamic-column-rdls.html
Build 2 related Datasets, first one for the report content, and the second one for the list of its column labels.
The Dataset of the report content must have a fixed number of columns and name. You can allocate some maximum number of columns.
In this example I have the first 2 columns as fixed, or always visible, and a maximum of 4 columns to be displayed by choice through a multivalued parameter, or depends on the query conditions. And as usual, we may have a total as well. So, it may look like this:
Fixed01, Fixed02, Dyna01, Dyna02, Dyna03, Dyna04, Total
The second Dataset with its values will look like this:
Name Label
---- -----
Dyna01 Label01
Dyna02 Label02
Dyna03 Label03
I have omitted the 4th Label to demonstrate that not all columns are being used by a certain query condition. Remember that both Datasets are meant to be related to the same query.
Now create a parameter named, say, #columns; populate its Available Values and Default Values with the second Dataset.
For each of those 4 dynamic columns, set the column visibility with the following expression:
=IIf(InStr(join(Parameters!columns.Value,","),"Dyna01"),false,true)
And for each of their column header Text Boxes, use the following expression:
=Lookup("Dyna01", Fields!Name.Value, Fields!Label.Value, "dsColumns")
As for the Total, here is the expression for its visibility:
= IIf(InStr(join(Parameters!columns.Value, ","), "Dyna01"), false, true)
AndAlso IIf(InStr(join(Parameters!columns.Value, ","), "Dyna02"), false, true)
AndAlso IIf(InStr(join(Parameters!columns.Value, ","), "Dyna03"), false, true)
AndAlso IIf(InStr(join(Parameters!columns.Value, ","), "Dyna04"), false, true)
And here is for its values:
= IIf(InStr(join(Parameters!columns.Value, ","), "Dyna01"), Fields!C01.Value, 0)
+ IIf(InStr(join(Parameters!columns.Value, ","), "Dyna02"), Fields!C02.Value, 0)
+ IIf(InStr(join(Parameters!columns.Value, ","), "Dyna03"), Fields!C03.Value, 0)
+ IIf(InStr(join(Parameters!columns.Value, ","), "Dyna04"), Fields!C04.Value, 0)
That's all, hope it helps.
Bonus, that second Dataset, dsColumns, can also hold other column attributes, such as: color, width, fonts, etc.
I think the best way to do it is add all the columns in your table and edit the visibility property of it with the help of arguments that you get from your SP..this will solve the purpose of dynamic column but when viewing the report you will get a lot of white-space which you can solve with SSRS - Keep a table the same width when hiding columns dynamically? and your report will be ready
I've had the need to do this in the past and the conclusion I came to is "you can't", however I'm not positive about that. If you find a solution, I'd love to hear about it.
An issue that comes to mind is that you need to define the report using the names of the columns that you're going to get back from the stored proc, and if you don't know those names or how many there are, how can you define the report?
The only idea I had on how to do this is to dynamically create the report definition (.rdl file) via C#, but at the time, I wasn't able to find an MS API for doing so, and I doubt one exists now. I found an open source one, but I didn't pursue that route.