I feel like this should be easy but I can't figure it out.
[Result View]
This is logically what I think should work:
=(ReportItems("CustCounts2").value/ReportItems("RowTotal2").value)
But the RowTotal2 is an outside group and won't render.
It looks like you are using a matrix, so this is based on what I think your data looks like..
I used this to generate some sample data
I created a dataset DataSet1 with the following as the dataset's query
DECLARE #t table(office varchar(10), EstimateStatus varchar(10), Counts int)
INSERT INTO #t VALUES
('Office A', 'Loss', 92),
('Office A', 'Win', 971),
('Office B', 'Loss', 50),
('Office B', 'Win', 500)
SELECT * FROM #t
I then added a matrix, added office as the row group and EstimateStatus as the column group and finally counts as the data. I then added totals for both row and column groups.
Finally I removed the last column which was generated (as this was a total percentage column, that you did not have in your design).
I renamed the rowgroup for clarity to GrpOffice as you can see
The design looks like this
In the percentage column at the office level I used the following expression
=SUM(Fields!Counts.Value)/SUM(Fields!Counts.Value, "GrpOffice")
This reads get the sum of the Counts for this row (even if there is only 1) and divide it by the sum of the counts this the whole group "GrpOffice". Note this name must be in quotes and is case sensitive.
For the total row I used a similar expression..
=Sum(Fields!Counts.Value) / Sum(Fields!Counts.Value, "DataSet1")
This reads, get the sum of counts in the current scope (total column group in this case) and divide by the sum of the counts for the entire dataset called "DataSet1"
With a format of p2 on those cells to tidy it up, we get the following output.
It has something with .Data file size. As it exceeds certain limit error starts appearing. Deleting that file will force the project to recreate the .data file and issue will disappear temporarily.
Related
My tablix groups on one of its columns and only needs to output a list of time stamps for each row. As the time stamps are only two columns, that leaves an awful lot of wasted space.
Here is a basic mock-up of the current layout...
... and this is the desired layout:
As shown, the report would ideally adjust dynamically to display half the rows of a group in the left "column" (including the extra row if uneven) and the remaining rows in the right "column". Is this possible with SSRS? If not as described, can you suggest something with a similar result?
You can do this with as long as your dataset can be updated to support it.
First I grabbed some sample datetime data I had and inserted it into a table variable called #t. You'll just need to swap out #t for your actual table name. This gave me the following
Then I take this data and workout the row and column the data should sit in. In this example I am using a parameter to define the number of columns I want. You could do this and pass it in from your report if it's helpful, or just change it to a staic value. I'll demo with the parameter being passed in though.
Here's the query (Note you'll need to comment out the #Columns declaration if you want to pass this in from your report but for now we are just testing in SSMS or similar.
-- REPLACE #t with your actual tablename below
DECLARE #Columns int = 2 -- <= comment this out when you copy into your dataset query
SELECT
*
, ColumnNum = ((SortOrder-1) % #Columns) + 1
, RowNum = ROW_NUMBER() OVER(PARTITION BY GroupID, SortOrder % #Columns ORDER BY SortOrder)
FROM(
SELECT
ROW_NUMBER() OVER(PARTITION BY GroupID ORDER BY dt) as SortOrder,
GroupID, dt
FROM #t) x
ORDER BY GroupID, SortOrder
This gives us the following output
Now all we have to do is use a matrix control in the report to display it correctly.
Create a new report
Add a datsource and dataset
Set your dataset query as above remember to comment out the DECLARE #Columns line if you want to parameterise it.
Add a matrix control
Drag RowNum to the 'Rows' placeholder, dt to the 'data' placeholder and finally select ColNum in the columns placeholder
The matrix should look like this (we're not finished yet...)
In the row groups panel, drag GroupID above the exiting row group (above rownum in my example) so it creates a parent group.
Finally, add a blank row inside the RowGroup group by right-clicking the rownum textbox and doing "Insert Row, Inside Group - Below". This will just give us a gap between groups
Note: I've changed the colour of the rownum and columnnum text boxes as we can delete these once testing is complete.
The final design should look like this.
When we run the report and set the parameter to 2 we get this
set it to 3 and we get this
You can now remove the top row and middle column to get rid of the row and column numbers. If you want to have a group header as in your sample. Add a row inside the group again but this time at the top and then add an expression to give your desired title.
How can I group by based on a pattern in column to calculate the total?
My table has the following columns: CustomerAccount (char30), AccountDesc varchar(200), AccountAmount1 (decimal), AccountAmount2,....., AccountAmount5.
The CustomerAccount is in this format: xxx.xxxx.xxxxx.
Some of the values are:
How do I group the data so any value like xxx.xxxx.31xxx, xxx.xxxx.32xxx, etc is grouped together so I can calculate the AccountAmount like the image below in SSRS report? The highlighted part ranges from 30 to 39:
I am not sure if it would be easier to do it in SQL query, but not sure how.
If your account number is always a fixed length (or more precisely, if the numbers you want to group by are always in the same position) then you can create a row group with the group expression being something like
=MID(Fields!CustomerAccount.Value, 11,2)
If you wanted to group an everything up to that point you could do
=LEFT(Fields!CustomerAccount.Value, 13)
The numbers might be out by one as I can't remember if these are zero or 1 based functions but you'll soon notice that.
Say I have a dataset in SSRS called DataSet1 that looks like this:
CREATE TABLE #data
(ID int, Value int, UserID varchar(2))
INSERT INTO #data VALUES
(1, 1000, 'AA'),
(2, 2000, 'AA'),
(3, 3000, 'BB'),
(4, 2000, 'BB'),
(5, 1500, 'BB'),
(6, 1800, 'BB'),
(7, 1700, 'CC')
..and that my report just presents this as a table.
Let's then say I want to add a parameter in that report, that let's the user filter the table by UserID. I want it to be a multiple value parameter where they can choose which users to include in their report. In this case I want the list to be AA, BB and CC.
So far I have done it by creating an extra SQL query based dataset like this:
DataSet1:
SELECT ID, Value, UserID
FROM table
DataSet2:
SELECT DISTINCT UserID
FROM table
And then have the parameter get its available values from DataSet2. However the query I have in my particular report is a very long and complex query, that I would prefer to not use in two datasets. If I have to go back and change something in the query, I would have to maintain that in two places, and so on.
In short: Is there a way to have the available values of my parameter by something like this:
SELECT DISTINCT UserID FROM DataSet1
Thanks!
I decided to write my comment on your answer, M.Ali, as an answer to my own question, as I found a way to solve this. Maybe I didn't explain my problem precisely enough. I am aware of how the above thing works, and how to pass parameters based on one dataset, down thru the SQL to create another dataset, multiple values allowed or not. I appreciate your answer though!
The problem I have is that the query that would define my list of values for the parameter, and the query for the actual dataset, are the same. And it's a HUGE query. In other words, where it says 'TABLE' in the code sample, I have several hundreds of lines of code. And my goal was to not have this whole query be defining both datasets. If I in the future have to change the query, I would have to do it in more than one place. Here's how I solved it:
I placed the main query in a shared dataset instead of embedding it into my report. And I then added a row_number function to my query like so:
SELECT ID, Value, UserID, rn = ROW_NUMBER() OVER(PARTITION BY UserID ORDER BY UserID)
FROM *my huge query*
This means that there is only one 'rn = 1' row per UserID. Then I went back to my report. My original DataSet1 would then just point to the shared dataset. The DataSet2 (the parameter one) would also point to the shared dataset with the one difference that I added a filter to that dataset saying 'rn = 1'. I then made a parameter with 'allow multiple values' that took its values from DataSet2. And it works like a charm. This way I can just go to the shared dataset when I need to update the query, and both DataSet1 and DataSet2 will be updated accordingly!
Success :)
Again, thanks for your answer!
You will have to have a separate data set for your parameter query and yes you got that part right, for the given data set:
SELECT DISTINCT UserID
FROM TABLE
This query will be used to populate the drop down list of your parameter. (Multiple values allowed or not).
For you Main query:
if you allow Multiple Selection for #UserID parameter you will write you main Data set query with IN operator as below:
SELECT ID, Value, UserID
FROM table
WHERE (UserID IN (#UserID))
If you only want users to be able to select only one value at a time the you can write the above query with a where clause something like WHERE UserID = #UserID.
Make sure you map the variables correctly. But you will have to have a separate query for your drop down list.
This seems like it should be simple but I can't find anything yet. In Reporting Services I have a table with up to 6 rows that all have calculated values and dynamic visibility. I would like to sum these rows. Basically I have a number of invoice items and want to make a total. I can't change anything on the DB side since my stored procedures are used elsewhere in the system. Each row pulls data from a different dataset as well, so I can't do a sum of the dataset. Can I sum all the rows with a table footer? Similarly to totaling a number of rows in Excel? It seems very redundant to put my visibility expression from each row into my footer row to calculate the sum.
A few ways you could achieve this:
1. Do the calculation in the SQL and sum that field, like so:
SELECT Quantity, Amount, Quantity * Amount As TotalAmount FROM MyTable
Then just use the TotalAmount field in your Detail row and sum it in the footer.
2. Create a second Dataset that calculates the total for you and use that in your footer instead of a sum:
=Sum(Fields!TotalAmount.Value, "MyTotalingDataset")
3. Do it using custom code. Right-click on the Layout space choose Properties and click on the Code tab. Put in the following code:
Public Dim TotalAmount As Double = 0
Public Function CalculateRowTotal(ThisValue As Double, ThatValue As Double) As Double
TotalAmount = TotalAmount + (ThisValue * ThatValue)
Return ThisValue * ThatValue
End Function
On the Detail band, make the column where you sum the field have this expression:
=Code.CalculateRowTotal(Fields!Quantity.Value, Fields!Amount.Value)
This will execute the code above and do your calculation plus calculate the total sum in the process.
The Footer band displays the total sum so the column has the expression:
=Code.TotalAmount
And you're done. Just be careful because you aren't guaranteed the order in which your code will execute and for some reports it will execute the footer first (for example, if you use the Sum of the rows in the Detail band) which would make the total zero as the Detail band calculations haven't happened yet, but for the general case this should work.
You could change the db as follows.
Did you know you can get aggregated results in SQL without aggregating the data?
Just add an extra column to the dataset as follows:
,SUM(OrderQty) OVER(PARTITION BY SalesOrderID) AS 'Total'
In the above sample:
OrderQty is the value you wish to sum
SalerOrderID is the equivalent of 'GROUP BY'
You can use the same technique with COUNT, AVG and so on
More information here
http://msdn.microsoft.com/en-us/library/ms189461(SQL.90).aspx
In case you have a problem with the execution order, add a text box below of the table and display TotalAmount in this box.
I'm trying to create an ssrs report. Here's the data i have:
original data
I need to grouping and numbering based on specific column but ignoring the Entire entry row, the final result should be like this.
result
What's the grouping should be on case like this so i can put the number just like in my screenshot ?
Insert a matrix , row groups for Warehouse, Column1, Column 2
and for column groups use Amount, insert amount field with aggregate function of sum.
to add in the No. row, you will need to insert a empty column between column1 and column2 and insert an expression similar to:
=RunningValue(Fields!Test_case.Value, CountDistinct,"Tablix3" )
Whereby Fields!Test_case.Value is equivelant to Column1 and Tablix3 is equivelant to your matrix.
Example of design and report outcome, just need to correct expression for the No. column: