Take Datetime and give the half hour band it belongs to, irrespective of the date, just interested in the time.
There is as far as I can see, no time periods in SSRS, I need half hour time periods, that's 48 blocks in a day.
I would like to plot my data in bar chart,the interval for the bar width is along the x axis, the height is the occurrences on the y axis. I need an interval of half hour(the width of the histogram),I don't want to run some IIF/CASE statement, I would rather, convert the DateTime i have to a band on each row of data, what's the best way to output so I get half hour intervals along the X axis.
I don't want to run some IIF/CASE statement
By this I assume you mean you don't want 48 layers of IIF/CASE. Here's an SSRS expression that'll band a datetime just using a single IIF:
=DateAdd(DateInterval.Minute, 0-
IIF(Minute(Fields!DATETIMEFIELD.Value) <= 29, Minute(Fields!DATETIMEFIELD.Value), Minute(Fields!DATETIMEFIELD.Value) -30),
DateAdd(DateInterval.Second, 0-Second(Fields!DATETIMEFIELD.Value) ,Fields!DATETIMEFIELD.Value))
This removes the seconds from the time, and removes as many minutes necessary to get to the previous half-hour. You could likely use the same logic with different syntax as a column in your SQL query, if you prefer.
Use this calculated value for all the relevant parts of your SSRS chart.
Related
I'm stuck with a problem in SSRS 2012 that maybe is very simple:
I have a matrix with a group row (employee) and a group column (last 12 months); the values are COUNT(practicesDone) - i.e. the amount of practices worked.
I want the matrix to show an extra column on the right (after all the columns of the months, and clearly outside the column group) with again the number of practices for the current month.
Is it possible to achieve that?
thank you in advance!
You can do this, it's pretty simple.
I have assumed that your dataset contains a column that has a date for each entry and that the data returned only covers 12 months so the same month would not appear for different years. If your data does have multiple years, look at the second expression below.
Right-click your month column and then to "Insert Column --> Outside Group - Right"
Now set the expression for the text box to
=COUNT(IIF(MONTH(Fields!myDateColumn.Value) = MONTH(TODAY()), 1, Nothing))
You could swap COUNT for SUM and it should do the same thing but either will work.
All we are doing here is comparing the all data in scope which, due to the placement of the text box means the scope is the entire rowgroup. Then for all that data, check if the month matches the current month, if it does set it to 1 is not set it to nothing then count/sum all results. Count conveniently ignores 'nothing'.
If you data covers more than 12 months then you can still do this but you'll have to add a bit more to handle years and months like this.
=COUNT(
IIF(
MONTH(Fields!myDateColumn.Value) = MONTH(TODAY())
AND YEAR(Fields!myDateColumn.Value) = YEAR(TODAY()),
1,
Nothing
)
)
First post in stackoverflow - so forgive me if I don't get this right. I have an SSRS report with a matrix which groups Quantity, Total Spend and Average Cost by part number for each year. Part Number and description down the left and the the years along the top. I want to add a delta column in each year after the first year which shows the change in price from the previous year. I have seen examples of how to get the difference between first and last year - but not the difference between each year and the previous one. I have hidden the delta column for the first year - no would love some guidance on how to calculate the difference in cost.
So from the image below the first row in the delta column under FY2019 would show -€0.01 as price has reduced from 0.59 to 0.58.
You haven't explained how if Avg. Cost is calculated in your report but I'm assumming it's just something like =SUM(Fields!Spend.Value) / SUM(Fields!Qty.Value)
You've not shown your report design so I can't tell what your row/column groups are called but I'll assume you have rowgroup by Part and one by Year. Let's assume your column group name is PeriodID so it's the same as my demo report.
In this case you can use the PREVIOUS() function to get the previous values to compare against.
I set up a similar report to demonstrate. As you can see in my case the year column is grouped using a columngroup called PeriodID
The expressions highlighted are as follows.
Price. This is just Cost/Qty =SUM(Fields!Cost.Value)/SUM(Fields!Qty.Value)
lastprice. This is just for illustration and debugging. It uses the PREVIOUS() fucntion to get the previous year's data
=Previous(Sum(Fields!Cost.Value), "PeriodID") / Previous(Sum(Fields!Qty.Value), "PeriodID")
Note that "PeriodID" is the name of the column group (case sensitive). This is scope for the previous function so it know to get data from the previous column group.
delta. This is the final output. It's just the current "Price" expression minus the "lastprice" expression.
=(Sum(Fields!Cost.Value) / Sum(Fields!Qty.Value)) - (Previous(Sum(Fields!Cost.Value), "PeriodID") / Previous(Sum(Fields!Qty.Value), "PeriodID"))
The final output looks like this (I've not hidden the column for the first column group or hidden last price, just so you can see it working). Also, if you see slight differences in the delta column compared to what you might expect, it's just down to the fact that the numbers are formatted to 2 decimals but my test data is up to 14 decimals.
I have recently been putting together an SSRS report that will run every 15 minutes for the previous 15 minute 'chunk' of time. In essence a very straight forward and simple report that will run via an automated subscription.
I was using Microsoft SQL Server 12 Report Builder Version 3.
I was alerted to an issue with the output csv when my recipient reported being sent blank files, most odd considering the report generated as expected when run manually.
Long story short, it was the expressions I was using to generate the From and To dates. Manual runs produced data, subscription runs did not.
Original parameters
FromDate
dateadd(DateInterval.Second, (second(now()) + 900) * -1, dateadd(Dateinterval.Minute, (minute(now()) mod 15) * -1, now()))
ToDate
dateadd(DateInterval.Second, (second(now()) + 1) * -1, dateadd(Dateinterval.Minute, (minute(now()) mod 15) * -1, now()))
New Parameters
FromDate
dateadd(DateInterval.Minute, -15, dateadd(DateInterval.Minute, cint(datediff(DateInterval.Minute,today(),now()) / 15) * 15, today()))
ToDate
dateadd(DateInterval.Second, 899,Parameters!FromDate.Value)
Thought I would post this here for two reasons
Theories as to why
It might help someone in the future
Your original parameters take Now and subtract the minutes to arrive at a 15-minutes time, then they take the seconds of another Now (which is later and could be in the next second or even minute) and subtract that value to arrive at a 0-second time (or a 59-second time). This could already cause a problem when there is a change of seconds between the first and the second Now, which isn't very unikely, as on my test system there were 0.59 seconds between the two evaluations of Now in the FromDate parameter. Also, the Now value is more accurate than just a second, and your formula does not respect that. Therefore, if the records you are trying to process in your report happen to have a time of exactly a quarter of an hour, the first parameter is for sure greater (by maybe 0.01 second) and so the record is ignored.
Your formula for the "new parameters" does not depend on the seconds of Now() and will always return a time with no fraction of a second, so I guess that that's what makes the difference.
The expression for the FromDate could be simplified a little:
=Today.AddSeconds(900*(DateDiff(DateInterval.Minute, Today, Now)\15-1))
If you do not plan to run the report very short before midnight, there should not be a problem caused by a change of the day during the evaluation of Today and Now, and you could calculate the second parameter in a similar way, independently from the first one:
=Today.AddSeconds(900*(DateDiff(DateInterval.Minute, Today, Now)\15)-1)
The original parameter values were being calculated individually which means they would each have slightly different values for Now(). I know this is a long shot, but it's a theory. If the subscription job fired off a fraction of a second before a 15 minute interval, it's possible that the ToDate returned just before the FromDate. This would result in an invalid date range.
With the new expressions, the ToDate is referencing the FromDate which forces them to be calculated in sequence, not in parallel. Not to mention you're adding to the FromDate which also forces the date range to have a consistent length. However, you may still run into a case where you get the same report twice if the FromDate is calculated on the wrong side of a 15 minute cutoff.
One way to test/avoid this issue would be to offset the subscription time so that it doesn't actually try to fire at the exact 15 minute cutoffs. For example, you could have it scheduled to go off 1 minute afterwards.
I am creating a line chart to show sales prospecting data. I have 4 sets of values: Monthly Revenue at 100% confidence, Monthly Revenue adjusted to actual confidence %, Yearly Revenue at 100% confidence, and Yearly Revenue adjusted to actual confidence %. I'm using a RunningValue() function to calculate the "Yearly" values, both 100% and adjusted, which are separated as a Series Group on each year. The RunningValue is working perfectly, but I would like the line to end at the end of the year (or series), rather than plateauing through the rest of the graph. I'm thinking using an expression on the Pick Color selection, so that if the Year is greater than current running year, set it to No Color, but I'm not sure how to write that expression.
The highlighted yellow areas are what I would like to remove.
A minor supplemental question is, can I eliminate the doubling up of the legend that occurs from the Series Group separation, which I need to use because I want the separate line rather than having a drastic drop between years.
Add a condition to your running value expression so that it evaluates the year. I would use this on the value rather than the Color.
=IIF(YEAR(FIELDS!YourDateField.Value) <= YEAR(TODAY), <YOUR RUNNING TOTAL EXPRESSSION> , NOTHING)
Use de 'Field Scope' in the RunningValue() expression. This way, the ruuning 'resets' every year.
=RunningValue(Fields!MonthlyRevenue.Value,sum,"NameOfYearField")
Alright, this is kind of a convoluted problem, so bear with me:
I have a chart that displays 25 hours worth of data from rows sent to it. The hours of the data are to be displayed starting and ending with the 22nd hour. That is, the x axis goes 22, 23, 0, 1, 2, ... 22. It's important to note that there are two 22nd hours on two separate days.
Now, it is possible that the database will not return some rows. In which case, there must be an empty space for that hour. However, there must still be 25 x axis values.
This combination of restrictions has me stumped. I can't represent the x axis as a custom scalar, because the values are to be displayed out of order and duplicated. And I can't find a way to use an x axis category because I won't get all of the categories from the data and, again, there is a duplicated 22nd hour.
Any help is appreciated, let me know if I can provide any additional information.
I would add a column to the dataset to calculate a "relative hour". This would start with a value of 0 for the 22nd hour, 1 for the 23rd etc finishing with 25 for the 2nd 22nd hour.
Then I would change the Category Group definition in the Chart to use that "relative hour" value as the "Group On" value. Note the Label can remain as is.
I would change the source dataset so that it always returns a row for all the 25 x axis values, e.g. via a right join to a numbers table. Rows representing those "missing" hours will need both the "relative hour" value and your existing hour column value for the label.