Link to home
Start Free TrialLog in
Avatar of HSI_guelph
HSI_guelphFlag for Canada

asked on

Need help recreating an excel lieu time sheet in SSRS

I'm trying to recreate a lieu time report currently in excel.  I have a table storing hours entered, the code (billable, personal, vacation, etc.) against which it is entered, the date and the employee id.  I can easily pull out all the data for a given employee beginning with the start of our fiscal year (May 1) but I'm not sure about how to group it by the week ending.  Plus I have a separate table where I've generated all the days of the year and marked it as either a work day, weekend or holiday (as well as other information).  

This is the sheet I'm trying to recreate:
User generated image  

And here is the code I used to create the calendar table (I didn't include the last part where I mark the holidays).  Though I think perhaps I should have included the week ending day.
IF EXISTS(SELECT * FROM sys.tables WHERE name='WorkCalendar') 
	DROP TABLE WorkCalendar
GO

CREATE TABLE WorkCalendar (
	PKDate date primary key, 
	-- Years
	calendar_year smallint,
	-- Quarters 
	calendar_quarter tinyint, 
	calendar_quarter_desc varchar(10),  
	-- Months
	calendar_month tinyint, 
	calendar_month_name_long varchar(30), 
	calendar_month_name_short varchar(10), 
	-- Weeks
	calendar_week_in_year tinyint, 
	calendar_week_in_month tinyint, 
  
    -- added
	pay_week_in_month tinyint,  
  
	-- Days
	calendar_day_in_year smallint, 
	calendar_day_in_week tinyint,  -- The first of the month 
	calendar_day_in_month tinyint, 
	mdy_name_long varchar(30), 
	mdy_name_long_with_suffix varchar(30), 
	day_name_long varchar(10), 
	day_name_short varchar(10), 
	description varchar(30), 
	is_weekend tinyint,            -- Tinyint and not bit so you can add the 1's. 
	is_holiday tinyint,            -- Tinyint and not bit so you can add the 1's. 
	is_workday tinyint,            -- Tinyint and not bit so you can add the 1's. 
	is_event tinyint               -- Used to indicate any special event days. 
	)
;

DECLARE @dt_start date = '20120101'
      , @dt_end date   = '20160430'
      , @total_days int
      , @i int = 0
      , @start_Month int = 5 -- added


SELECT @total_days = DATEDIFF(d, @dt_start, @dt_end) 

WHILE @i <= @total_days
	begin
	INSERT INTO WorkCalendar (PKDate) 
	SELECT CAST(DATEADD(d, @i, @dt_start) as DATE) 

	SET @i = @i + 1
	end
;

UPDATE WorkCalendar
SET 
      calendar_year = YEAR(PKDate), 
      calendar_quarter = DATEPART(q, PKDate),
      calendar_month = DATEPART(m, PKDate), 
      calendar_week_in_year = DATEPART(WK, PKDate), 
      calendar_day_in_year = DATEPART(dy, PKDate), 
      calendar_day_in_week = DATEPART(Weekday, PKDate),
      calendar_day_in_month = DATEPART(d, PKDate),
      day_name_long = datename(weekday, PKDate)
;

UPDATE WorkCalendar
SET 
      is_weekend = CASE DATEPART(weekday, PKDate) WHEN 1 THEN 1 WHEN 7 THEN 1 ELSE 0 END, 
      calendar_quarter_desc =  'Q' + CAST(calendar_quarter as char(1)) + ' ' + CAST(calendar_year as char(4)), 
      calendar_month_name_long = DATENAME(m, PKDate) + ' ' + CAST(calendar_year as CHAR(4)),
      mdy_name_long = DATENAME(m, PKDate) + ' ' + CAST(DATEPART( d, PKDate ) as varchar(2)) + ', '  + CAST(calendar_year as CHAR(4)),
      day_name_short = LEFT(datename(weekday, PKDate),3)
;
UPDATE WorkCalendar
SET calendar_week_in_month = 
CASE
    WHEN DATEPART(DAY, PKDate) BETWEEN 1 AND 7 THEN 1
    WHEN DATEPART(DAY, PKDate) BETWEEN 8 AND 14 THEN 2
    WHEN DATEPART(DAY, PKDate) BETWEEN 15 AND 21 THEN 3
    WHEN DATEPART(DAY, PKDate) BETWEEN 22 AND 28 THEN 4
    ELSE 5
END
;

-- added
update WorkCalendar
set pay_week_in_month = sq.PAY_WEEK_IN_MONTH
from WorkCalendar
inner join (
              
              SELECT
                      dense_rank() over (partition by fy_start
                                                    , month(paywk_end)
                                         order by paywk_start)         as PAY_WEEK_IN_MONTH
                    , pkdate
              FROM WorkCalendar AS cal
              cross apply (
                           /* calc the number of days to reach Saturday of this "week" */
                           select abs((datediff(day,6,pkdate) % 7) - 6) 
                          ) ca1 (to_sat)
              cross apply (
                           select
                                  dateadd(day,-6,dateadd(day,to_sat,pkdate))
                                , dateadd(day,to_sat,pkdate)
                                , dateadd(month,@start_month-1,
                                          case when month(pkdate) >= @start_month
                                                    then cast(dateadd(year,year(pkdate)-1900,0) as date)
                                               else cast(dateadd(year,year(pkdate)-1901,0) as date)
                                          end)
                          ) ca2 (pay_start,pay_end, fy_start)
              cross apply (
                           select
                                   case when month(pay_start) < @start_Month and
                                             month(pay_end)   = @start_Month and
                                             datediff(day,fy_start, pay_end) < 8
                                               then fy_start
                                        else pay_start
                                   end
                
                                 ,  case when month(pay_start) < @start_Month and
                                             month(pay_end)   = @start_Month and
                                             datediff(day,fy_start, pay_end) > 365
                                               then dateadd(day,-1,dateadd(year,1,fy_start))
                                        else pay_end
                                   end
                
                          ) ca3 (paywk_start,paywk_end)
              WHERE cal.pkdate BETWEEN @dt_start AND @dt_end
              ) sq on WorkCalendar.pkdate = sq.pkdate
; 

Open in new window


I am not sure how to generate this report.  Should it be a Matrix with the codes at the top?  Should I group codes together in the ds query, such as the PE3 and PE6 Personal Time?  Perhaps I need the initial query to return results for each week with grouped codes?  

Any suggestions on how to get this up and running would be greatly appreciated!!!
Avatar of Phillip Burton
Phillip Burton

You've given the WorkCalendar table, but not the actual data table.

I know what you have in Excel, but presumably have you just transferred the Excel table into SQL Server as is, or have you normalised it, or what?

A bit more information there is essential.

I would suggest starting with a Matrix, and then see if there is anything you need to add afterwards (such as Parameters). Start small, and work up.
Avatar of HSI_guelph

ASKER

Here are the results from the tables
User generated imageUser generated image
Are these tables related? I can see you have a "Week number" in "Work Calendar data", but do you have a date there for the start of the Week? That seems to be the thing you are lacking (unless it is hidden from your screenshots).

It can be added with a little SQL if you haven't got it using the WEEKDAY function. It's easier if you have SQL Server 2008R2 or greater, because then you can use the DATE function, i.e.

DATE(year(MyDate), month(MyDate), day(MyDate) - WEEKDAY(MyDate,2) + 1)

Once that is in place, so do the Matrix, with Service going across, and Week Ending going down.
No there is no start of the week but should I put a start of the week or end of the week?  This was originally set up because I was going to make a report that would show the hours per week of the month so dividing the weeks up where one month ends and another begins was a goal.  We are using SQL Server 2008 R2 so I can add that column to the table. I'm just not sure how to get the rows to group by week.  Does this have to be done in the query or can it be done in the row groups pane?
ASKER CERTIFIED SOLUTION
Avatar of Phillip Burton
Phillip Burton

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Got something working for now but I'll continue to work with it to achieve the result I want.  Thanks for helping me work through this!