Copy name, project number, hours total from all employees timesheets in a directory vba

jimmygogo

New Member
Joined
Mar 29, 2022
Messages
18
Office Version
  1. 365
Platform
  1. Windows
Hi there, I am looking for help in writing a code where I can copy employee name, project numbers and total hours worked on each project per week from employee directory. Each employee has their own excel file.

1648580216567.png




Each week (separate tab for each week) hundreds of employee fill in their time sheet (example) below. For my purpose, I want the code to open each workbook, copy name (C8), Project numbers (B13 to end) and total hours (N13 to end) and then move on to the next employee.

1648580557275.png



Employee directory

1648580427785.png




Thank you in advance for your help.
 

Attachments

  • 1648580316486.png
    1648580316486.png
    74.5 KB · Views: 8
  • 1648580546247.png
    1648580546247.png
    53 KB · Views: 11

Excel Facts

Format cells as currency
Select range and press Ctrl+Shift+4 to format cells as currency. (Shift 4 is the $ sign).
I am working on this but have a couple questions:

How do you specify the week (or worksheet in the employee files) to copy cells from?

Which column should I use to decide which rows in the employee worksheet to copy cells from?
 
Upvote 0
Hey, Thanks for getting back to me. Program asks user to specify the week it copies from and the data is in column B (starts B13) and column N (starts N13). It should only copy project name if the hours are in column N. If no hours, it should loop to the next workbook.
 
Upvote 0
Do you plan a Userform to prompt the user for the week to process?

I am in USA so will usually handle a date as mm/dd/yyyy. From your OP it appears you handle dates as dd/mm/yyyy. Is that significant?

I will be working on this more to get you a usable solution soon.
 
Upvote 0
Thank you again. Yes, a box opens asking user to enter the date/month/year as all timesheets are saved every Sunday of the week for example, first time sheet ends on 09/01/2022.
 
Upvote 0
Is it correct to assume the week always ends on Sunday? I will check the user entered date is Sunday to valid the entry.
 
Upvote 0
Are you familiar with Defined Names on a worksheet?
 
Upvote 0
Yes, the weeks always ends on a Sunday. No, not familiar with the defined names on the a worksheet.
 
Upvote 0
I have something for you to try out and give feedback on. There is two code blocks. The first is to process the Userform:
VBA Code:
Option Explicit

Private Sub CommandButton1_Click()
  If Not IsDate(TextBox1.Text) Then
      MsgBox "Date required"
  Else
    If Weekday(TextBox1.Text) <> vbSunday Then  ' check if date is Sunday
      MsgBox "Date must be Sunday"
    Else
      Me.Hide
    End If
  End If
End Sub

Private Sub CommandButton2_Click()
  TextBox1.Value = ""
  Me.Hide
End Sub

The second should be in a standard code module:
VBA Code:
Option Explicit

Sub Main()
  Dim FileList As Collection, FileName As Variant, strFileName As String, EmployeeWB As Workbook
  Dim ProcessDate As Date, SummaryWS As Worksheet
  Dim srcEmployeeName As String, srcProjectNumber As String, srcProjectHours As String
  Dim EmployeeWS As Worksheet, EmployeeName As String, HourCell As Range, LastRow As Long
  
  srcEmployeeName = "$C$8"
  srcProjectNumber = "$B$13:$B$35"
  srcProjectHours = "$N$13:$N$35"
  
  UserForm1.Show
  If IsDate(UserForm1.TextBox1.Value) Then
    ProcessDate = UserForm1.TextBox1.Value
  Else
    Unload UserForm1
    Exit Sub
  End If
  Unload UserForm1
  
  Set SummaryWS = ActiveSheet
' find last row
  LastRow = GetLastRow(SummaryWS)
  
'  Set FileList = New Collection
' get all file names from employee folder
  Set FileList = GetAllFilenames("c:\TestFolder\*.xl*")
  
  If FileList.Count > 0 Then
    For Each FileName In FileList
      strFileName = "c:\TestFolder\" & CStr(FileName)
  '   open workbook read-only
      Set EmployeeWB = Workbooks.Open(strFileName, , True)
      For Each EmployeeWS In EmployeeWB.Worksheets
        If IsDate(EmployeeWS.Name) Then
          If ProcessDate = CDate(EmployeeWS.Name) Then
            EmployeeName = EmployeeWS.Range(srcEmployeeName).Value
            For Each HourCell In EmployeeWS.Range(srcProjectHours).Cells
              If HourCell.Value > 0 Then
'   copy cells from employee file to this file
                With SummaryWS
                  .Cells(LastRow + 1, 1).Value = EmployeeName
                  .Cells(LastRow + 1, 2).Value = EmployeeWS.Cells(HourCell.Row, 2)
                  .Cells(LastRow + 1, 3).Value = HourCell.Value
                End With
                LastRow = LastRow + 1
              Else
              End If
            Next HourCell
          Else
          End If
        Else
        End If
      Next EmployeeWS
  '   close employee file without saving
      EmployeeWB.Close False
    Next FileName
  End If
End Sub

