2

First of all, thanks everyone for helping yesterday.

I've managed to get my report working (so far) so now I need to show the date periods (FROM: TO:) in my header. Here is the query:

Declare @startdate  datetime
Declare @enddate  datetime
Declare @BeginningDate datetime

set @BeginningDate = '12-01-2011'

IF Month(@BeginningDate) < (Month(GETDATE())-1)--(YTD)
BEGIN
set @startdate = DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)
set @enddate = dateadd(day, datediff(day, 0, getdate()), 0)
END

IF Month(@BeginningDate) = (Month(GETDATE())-1)--(MTD)
BEGIN
set @startdate = dateadd  (mm,-1,
  DATEADD(dd,-(DAY(DATEADD(mm,1,convert(varchar(10),getdate(),111)))-1),
  DATEADD(mm,0,convert(varchar(10),getdate(),111))))--BEGINNING OF PRIOR MONTH
set @enddate =DATEADD(dd,-1,
  DATEADD(mm, 
  DATEDIFF(m,0,convert(varchar(10),getdate(),111)),0))--END OF PRIOR MONTH
END


IF Month(@BeginningDate) = (Month(GETDATE()))--(Current Period)
BEGIN
set @startdate = dateadd(month, datediff(month, 0, 
  dateadd(day, datediff(day, 1, getdate()), 0)), 0)--BEGINNING OF CURRENT MONTH
set @enddate = dateadd(day, 
  datediff(day, 0, getdate()), 0)--THROUGH CURRENT MONTH (TODAY)
END

If the user inputs the dates 11/27/2011 to 12-03-2011 as a search parameter then my header should show FROM: 11/01/2011 TO:11/30/2011 (MTD). If they select, for example, 12/01/2011 to 12/08/2011 then I need just those dates(Current Period). If the user inputs 10/01/2011-12/8/2011 then the period would be from 01/01/2011 to 12/8/2011 (YTD).

How would I set this up in SSRS as an expression? Do I need to create a data set based on these inputs and then call a parameter? I've done this using one date time frame but never something like this where there's multiple time frame issues.

Thanks in advance!

UPDATE: This is what I'm trying to accomplish in my SSRS expression:

