Chandoo posted an interesting challenge on his blog last Friday, challenging users to calculated hours worked for an employee name Billy. This example resonated with me for a couple of reasons. The first is that I’ve had to do this kind of stuff in the past, the second is because I’ve got a new toy I’d use to do it. (Yup… that toy would be Power Query.)
It always blows my mind how many people respond on Chandoo’s blog. As the answers were pouring in, I decided to tackle the issue my own way too. I thought I’d share a bit more detailed version of that here as I think many users still struggle with time in Excel.
Background and Excel Formula Solution
Chandoo provided a sample file on his blog, so I downloaded it. The basic table of data looks like this:
Now, for anyone who has done this a long time, there a few key pieces to solving this:
- The recognition that all times are fractions of days,
- The recognition that if you omit the day it defaults to 1900-01-01, and
- The data includes End times that are intended to be the day following the Start time
The tricks we use to deal with this are:
- Test if the End time is less than the start time. If so, add a day. (This allows us to subtract the Start from the End and get the difference in hours.
- Multiply the hours by 24. (This allows us to convert the fractional time into a number that represents hours instead of fractions of a day.)
Easy enough, and the following submitted formula (copied down from F4:F9 and summed) works:
=(D4+IF(C4>D4,1,0)-C4)*24
Also, there was a great comment that Billy shouldn’t get paid for his lunch break. Where I used to work (before I went out on my own), we had a rule that if you worked any more than 4 hours you MUST take a lunch break. Plumbing in that logic, we’d would need a different formula. There’s lots that would work, and this is one:
=((D4+IF(C4>D4,1,0)-C4)*24)-IF(((D4+IF(C4>D4,1,0)-C4)*24)>4,1,0)
So why Power Query?
If we can do this in Excel, why would we cook up a Power Query solution? Easy. Because I’m tired of having to actually write the formula every time Billy sends me his timesheet. Formula work is subject to error, so why not essentially automate the solution?
Using Power Query to Calculate Hours Worked
Okay, first thing I’m going to do is set up a system. I’m set up a template, email to Billy and get him to fill it out and email it to me every two weeks. I’ll save the file in a folder, and get to work.
- Open a blank workbook –> Power Query –> From File –> From Excel
- Browse and locate the file
- Select the “Billy” worksheet (Ok, to be fair, it would probably be called Sheet1 in my template)
- Click Edit
And now the fun begins…
- Home –> Remove Rows –> Remove Top Rows –> 2
- Transform –> Use First Row as Headers
- Filter the Day column to remove (null) values
- Select the Day:End columns –> right click –> Remove Other Columns
And we’ve now got a nice table of data to start with:
Not bad, but the data type for the Start and End columns is set to “any”. That’s bad news to me, as I want to do some Date/Time math. The secret here is that we need our values to be Date/Times (not just times), so let’s force that format on them, just to be safe:
- Select Start:End –> Transform –> Date/Time
Next, we need to test if the Start Date occurs after the End Date. Let’s use one step to test that and add one day if it’s true:
- Add Column –> Add Custom Column
- Name: Custom
- Formula: =if [Start]>[End] then Date.AddDays([End],1) else [End]
So basically, we add 1 day to the End data if the Start time is greater than the end time. Once we’ve done that, we can:
- Right click the End column –> Remove
- Right click the Custom column –> Rename –> End
And, as you can see, we’ve got 3 records that have been increased by a day (they are showing 12/31/1899 instead of 12/30/1899
Good stuff, let’s figure out the difference between these two. The order of the next 3 steps is important…
- Select the End column
- Hold down the CTRL key and select the Start column
- Go to Add Column –> Time –> Subtract
Because we selected the Start column second, it is subtracted from the End column we selected first:
Now we can set the Start and End columns so that only show times, as we don’t need the date portion any more. In addition, we want to convert the TimeDifference to hours:
- Select the Start:End columns –> Transform –> Time
- Select the TimeDifference column –> Transform –> Decimal Number
Hmm… that didn’t work quite as cleanly as we’d like:
Ah… but times are fractions of days, right? Let’s multiply this column by 24 and see what happens:
- With the TimeDifference column selected: Transform –> Standard –> Multiply –> 24
- Right click the TimeDifference column –> Rename –> Hours
Nice!
Oh… but what about those breaks?
- Add Column –> Add Custom Column
- Name: Breaks
- Formula: =if [Hours]>4 then -1 else 0
- Add Column –> Add Custom Column
- Name: Net Hours
- Formula: =[Hours]+[Breaks]
And here we go:
At this point I would generally:
- Change the name of the query to something like: Timesheet
- Close and Load to a Table
- Add a total row to the table
But just in case you only cared about the total of the Net Hours column, we could totally do that in Power Query as well. Even though it’s not something I would do (I’m sure Billy would trust YOU implicitly and never want to see the support that proved you added things up correctly…), here’s how you’d do it:
- Go to Transform –> Group By
- Click the – character next to the Day label to remove that grouping level
- Set up the Grouping column:
- Name: Net Hours
- Operation: Sum
- Column: Net Hours
Here’s what it looks like if you set the column details up first, indicating where to click to remove the grouping level:
And the result after you click OK:
Holy Cow that’s a LOT of Work!?!
Not really. Honestly, it took me about a minute to cook it up. (And a LOT longer to write this post.) But even better, this work was actually an investment. Next time I get a timesheet, I just save it over the old one, open this file, right click the table and click Refresh. Done, dusted, finished and time to move on to more challenging problems.
Even better, if I wanted to get really serious with it, I could implement a parameter function to make the file path relative to the file, and then I could pass it off to someone else to refresh. Or automate the refresh completely. After all, why write formulas every month if you don’t have to?
The post Calculate Hours Worked appeared first on The Ken Puls (Excelguru) Blog.