Function GetAllFilenames(inPath As String) As Collection
  Dim StrFile As String, FileList As Collection
  Set FileList = New Collection
  StrFile = Dir(inPath)
  Do While Len(StrFile) > 0
    FileList.Add StrFile
    StrFile = Dir
  Loop
  Set GetAllFilenames = FileList
End Function

Function GetLastRow(sh As Worksheet) As Long
'Ron de Bruin, 5 May 2008
  On Error Resume Next
  GetLastRow = sh.Cells.Find(What:="*", After:=sh.Range("A1"), Lookat:=xlPart, _
                          LookIn:=xlFormulas, SearchOrder:=xlByRows, _
                          SearchDirection:=xlPrevious, MatchCase:=False).Row
  On Error GoTo 0
End Function

There is no code to trigger the actual gathering data from the employee sheets. I would suggest on the Summary sheet you have a button that links to the "Main" procedure.

I created a Userform to get the date to process. Ask if you need help with that.

let me know how it works or if you would like explanations of the code.
 
Upvote 0
I have something for you to try out and give feedback on. There is two code blocks. The first is to process the Userform:
VBA Code:
Option Explicit

Private Sub CommandButton1_Click()
  If Not IsDate(TextBox1.Text) Then
      MsgBox "Date required"
  Else
    If Weekday(TextBox1.Text) <> vbSunday Then  ' check if date is Sunday
      MsgBox "Date must be Sunday"
    Else
      Me.Hide
    End If
  End If
End Sub

Private Sub CommandButton2_Click()
  TextBox1.Value = ""
  Me.Hide
End Sub

The second should be in a standard code module:
VBA Code:
Option Explicit

Sub Main()
  Dim FileList As Collection, FileName As Variant, strFileName As String, EmployeeWB As Workbook
  Dim ProcessDate As Date, SummaryWS As Worksheet
  Dim srcEmployeeName As String, srcProjectNumber As String, srcProjectHours As String
  Dim EmployeeWS As Worksheet, EmployeeName As String, HourCell As Range, LastRow As Long
 
  srcEmployeeName = "$C$8"
  srcProjectNumber = "$B$13:$B$35"
  srcProjectHours = "$N$13:$N$35"
 
  UserForm1.Show
  If IsDate(UserForm1.TextBox1.Value) Then
    ProcessDate = UserForm1.TextBox1.Value
  Else
    Unload UserForm1
    Exit Sub
  End If
  Unload UserForm1
 
  Set SummaryWS = ActiveSheet
' find last row
  LastRow = GetLastRow(SummaryWS)
 
'  Set FileList = New Collection
' get all file names from employee folder
  Set FileList = GetAllFilenames("c:\TestFolder\*.xl*")
 
  If FileList.Count > 0 Then
    For Each FileName In FileList
      strFileName = "c:\TestFolder\" & CStr(FileName)
  '   open workbook read-only
      Set EmployeeWB = Workbooks.Open(strFileName, , True)
      For Each EmployeeWS In EmployeeWB.Worksheets
        If IsDate(EmployeeWS.Name) Then
          If ProcessDate = CDate(EmployeeWS.Name) Then
            EmployeeName = EmployeeWS.Range(srcEmployeeName).Value
            For Each HourCell In EmployeeWS.Range(srcProjectHours).Cells
              If HourCell.Value > 0 Then
'   copy cells from employee file to this file
                With SummaryWS
                  .Cells(LastRow + 1, 1).Value = EmployeeName
                  .Cells(LastRow + 1, 2).Value = EmployeeWS.Cells(HourCell.Row, 2)
                  .Cells(LastRow + 1, 3).Value = HourCell.Value
                End With
                LastRow = LastRow + 1
              Else
              End If
            Next HourCell
          Else
          End If
        Else
        End If
      Next EmployeeWS
  '   close employee file without saving
      EmployeeWB.Close False
    Next FileName
  End If
End Sub

Function GetAllFilenames(inPath As String) As Collection
  Dim StrFile As String, FileList As Collection
  Set FileList = New Collection
  StrFile = Dir(inPath)
  Do While Len(StrFile) > 0
    FileList.Add StrFile
    StrFile = Dir
  Loop
  Set GetAllFilenames = FileList
End Function

Function GetLastRow(sh As Worksheet) As Long
'Ron de Bruin, 5 May 2008
  On Error Resume Next
  GetLastRow = sh.Cells.Find(What:="*", After:=sh.Range("A1"), Lookat:=xlPart, _
                          LookIn:=xlFormulas, SearchOrder:=xlByRows, _
                          SearchDirection:=xlPrevious, MatchCase:=False).Row
  On Error GoTo 0
End Function

There is no code to trigger the actual gathering data from the employee sheets. I would suggest on the Summary sheet you have a button that links to the "Main" procedure.

I created a Userform to get the date to process. Ask if you need help with that.

let me know how it works or if you would like explanations of the code.
Hi there, Thanks for sending the code.
I created a userform1 and added two buttons as per the code above. When I enter date and hit command button 1, I get the following error, Do you know why am I getting this error ? I am very new at this so I may have created an incorrect user form

1649086382063.png

The userform1 I created.
1649086409681.png
 
Last edited:
Upvote 0

Forum statistics

Threads
1,215,046
Messages
6,122,849
Members
449,096
Latest member
Erald

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top