="FROM:"&iif(Month(Parameters!BeginningDate.Value < (Month(today()-1)) THEN (DateAdd("d",-DatePart(DateInterval.DayOfYear,Today(),0,0)+1,Today())).tostring("dd/MM/yyyy")+"       "+"TO:today()"

If the user selects a beginning date greater than the previous month (e.g. 10/1) then the date returned should be 1/1/2011 to 12/16/2011

I hope this clarify's things.

Thanks!

Aaron Smith
  • 151
  • 2
  • 2
  • 13
  • @Ken White. How do you get the dates to 'high-lite' that way? Did you indent like you do with code? Still trying to learn all the tricks of the trade on here to minimize getting flamed :D Thanks! – Aaron Smith Dec 09 '11 at 16:55
  • Backticks (the backward apostrophe, on the same key as the ~ on US keyboards just below `Esc`) around them, treating them as inline code. – Ken White Dec 09 '11 at 17:00
  • Thank you! I forgot to ask this when I noticed this on a previous question. – Aaron Smith Dec 09 '11 at 17:07
  • @AaronSmith - That `iif` condition is going to get real ugly if you handle it that way. It will grow and grow and as soon as you think you got it working the requirements will change. You need to make use of some common date functions where if you have a single date, you can pass it to a function and it can return some nice information to you such as the first day of the month, the last day of the month, the month name, one week before the date passed, etc. See my answer below. – JonH Dec 16 '11 at 18:29
  • @JonH I was going to ask you about how I could incorporate the iif with your suggestion below. My problem is because of the dataset that I'm using this date issue for. The From/To will vary based on the `@BeginningDate` and so I am not sure how to incorporate your suggestion (which is amazing BTW) with my report requirements. – Aaron Smith Dec 16 '11 at 20:27
  • @AaronSmith - The nice thing is, the solution I posted wouldn't touch your `DataSet` you would add a new dataset in reporting services and that dataset would only bring you in those functions. You could then use this dataset in your report parameters. Remember in RS there is nothing holding you back from creating multiple datasets, this one would not interfer with your current one. Maybe it goes in depth, but I hope it gives you a good idea of why it could make your life easier. It's easier to deal with functions that handle dates and return results you want rather then confusing iif. – JonH Dec 16 '11 at 20:32
  • @JonH In depth is JUST fine! And just had a meeting with my boss and convinced her that what the project managers were asking for was making things more complicated than it had to be. Sooo... You're solution is saved and will soon be incorporated! Thank you for an amazing solution! – Aaron Smith Dec 16 '11 at 20:54
  • @AaronSmith - Let me know via comments or questions if you need help, I use these scalar functions all the time in reporting services it will make your life easier in the future when developing reports. For instance, here we have reports where end users need to have an automatic date range of one week before the selected date, these functions have made life easier. Good luck. – JonH Dec 16 '11 at 21:11
  • @JonH * TWO THUMBS UP * Will do! – Aaron Smith Dec 16 '11 at 21:28

1 Answers1

3

I posted this before, you need to make use of a dataset where you can call date functions. See if you can follow this: SQL Server: calculating date ranges it works wonders. Specifically look at the section that reads For Reporting Services Folks.

For you it will be really simple, if they select 11/27/2011 and you want to return 11/1/2011 you just call the dataset which in turns calls the function month_start. It is all well documented in that thread and used extensively.

The jist of it is you need this function in RS:

CREATE FUNCTION [dbo].[udfCommonDates] (@date datetime)
RETURNS @t table (week_start datetime,
                  week_end datetime,
                  lastweek_start datetime,
                  lastweek_end datetime,
                  month_start datetime,
                  month_end datetime,
                  lastmonth_start datetime,
                  lastmonth_end datetime,
                  yesterday_start datetime,
                  yesterday_end datetime,
                  today_start datetime,
                  today_end datetime,
                  thisweek_monday_start datetime,
                  thisweek_monday_end datetime,
                  year_start datetime,
                  year_end datetime,
                  tomorrow_noon datetime,
                  today_noon datetime,
                  date_only datetime)
BEGIN
   INSERT @t
   SELECT
   dbo.get_week_start ( @date ) AS week_start,
   dbo.get_week_end   ( @date ) AS week_end,
   dbo.get_week_start ( DATEADD(d, -7, @date ) ) AS lastweek_start,
   dbo.get_week_end   ( DATEADD(d, -7, @date ) ) AS lastweek_end,
   dbo.get_month_start( @date ) AS month_start,
   dbo.get_month_end  ( @date ) AS month_end,
   dbo.get_month_start ( DATEADD(m,-1, @date) ) AS lastmonth_start,
   dbo.get_month_end  ( DATEADD(m,-1,@date) ) AS lastmonth_end,
   dbo.get_yesterday_start ( @date ) AS yesterday_start,
   dbo.get_yesterday_end ( @date ) AS yesterday_end,
   dbo.get_today_start (@date) AS today_start,
   dbo.get_today_end ( @date ) AS today_end,
   dbo.get_weekday_start(1,@date) AS thisweek_monday_start,
   dbo.get_weekday_end(1,@date) AS thisweek_monday_end,
   dbo.get_year_start(@date) AS year_start,
   dbo.get_year_end(@date) AS year_end,  
   dbo.get_tomorrow_noon(@date) AS TomorrowNoon,
   dbo.get_today_noon(@date) AS TodayNoon,
   dbo.get_date_only(@date) AS DateOnly
RETURN
END

Then you need the scalar valued functions for each one:

   CREATE FUNCTION [dbo].[get_date_only] (@date datetime)
    RETURNS datetime
    WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
    AS    
    BEGIN
        RETURN dateadd(day, DateDiff(day, 0, GetDate()), 0)
    END
    GO

CREATE FUNCTION [dbo].[get_month_end] (@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    
BEGIN
   RETURN dateadd(ms, -3, dateadd (m,datediff(m,0,
          dateadd(m,1,@date)),0))
END
GO

CREATE FUNCTION [dbo].[get_month_start] (@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    
BEGIN
   RETURN dateadd(m,datediff(m,0, @date),0)
   END
GO

CREATE FUNCTION [dbo].[get_today_end] (@today datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    
BEGIN
   return dateadd(ms, -3, datediff(d,0,dateadd(d,1,@today)))
END
GO

CREATE FUNCTION [dbo].[get_today_noon](@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    BEGIN
   RETURN DATEADD(hh, 12, DATEADD(d,DATEDIFF(d,0, @date),0))
END
GO

CREATE FUNCTION [dbo].[get_today_start] (@today datetime)
RETURNS datetime 
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    BEGIN
   return dateadd(day, 0, datediff(d,0,@today))
END
GO

CREATE FUNCTION [dbo].[get_tomorrow_noon](@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    BEGIN
   RETURN DATEADD(hh, 12, DATEADD(d,DATEDIFF(d,-1, @date),0))
END
GO

CREATE FUNCTION [dbo].[get_week_end] (@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    BEGIN
   return dateadd(yyyy, datepart(yyyy,
      dateadd(weekday,7-datepart(weekday, @date),@date))-1900, 0)
    + dateadd(ms, -3,
      dateadd(dy, datepart(dy,
     dateadd(weekday,7-datepart(weekday, @date),@date)),0) )
END
GO

CREATE FUNCTION [dbo].[get_week_start] (@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    BEGIN
   return dateadd(yyyy, datepart(yyyy,
      dateadd(weekday,1-datepart(weekday, @date),@date))-1900, 0)
    + dateadd(dy, datepart(dy,
      dateadd(weekday,1-datepart(weekday, @date),@date))-1,0)
END
GO

CREATE FUNCTION [dbo].[get_weekday_end] (@weekday tinyint,
                                 @date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    BEGIN
   return dateadd(yyyy, datepart(yyyy,
      dateadd(weekday,@weekday-
      datepart(weekday, @date),@date))-1900, 0)
    + dateadd(ms, -3,
      dateadd(dy, datepart(dy,
      dateadd(weekday,@weekday-datepart(weekday, @date),
                                        @date)),0) )
END
GO

CREATE FUNCTION [dbo].[get_weekday_start] (@weekday tinyint,
                                   @date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    BEGIN
   return dateadd(yyyy, datepart(yyyy,
      dateadd(weekday,@weekday-
      datepart(weekday, @date),@date))-1900, 0)
    + dateadd(dy, datepart(dy,
      dateadd(weekday,@weekday-datepart(weekday, @date),
                                        @date))-1,0)
END
GO

CREATE FUNCTION [dbo].[get_year_end] (@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    BEGIN
RETURN DATEADD(year, DATEDIFF(year, 0, GetDate())+1, 0)-1
END
GO

CREATE FUNCTION [dbo].[get_year_start] (@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    BEGIN
   RETURN DATEADD(year,DATEDIFF(year,0, @date),0)
END
GO

CREATE FUNCTION [dbo].[get_yesterday_end] (@today datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    BEGIN
   return dateadd(ms, -3, datediff(d,0,@today))
END
GO

CREATE FUNCTION [dbo].[get_yesterday_start] (@today datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS    BEGIN
   RETURN dateadd(day, -1, datediff(d,0,@today))
END
GO

Now the hard work is done for reporting services remember a dataset can be a stored procedure or a direct table. So you would simply create a stored procedure:

CREATE PROCEDURE [dbo].[uspCommonDates] AS
begin
   set datefirst 1
   declare @date datetime
   set @date = getdate()
   select * from dbo.udfCommonDates(@date)
end

And use this stored procedure as a dataset. So now you have access to all of these nice date functions. So you can now go to your parameters section and call these functions like so:

enter image description here

Community
  • 1
  • 1
JonH
  • 32,732
  • 12
  • 87
  • 145