Data transformation formula

sumsaam

Board Regular
Joined
Dec 31, 2012
Messages
82
Office Version
  1. 2010
Platform
  1. Windows
1-4 to 20-4.xlsx
ABCDEFGHIJKLMN
1IDName
2IDNameDateTime log8Hasnain
38Hasnain01-04-202310:58Date1234567
48Hasnain01-04-202323:1610:58 23:1612:36 22:5011:21 22:4311:20 13:30 14:22 22:4111:00 12:11 12:29 22:3911:06 22:4314:58 19:48 20:21 23:18
58Hasnain02-04-202312:36IDName
68Hasnain02-04-202322:509Ali
78Hasnain03-04-202311:21Date1234567
88Hasnain03-04-202322:4311:06 23:1612:05 22:4612:19 22:4211:20 22:4111:00 14:47 14:57 22:3914:58 23:17
98Hasnain04-04-202311:20
108Hasnain04-04-202313:30
118Hasnain04-04-202314:22
128Hasnain04-04-202322:41
138Hasnain05-04-202311:00
148Hasnain05-04-202312:11
158Hasnain05-04-202312:29
168Hasnain05-04-202322:39
178Hasnain06-04-202311:06
188Hasnain06-04-202322:43
198Hasnain07-04-202314:58
208Hasnain07-04-202319:48
218Hasnain07-04-202320:21
228Hasnain07-04-202323:18
239Ali01-04-202311:06
249Ali01-04-202323:16
259Ali02-04-202312:05
269Ali02-04-202322:46
279Ali03-04-202312:19
289Ali03-04-202322:42
299Ali04-04-202311:20
309Ali04-04-202322:41
319Ali05-04-202311:00
329Ali05-04-202314:47
339Ali05-04-202314:57
349Ali05-04-202322:39
359Ali07-04-202314:58
369Ali07-04-202323:17
Sheet1



I have attendence logs of my staff (Left side) from biometric attendance machine, I want to sort this data in form of right side table, formula should take input like ID,Name and date in corresponding cells of right side table and return the time logs. the character used between to logs is Alt+Enter. I use Excel 2010.
 
Last edited:

Excel Facts

How can you automate Excel?
Press Alt+F11 from Windows Excel to open the Visual Basic for Applications (VBA) editor.
I put together code below that does what you asked for. I have Office 365 so there is a chance that this will not work for you. If it does not work with Excel 2010 then I am not sure what I can do. Let me know if you have questions.

The workbook is HERE.

Primary Sub

VBA Code:
Option Explicit
Option Base 1

Sub SummarizeData()

'   ----------------------------
'          Declarations
'   ----------------------------

'   Workbook where data is located.
    Dim wsData As Worksheet

'   Workbook into which results are place.
    Dim wsResults As Worksheet

'   Upperleftmost cell where data are located.
    Dim rAnchorCellData As Range

'   Upperleftmost cell where results are located.
    Dim rAnchorCellResults As Range

'   Count of rows in the data range.
    Dim iDataRowsCount As Long

'   Count of rows in results FOR EACH PERSON.
    Dim iPersonResultsRowsCount As Long

'   Count of rows in results FOR EACH PERSON.
    Dim iRowsToClearCount As Long

'   For looping through the rows in the data.
    Dim iDataRow As Long

'   Array that contains all data.
    Dim avData() As Variant

'   Array used to keep track of the IDs encountered -- one per person.
'   "Row" 1 is the ID number, "row" 2 is the name "row" 3 is count of
'   data rows for a person
    Dim avUniqueIDsFound() As Variant

'   Keep track of unique IDs encountered in data.
    Dim iUniqueIDsCount As Long

'   Used to loop unique IDs array.
    Dim iUniqueIDIndex As Long

'   String holding the unique ID for a person.
    Dim sUniqueID As String

'   Used while looping to determine if there is a change of ID
'   from one data row to the next.
    Dim sCurrentID As String

'   Count of rows (entries) to process.
    Dim iEntriesCount As Long

'   Used for looping through entries.
    Dim iEntryIndex As Long

'   Used to keep track of the how many rows of data have been processed.
'   That is needed to determine the next data row to process relative to
'   the data anchor cell rAnchorCellData (e.g. when gathering data for a person.
    Dim iDataRowsProcessed As Long

'   Used to keep track of which day of the week is being processed 1 - 7.
    Dim iOneToSeven As Long

'   Used to keep track of how many times there are for a given person
'   in a given day. Either two or four. Four if there are two time in and
'   time out time stamps for a person in one day.
    Dim iOneToFour As Long

'   String used to gather time(s) in and time(s) out for a person for a
'   given day.
    Dim sTimes As String

'   Used to determime if the date for the next time in/time out entry
'   is the same date as the curren time in/time out entry.
    Dim bIsSameDate As Boolean

'   Is there a date "missing" for a person in the data meaning that she
'   did not work the next day.
    Dim bIsSkipDate As Boolean
   
    Dim iDaysMissing As Long

'   Count of rows in te data for the person being processed.
    Dim iPersonRowsCount As Long

'   Date of the data row being processed.
    Dim dCurrentDate As Date

'   Date of the next bdata row to process.
    Dim dNextDate As Date

'   ----------------------------
'         Initializations
'   ----------------------------

    Application.ScreenUpdating = False

    Set wsData = ThisWorkbook.Worksheets("Sheet1") '<= Name of sheet containg data

    Set rAnchorCellData = wsData.Range("B2") '<= (Header) cell where data starts
   
    Set wsResults = ThisWorkbook.Worksheets("Sheet1") '<= Name of sheet containg data

    Set rAnchorCellResults = wsResults.Range("G1") '<= cell where results start

    iPersonResultsRowsCount = 4 '(e.g., rows 1 through 4 for first person processed.

    iDataRowsCount = rAnchorCellData.CurrentRegion.Rows.Count - 1

'   Set up array to hold values for 4 "columns".
'   Minus one because we skip the header row.
'   1. ID, 2. Name, 3. Date, 4. Time
    ReDim avData(1 To 4, 1 To iDataRowsCount)

'   Set up array to hold values for 3 "columns".
'   1. ID, 2. Name, 3. Entries Count. One "row"
'   for each person.
    ReDim avUniqueIDsFound(1 To 3, 1)

'   ----------------------------------
'         Clear existing results
'   ----------------------------------

    With rAnchorCellResults
   
        iRowsToClearCount = .Offset(100000).End(xlUp).Row - .Row + 2

        .Resize(iRowsToClearCount, 8).Clear
   
    End With

'   ----------------------------
'         Fill Data Arrays
'   ----------------------------

    iUniqueIDsCount = 0

    Call FillDataArray(rAnchorCellData, iDataRowsCount, avData)
   
    Call FillUniqueIDsArray(rAnchorCellData, avData, avUniqueIDsFound)
   
    iUniqueIDsCount = UBound(avUniqueIDsFound, 2)
   
'   For some reason SOMETIMES the call to funtion FillUniqueIDsArray
'   Reports n+1 iUniqueIDsCount. Must decrement the count to
'   account for that. Look for an empty array element in "row"
'   n+1 to determine if that happened. If there is no "row" n+1
'   then this command causes an error.
    On Error Resume Next
    If avUniqueIDsFound(1, iUniqueIDsCount) = "" Then iUniqueIDsCount = iUniqueIDsCount - 1
    On Error GoTo 0
   
'   Resize the array so it has just the right number of "rows."
    ReDim Preserve avUniqueIDsFound(1 To 3, iUniqueIDsCount)

'   -----------------------------------------------------
'         Put Results Labels into the Results Area
'   -----------------------------------------------------
   
    For iUniqueIDIndex = 1 To iUniqueIDsCount

'       Adds results labels in the results range. NO DATA.
        Call CreateLabels( _
            avUniqueIDsFound, _
            rAnchorCellResults, _
            iUniqueIDIndex, _
            iPersonResultsRowsCount)

        sUniqueID = avUniqueIDsFound(1, iUniqueIDIndex)

    Next iUniqueIDIndex

'   ----------------------------------------------
'        Put Array Data into the Results Area
'   ----------------------------------------------

'   Used to keep track of how many data rows have been processed. Needed
'   to determine the next data row to process relative to the data
'   anchor cell rAnchorCellData. To this value is added the iRow number hence
'   initialize to zero.
    iDataRowsProcessed = 0

'   Iterate through all unique IDs found.
    For iUniqueIDIndex = 1 To iUniqueIDsCount

'       For unique IDs # two to n update the row offset for accessing each
'       data row in worksheet data. That value starts at zero for first
'       iteration.
        If iUniqueIDIndex > 1 _
         Then
            iDataRowsProcessed = iDataRowsProcessed + avUniqueIDsFound(3, iUniqueIDIndex - 1)
        End If
       
'       The count of data rows for the person being processed is in array
'       avUniqueIDsFound "column" 3. Row is iUniqueIDIndex
        iPersonRowsCount = avUniqueIDsFound(3, iUniqueIDIndex)
       
'       Initialize variable that keeps track of how many days were "skipped"
'       for a person being processed for the week being processed.
        iDaysMissing = 0
       
        bIsSkipDate = False

'       Process all data rows for a person.
        For iDataRow = 1 To iPersonRowsCount

'           Get the date for the current data row being processed. It is in the
'           avData in column 3, row iDataRow + iDataRowsProcessed.
            dCurrentDate = avData(3, iDataRow + iDataRowsProcessed)

            If iDataRow = iPersonRowsCount _
             Then

'               If processing the final data row for a given person
'               then next date is irrelavant so set it to zero.

                dNextDate = 0
            Else
                dNextDate = avData(3, iDataRow + iDataRowsProcessed + 1)
            End If

'           Determine if the current date = the next date.
'           Set bIsSameDate accordingly, unless it is the last
'           data row for the person being processed.
            If iDataRow = iPersonRowsCount _
             Then
                bIsSameDate = False
            Else
                bIsSameDate = dCurrentDate = dNextDate
            End If
                       
'           Gather the times for the person-day being processed.

'           Add a linefeed character if this is not the first
'           time that is being processed.
            If Len(sTimes) <> 0 Then sTimes = sTimes & Chr(10)

'           Add the next time to the sTimes string variable.
            sTimes = sTimes & _
             Format(rAnchorCellData.Offset(iDataRowsProcessed + iDataRow, 3).Value, "Short Time")

'           Increment counter iOneToFour keeping track of which time row
'           is being processed may be two or four (four if there are two
'           start times and two end times for a person for a day).
            iOneToFour = iOneToFour + 1

'           Only record times if the following conditions are met: 1. Not iOneToFour = 1,
'           2. Not iOneToFour = 3 and Not (iOneToFour = 2 And bIsSameDate).
'           So process if 1. iOneToFour = 2, and 2. not same date as previous data row being
'           processed or 3. iOneToFour = 4.

            If Not iOneToFour = 1 And Not iOneToFour = 3 And Not (iOneToFour = 2 And bIsSameDate) _
             Then
           
'               Reset the counter keeping track of how many times have been
'               encountered for the day being processed.
                iOneToFour = 0

'               Increment counter that keeps track of which column
'               the current day's data is to be placed into.
                iOneToSeven = iOneToSeven + 1

'               If there was a date skip then adjust iOneToSeven to
'               account for the column number by the number of days skipped.
                If bIsSkipDate Then iOneToSeven = iOneToSeven + iDaysMissing

'               Put the person's hours and date for the date being processed
'               into the two cells where that data is placed.
                With rAnchorCellResults

'                   Put the date into the cell in the results area.
                    With .Offset((iUniqueIDIndex * 4) - 2, iOneToSeven)
                        .Value = dCurrentDate
                        .HorizontalAlignment = xlCenter
                        .VerticalAlignment = xlCenter
                    End With

'                   Put the times into the cell in the results area.
                    With .Offset((iUniqueIDIndex * 4) - 1, iOneToSeven)
                        .Value = sTimes
                        .HorizontalAlignment = xlCenter
                        .VerticalAlignment = xlCenter
                    End With

                End With

'               We saved the times so clear the string variable sTimes
'               to prepare for the next date/times pair to process.
                sTimes = ""

'               Boolean flag bIsSkipDate indicates whether to skip a date (column)
'               for the next day's data.
                bIsSkipDate = False
                If dNextDate - dCurrentDate >= 2 _
                 Then
                    bIsSkipDate = True
                End If
               
'               If there is a skipped date determine how many days are skipped.
'               That value is used in the next iteration to determine how many
'               days to skip when putting date and time values into the results area.
                If bIsSkipDate _
                 Then
                    iDaysMissing = dNextDate - dCurrentDate - 1
                Else
                    iDaysMissing = 0
                End If
           
            End If

        Next iDataRow

'       Set up to process the seven days for the next person.
        iOneToSeven = 0
'
    Next iUniqueIDIndex

End Sub

Sub that creates labels

VBA Code:
Option Explicit

Sub CreateLabels( _
    pavUniqueIDsFound As Variant, _
    prAnchorCellResults As Range, _
    piUniqueID As Long, _
    piResultsRowsCount As Long)
   
    Dim iDateIndex As Long

    With prAnchorCellResults.Offset((piUniqueID - 1) * piResultsRowsCount)

'       -------------------------------------
'                   ID label
'       -------------------------------------

        .Offset(0, 1).Value = "ID"

        With .Offset(0, 1).Resize(1, 3)
            .HorizontalAlignment = xlCenterAcrossSelection
            .VerticalAlignment = xlCenter
            .WrapText = False
            .ShrinkToFit = False
            .MergeCells = False
        End With

'       -------------------------------------
'                   Name label
'       -------------------------------------

        .Offset(0, 4).Value = "Name"

        With .Offset(0, 4).Resize(1, 4)
            .HorizontalAlignment = xlCenterAcrossSelection
            .VerticalAlignment = xlCenter
            .WrapText = False
            .ShrinkToFit = False
            .MergeCells = False
        End With

'       -------------------------------------
'             Person's ID number (cells)
'       -------------------------------------

        .Offset(1, 1).Value = pavUniqueIDsFound(1, piUniqueID)

        With .Offset(1, 1).Resize(1, 3)
            .HorizontalAlignment = xlCenterAcrossSelection
            .VerticalAlignment = xlCenter
            .WrapText = False
            .ShrinkToFit = False
            .MergeCells = False
        End With

'       -------------------------------
'           Person's name (cells)
'       -------------------------------

        .Offset(1, 4).Value = pavUniqueIDsFound(2, piUniqueID)

        With .Offset(1, 4).Resize(1, 4)
            .HorizontalAlignment = xlCenterAcrossSelection
            .VerticalAlignment = xlCenter
            .WrapText = False
            .ShrinkToFit = False
            .MergeCells = False
        End With

'       -------------------------------
'               Date label (cell)
'       -------------------------------

        With .Offset(2, 0)
            .Value = "Date"
            .HorizontalAlignment = xlCenter
            .VerticalAlignment = xlCenter
            .MergeCells = False
        End With

    End With

End Sub

Function that puts all data rows for all people into an array.

VBA Code:
Option Explicit
Option Base 1

Function FillDataArray( _
    prAnchorCellData As Range, _
    piDataRowsCount As Long, _
    ByRef pavData As Variant _
)

'   Used for looping through data rows for a person.
    Dim iRow As Long
   
'   Iterate through all data rows for all people.
    For iRow = 1 To piDataRowsCount
       
        ReDim Preserve pavData(1 To 4, iRow)
       
        With prAnchorCellData.Offset(iRow, 0)
            pavData(1, iRow) = .Value
            pavData(2, iRow) = .Offset(0, 1).Value
            pavData(3, iRow) = .Offset(0, 2).Value
            pavData(4, iRow) = .Offset(0, 3).Value

        End With
       
    Next iRow
   
End Function

Function that puts unique IDs into an array.

VBA Code:
Option Explicit
Option Base 1

Function FillUniqueIDsArray( _
    ByVal prAnchorCellData As Range, _
    ByVal pavData As Variant, _
    ByRef pavUniqueIDsFound As Variant)

'   Used for looping through data rows for a person.
    Dim iRow As Long
   
'   Used to keep track of the current ID being processed.
    Dim sCurrentID As String
   
'   Used to keep track of the previus ID that was processed.
    Dim sPreviousID As String
   
    Dim iUniqueIDsCount As Long
   
    Dim iDataRowsCount As Long
   
    Dim sUniqueID As String
   
    Dim iEntryIndex As Long

    Dim iEntriesCount As Long

    sCurrentID = ""
   
    sPreviousID = ""
   
    iUniqueIDsCount = 0
   
    iDataRowsCount = UBound(pavData, 2)
   
'   Iterate through all data rows for all people.
    For iRow = 1 To iDataRowsCount

'       Get the ID for the unique ID found.
        sCurrentID = pavData(1, iRow)

'       Process another uniqe ID if one is encountered.
        If sPreviousID <> sCurrentID _
         Then
            iUniqueIDsCount = iUniqueIDsCount + 1

'           Make the array bigger to accommodate the nbext uniquie ID encounterd.
            ReDim Preserve pavUniqueIDsFound(1 To 3, iUniqueIDsCount)
           
'           Into the array put the unique ID and the person's name. That data
'           was stored in the pavData array above.
            pavUniqueIDsFound(1, iUniqueIDsCount) = pavData(1, iRow)
            pavUniqueIDsFound(2, iUniqueIDsCount) = pavData(2, iRow)
           
        End If

'       Set previous ID for the next iteration.
        sPreviousID = sCurrentID

    Next iRow
   
'   Code above put an extra "row" into the pavUniqueIDsFound array.
'   Remove it if it exists. Causes error if the correct
    On Error Resume Next
    If pavUniqueIDsFound(2, iUniqueIDsCount) = "" _
     Then ReDim Preserve pavUniqueIDsFound(1 To 3, iUniqueIDsCount)
    On Error GoTo 0
   
   
'   Get a count of the data rows for each person being processed.
   
'   Initialize count of data entries (rows) that have been processed.
    iEntriesCount = 0
   
'   Loop through all "rows" in the pavUniqueIDsFound array (one for
'   each person/unique ID).
    For iRow = 1 To UBound(pavUniqueIDsFound, 2)

'       Get the next unique ID from "column" 2 in the pavUniqueIDsFound
'       array.
        sUniqueID = pavUniqueIDsFound(1, iRow)
       
'       Initialize var keeping track of how many rows there are for a person.
        iEntryIndex = 0

'       Iterate through data rows until the ID value in the next data
'       row is different than the ID value in the current data row.
        With prAnchorCellData.Offset(iEntriesCount)

            Do While .Offset(iEntryIndex + 1).Value = sUniqueID

'               Current row being processed for the current person.
                iEntryIndex = iEntryIndex + 1

'               Current data row -- of all data rows -- being processed.
                iEntriesCount = iEntriesCount + 1

            Loop

        End With
       
        pavUniqueIDsFound(3, iRow) = iEntryIndex
'
    Next
   
End Function
 
Upvote 0
I put together code below that does what you asked for. I have Office 365 so there is a chance that this will not work for you. Let me know if you have questions.

The workbook is .

Primary Sub

VBA Code:
Option Explicit
Option Base 1

Sub SummarizeData()

'   ----------------------------
'          Declarations
'   ----------------------------

'   Workbook where data is located.
    Dim wsData As Worksheet

'   Workbook into which results are place.
    Dim wsResults As Worksheet

'   Upperleftmost cell where data are located.
    Dim rAnchorCellData As Range

'   Upperleftmost cell where results are located.
    Dim rAnchorCellResults As Range

'   Count of rows in the data range.
    Dim iDataRowsCount As Long

'   Count of rows in results FOR EACH PERSON.
    Dim iPersonResultsRowsCount As Long

'   Count of rows in results FOR EACH PERSON.
    Dim iRowsToClearCount As Long

'   For looping through the rows in the data.
    Dim iDataRow As Long

'   Array that contains all data.
    Dim avData() As Variant

'   Array used to keep track of the IDs encountered -- one per person.
'   "Row" 1 is the ID number, "row" 2 is the name "row" 3 is count of
'   data rows for a person
    Dim avUniqueIDsFound() As Variant

'   Keep track of unique IDs encountered in data.
    Dim iUniqueIDsCount As Long

'   Used to loop unique IDs array.
    Dim iUniqueIDIndex As Long

'   String holding the unique ID for a person.
    Dim sUniqueID As String

'   Used while looping to determine if there is a change of ID
'   from one data row to the next.
    Dim sCurrentID As String

'   Count of rows (entries) to process.
    Dim iEntriesCount As Long

'   Used for looping through entries.
    Dim iEntryIndex As Long

'   Used to keep track of the how many rows of data have been processed.
'   That is needed to determine the next data row to process relative to
'   the data anchor cell rAnchorCellData (e.g. when gathering data for a person.
    Dim iDataRowsProcessed As Long

'   Used to keep track of which day of the week is being processed 1 - 7.
    Dim iOneToSeven As Long

'   Used to keep track of how many times there are for a given person
'   in a given day. Either two or four. Four if there are two time in and
'   time out time stamps for a person in one day.
    Dim iOneToFour As Long

'   String used to gather time(s) in and time(s) out for a person for a
'   given day.
    Dim sTimes As String

'   Used to determime if the date for the next time in/time out entry
'   is the same date as the curren time in/time out entry.
    Dim bIsSameDate As Boolean

'   Is there a date "missing" for a person in the data meaning that she
'   did not work the next day.
    Dim bIsSkipDate As Boolean
    
    Dim iDaysMissing As Long

'   Count of rows in te data for the person being processed.
    Dim iPersonRowsCount As Long

'   Date of the data row being processed.
    Dim dCurrentDate As Date

'   Date of the next bdata row to process.
    Dim dNextDate As Date

'   ----------------------------
'         Initializations
'   ----------------------------

    Application.ScreenUpdating = False

    Set wsData = ThisWorkbook.Worksheets("Sheet1") '<= Name of sheet containg data

    Set rAnchorCellData = wsData.Range("B2") '<= (Header) cell where data starts
    
    Set wsResults = ThisWorkbook.Worksheets("Sheet1") '<= Name of sheet containg data

    Set rAnchorCellResults = wsResults.Range("G1") '<= cell where results start

    iPersonResultsRowsCount = 4 '(e.g., rows 1 through 4 for first person processed.

    iDataRowsCount = rAnchorCellData.CurrentRegion.Rows.Count - 1

'   Set up array to hold values for 4 "columns".
'   Minus one because we skip the header row.
'   1. ID, 2. Name, 3. Date, 4. Time
    ReDim avData(1 To 4, 1 To iDataRowsCount)

'   Set up array to hold values for 3 "columns".
'   1. ID, 2. Name, 3. Entries Count. One "row"
'   for each person.
    ReDim avUniqueIDsFound(1 To 3, 1)

'   ----------------------------------
'         Clear existing results
'   ----------------------------------

    With rAnchorCellResults
    
        iRowsToClearCount = .Offset(100000).End(xlUp).Row - .Row + 2

        .Resize(iRowsToClearCount, 8).Clear
    
    End With

'   ----------------------------
'         Fill Data Arrays
'   ----------------------------

    iUniqueIDsCount = 0

    Call FillDataArray(rAnchorCellData, iDataRowsCount, avData)
    
    Call FillUniqueIDsArray(rAnchorCellData, avData, avUniqueIDsFound)
    
    iUniqueIDsCount = UBound(avUniqueIDsFound, 2)
    
'   -----------------------------------------------------
'         Put Results Labels into the Results Area
'   -----------------------------------------------------
    
    For iUniqueIDIndex = 1 To iUniqueIDsCount

'       Adds results labels in the results range. NO DATA.
        Call CreateLabels( _
            avUniqueIDsFound, _
            rAnchorCellResults, _
            iUniqueIDIndex, _
            iPersonResultsRowsCount)

        sUniqueID = avUniqueIDsFound(1, iUniqueIDIndex)

    Next iUniqueIDIndex

'   ----------------------------------------------
'        Put Array Data into the Results Area
'   ----------------------------------------------

'   Used to keep track of how many data rows have been processed. Needed
'   to determine the next data row to process relative to the data
'   anchor cell rAnchorCellData. To this value is added the iRow number hence
'   initialize to zero.
    iDataRowsProcessed = 0

'   Iterate through all unique IDs found.
    For iUniqueIDIndex = 1 To iUniqueIDsCount

'       For unique IDs # two to n update the row offset for accessing each
'       data row in worksheet data. That value starts at zero for first
'       iteration.
        If iUniqueIDIndex > 1 _
         Then
            iDataRowsProcessed = iDataRowsProcessed + avUniqueIDsFound(3, iUniqueIDIndex - 1)
        End If
        
'       The count of data rows for the person being processed is in array
'       avUniqueIDsFound "column" 3. Row is iUniqueIDIndex
        iPersonRowsCount = avUniqueIDsFound(3, iUniqueIDIndex)
        
'       Initialize variable that keeps track of how many days were "skipped"
'       for a person being processed for the week being processed.
        iDaysMissing = 0
        
        bIsSkipDate = False

'       Process all data rows for a person.
        For iDataRow = 1 To iPersonRowsCount

'           Get the date for the current data row being processed. It is in the
'           avData in column 3, row iDataRow + iDataRowsProcessed.
            dCurrentDate = avData(3, iDataRow + iDataRowsProcessed)

            If iDataRow = iPersonRowsCount _
             Then

'               If processing the final data row for a given person
'               then next date is irrelavant so set it to zero.

                dNextDate = 0
            Else
                dNextDate = avData(3, iDataRow + iDataRowsProcessed + 1)
            End If

'           Determine if the current date = the next date.
'           Set bIsSameDate accordingly, unless it is the last
'           data row for the person being processed.
            If iDataRow = iPersonRowsCount _
             Then
                bIsSameDate = False
            Else
                bIsSameDate = dCurrentDate = dNextDate
            End If
                        
'           Gather the times for the person-day being processed.

'           Add a linefeed character if this is not the first
'           time that is being processed.
            If Len(sTimes) <> 0 Then sTimes = sTimes & Chr(10)

'           Add the next time to the sTimes string variable.
            sTimes = sTimes & _
             Format(rAnchorCellData.Offset(iDataRowsProcessed + iDataRow, 3).Value, "Short Time")

'           Increment counter iOneToFour keeping track of which time row
'           is being processed may be two or four (four if there are two
'           start times and two end times for a person for a day).
            iOneToFour = iOneToFour + 1

'           Only record times if the following conditions are met: 1. Not iOneToFour = 1,
'           2. Not iOneToFour = 3 and Not (iOneToFour = 2 And bIsSameDate).
'           So process if 1. iOneToFour = 2, and 2. not same date as previous data row being
'           processed or 3. iOneToFour = 4.

            If Not iOneToFour = 1 And Not iOneToFour = 3 And Not (iOneToFour = 2 And bIsSameDate) _
             Then
            
'               Reset the counter keeping track of how many times have been
'               encountered for the day being processed.
                iOneToFour = 0

'               Increment counter that keeps track of which column
'               the current day's data is to be placed into.
                iOneToSeven = iOneToSeven + 1

'               If there was a date skip then adjust iOneToSeven to
'               account for the column number by the number of days skipped.
                If bIsSkipDate Then iOneToSeven = iOneToSeven + iDaysMissing

'               Put the person's hours and date for the date being processed
'               into the two cells where that data is placed.
                With rAnchorCellResults

'                   Put the date into the cell in the results area.
                    With .Offset((iUniqueIDIndex * 4) - 2, iOneToSeven)
                        .Value = dCurrentDate
                        .HorizontalAlignment = xlCenter
                        .VerticalAlignment = xlCenter
                    End With

'                   Put the times into the cell in the results area.
                    With .Offset((iUniqueIDIndex * 4) - 1, iOneToSeven)
                        .Value = sTimes
                        .HorizontalAlignment = xlCenter
                        .VerticalAlignment = xlCenter
                    End With

                End With

'               We saved the times so clear the string variable sTimes
'               to prepare for the next date/times pair to process.
                sTimes = ""

'               Boolean flag bIsSkipDate indicates whether to skip a date (column)
'               for the next day's data.
                bIsSkipDate = False
                If dNextDate - dCurrentDate >= 2 _
                 Then
                    bIsSkipDate = True
                End If
                
'               If there is a skipped date determine how many days are skipped.
'               That value is used in the next iteration to determine how many
'               days to skip when putting date and time values into the results area.
                If bIsSkipDate _
                 Then
                    iDaysMissing = dNextDate - dCurrentDate - 1
                Else
                    iDaysMissing = 0
                End If
            
            End If

        Next iDataRow

'       Set up to process the seven days for the next person.
        iOneToSeven = 0
'
    Next iUniqueIDIndex

End Sub

Sub that creates labels

VBA Code:
Option Explicit

Sub CreateLabels( _
    pavUniqueIDsFound As Variant, _
    prAnchorCellResults As Range, _
    piUniqueID As Long, _
    piResultsRowsCount As Long)
   
    Dim iDateIndex As Long

    With prAnchorCellResults.Offset((piUniqueID - 1) * piResultsRowsCount)

'       -------------------------------------
'                   ID label
'       -------------------------------------

        .Offset(0, 1).Value = "ID"

        With .Offset(0, 1).Resize(1, 3)
            .HorizontalAlignment = xlCenterAcrossSelection
            .VerticalAlignment = xlCenter
            .WrapText = False
            .ShrinkToFit = False
            .MergeCells = False
        End With

'       -------------------------------------
'                   Name label
'       -------------------------------------

        .Offset(0, 4).Value = "Name"

        With .Offset(0, 4).Resize(1, 4)
            .HorizontalAlignment = xlCenterAcrossSelection
            .VerticalAlignment = xlCenter
            .WrapText = False
            .ShrinkToFit = False
            .MergeCells = False
        End With

'       -------------------------------------
'             Person's ID number (cells)
'       -------------------------------------

        .Offset(1, 1).Value = pavUniqueIDsFound(1, piUniqueID)

        With .Offset(1, 1).Resize(1, 3)
            .HorizontalAlignment = xlCenterAcrossSelection
            .VerticalAlignment = xlCenter
            .WrapText = False
            .ShrinkToFit = False
            .MergeCells = False
        End With

'       -------------------------------
'           Person's name (cells)
'       -------------------------------

        .Offset(1, 4).Value = pavUniqueIDsFound(2, piUniqueID)

        With .Offset(1, 4).Resize(1, 4)
            .HorizontalAlignment = xlCenterAcrossSelection
            .VerticalAlignment = xlCenter
            .WrapText = False
            .ShrinkToFit = False
            .MergeCells = False
        End With

'       -------------------------------
'               Date label (cell)
'       -------------------------------

        With .Offset(2, 0)
            .Value = "Date"
            .HorizontalAlignment = xlCenter
            .VerticalAlignment = xlCenter
            .MergeCells = False
        End With

    End With

End Sub

Function that puts all data rows for all people into an array.

VBA Code:
Option Explicit
Option Base 1

Function FillDataArray( _
    prAnchorCellData As Range, _
    piDataRowsCount As Long, _
    ByRef pavData As Variant _
)

'   Used for looping through data rows for a person.
    Dim iRow As Long
   
'   Iterate through all data rows for all people.
    For iRow = 1 To piDataRowsCount
       
        ReDim Preserve pavData(1 To 4, iRow)
       
        With prAnchorCellData.Offset(iRow, 0)
            pavData(1, iRow) = .Value
            pavData(2, iRow) = .Offset(0, 1).Value
            pavData(3, iRow) = .Offset(0, 2).Value
            pavData(4, iRow) = .Offset(0, 3).Value

        End With
       
    Next iRow
   
End Function

Function that puts unique IDs into an array.

VBA Code:
Option Explicit
Option Base 1

Function FillUniqueIDsArray( _
    ByVal prAnchorCellData As Range, _
    ByVal pavData As Variant, _
    ByRef pavUniqueIDsFound As Variant)

'   Used for looping through data rows for a person.
    Dim iRow As Long
    
'   Used to keep track of the current ID being processed.
    Dim sCurrentID As String
    
'   Used to keep track of the previus ID that was processed.
    Dim sPreviousID As String
    
    Dim iUniqueIDsCount As Long
    
    Dim iDataRowsCount As Long
    
    Dim sUniqueID As String
    
    Dim iEntryIndex As Long

    Dim iEntriesCount As Long

    sCurrentID = ""
    
    sPreviousID = ""
    
    iUniqueIDsCount = 0
    
    iDataRowsCount = UBound(pavData, 2)
    
'   Iterate through all data rows for all people.
    For iRow = 1 To iDataRowsCount

'       Get the ID for the unique ID found.
        sCurrentID = pavData(1, iRow)

'       Process another uniqe ID if one is encountered.
        If sPreviousID <> sCurrentID _
         Then
            iUniqueIDsCount = iUniqueIDsCount + 1

'           Make the array bigger to accommodate the nbext uniquie ID encounterd.
            ReDim Preserve pavUniqueIDsFound(1 To 3, iUniqueIDsCount)
            
'           Into the array put the unique ID and the person's name. That data
'           was stored in the pavData array above.
            pavUniqueIDsFound(1, iUniqueIDsCount) = pavData(1, iRow)
            pavUniqueIDsFound(2, iUniqueIDsCount) = pavData(2, iRow)
            
        End If

'       Set previous ID for the next iteration.
        sPreviousID = sCurrentID

    Next iRow
    
'   Code above puts an extra "row" into the pavUniqueIDsFound array.
'   Remove it if it exists. This command causes  an error if the
'   correct number of "rows" is present.
    
    On Error Resume Next
    If pavUniqueIDsFound(2, iUniqueIDsCount) = "" _
     Then ReDim Preserve pavUniqueIDsFound(1 To 3, iUniqueIDsCount - 1)
    On Error GoTo 0
    
'   Get a count of the data rows for each person being processed.
    
'   Initialize count of data entries (rows) that have been processed.
    iEntriesCount = 0
    
'   Loop through all "rows" in the pavUniqueIDsFound array (one for
'   each person/unique ID).
    For iRow = 1 To UBound(pavUniqueIDsFound, 2)

'       Get the next unique ID from "column" 2 in the pavUniqueIDsFound
'       array.
        sUniqueID = pavUniqueIDsFound(1, iRow)
        
'       Initialize var keeping track of how many rows there are for a person.
        iEntryIndex = 0

'       Iterate through data rows until the ID value in the next data
'       row is different than the ID value in the current data row.
        With prAnchorCellData.Offset(iEntriesCount)

            Do While .Offset(iEntryIndex + 1).Value = sUniqueID

'               Current row being processed for the current person.
                iEntryIndex = iEntryIndex + 1

'               Current data row -- of all data rows -- being processed.
                iEntriesCount = iEntriesCount + 1

            Loop

        End With
        
        pavUniqueIDsFound(3, iRow) = iEntryIndex
'
    Next
    
End Function
 
Upvote 0
I apologize. Two of the code items I posted are older versions. These are current.

Main sub

VBA Code:
Option Explicit
Option Base 1

Sub SummarizeData()

'   ----------------------------
'          Declarations
'   ----------------------------

'   Workbook where data is located.
    Dim wsData As Worksheet

'   Workbook into which results are place.
    Dim wsResults As Worksheet

'   Upperleftmost cell where data are located.
    Dim rAnchorCellData As Range

'   Upperleftmost cell where results are located.
    Dim rAnchorCellResults As Range

'   Count of rows in the data range.
    Dim iDataRowsCount As Long

'   Count of rows in results FOR EACH PERSON.
    Dim iPersonResultsRowsCount As Long

'   Count of rows in results FOR EACH PERSON.
    Dim iRowsToClearCount As Long

'   For looping through the rows in the data.
    Dim iDataRow As Long

'   Array that contains all data.
    Dim avData() As Variant

'   Array used to keep track of the IDs encountered -- one per person.
'   "Row" 1 is the ID number, "row" 2 is the name "row" 3 is count of
'   data rows for a person
    Dim avUniqueIDsFound() As Variant

'   Keep track of unique IDs encountered in data.
    Dim iUniqueIDsCount As Long

'   Used to loop unique IDs array.
    Dim iUniqueIDIndex As Long

'   String holding the unique ID for a person.
    Dim sUniqueID As String

'   Used while looping to determine if there is a change of ID
'   from one data row to the next.
    Dim sCurrentID As String

'   Count of rows (entries) to process.
    Dim iEntriesCount As Long

'   Used for looping through entries.
    Dim iEntryIndex As Long

'   Used to keep track of the how many rows of data have been processed.
'   That is needed to determine the next data row to process relative to
'   the data anchor cell rAnchorCellData (e.g. when gathering data for a person.
    Dim iDataRowsProcessed As Long

'   Used to keep track of which day of the week is being processed 1 - 7.
    Dim iOneToSeven As Long

'   Used to keep track of how many times there are for a given person
'   in a given day. Either two or four. Four if there are two time in and
'   time out time stamps for a person in one day.
    Dim iOneToFour As Long

'   String used to gather time(s) in and time(s) out for a person for a
'   given day.
    Dim sTimes As String

'   Used to determime if the date for the next time in/time out entry
'   is the same date as the curren time in/time out entry.
    Dim bIsSameDate As Boolean

'   Is there a date "missing" for a person in the data meaning that she
'   did not work the next day.
    Dim bIsSkipDate As Boolean
    
    Dim iDaysMissing As Long

'   Count of rows in te data for the person being processed.
    Dim iPersonRowsCount As Long

'   Date of the data row being processed.
    Dim dCurrentDate As Date

'   Date of the next bdata row to process.
    Dim dNextDate As Date

'   ----------------------------
'         Initializations
'   ----------------------------

    Application.ScreenUpdating = False

    Set wsData = ThisWorkbook.Worksheets("Sheet1") '<= Name of sheet containg data

    Set rAnchorCellData = wsData.Range("B2") '<= (Header) cell where data starts
    
    Set wsResults = ThisWorkbook.Worksheets("Sheet1") '<= Name of sheet containg data

    Set rAnchorCellResults = wsResults.Range("G1") '<= cell where results start

    iPersonResultsRowsCount = 4 '(e.g., rows 1 through 4 for first person processed.

    iDataRowsCount = rAnchorCellData.CurrentRegion.Rows.Count - 1

'   Set up array to hold values for 4 "columns".
'   Minus one because we skip the header row.
'   1. ID, 2. Name, 3. Date, 4. Time
    ReDim avData(1 To 4, 1 To iDataRowsCount)

'   Set up array to hold values for 3 "columns".
'   1. ID, 2. Name, 3. Entries Count. One "row"
'   for each person.
    ReDim avUniqueIDsFound(1 To 3, 1)

'   ----------------------------------
'         Clear existing results
'   ----------------------------------

    With rAnchorCellResults
    
        iRowsToClearCount = .Offset(100000).End(xlUp).Row - .Row + 2

        .Resize(iRowsToClearCount, 8).Clear
    
    End With

'   ----------------------------
'         Fill Data Arrays
'   ----------------------------

    iUniqueIDsCount = 0

    Call FillDataArray(rAnchorCellData, iDataRowsCount, avData)
    
    Call FillUniqueIDsArray(rAnchorCellData, avData, avUniqueIDsFound)
    
    iUniqueIDsCount = UBound(avUniqueIDsFound, 2)
    
'   -----------------------------------------------------
'         Put Results Labels into the Results Area
'   -----------------------------------------------------
    
    For iUniqueIDIndex = 1 To iUniqueIDsCount

'       Adds results labels in the results range. NO DATA.
        Call CreateLabels( _
            avUniqueIDsFound, _
            rAnchorCellResults, _
            iUniqueIDIndex, _
            iPersonResultsRowsCount)

        sUniqueID = avUniqueIDsFound(1, iUniqueIDIndex)

    Next iUniqueIDIndex

'   ----------------------------------------------
'        Put Array Data into the Results Area
'   ----------------------------------------------

'   Used to keep track of how many data rows have been processed. Needed
'   to determine the next data row to process relative to the data
'   anchor cell rAnchorCellData. To this value is added the iRow number hence
'   initialize to zero.
    iDataRowsProcessed = 0

'   Iterate through all unique IDs found.
    For iUniqueIDIndex = 1 To iUniqueIDsCount

'       For unique IDs # two to n update the row offset for accessing each
'       data row in worksheet data. That value starts at zero for first
'       iteration.
        If iUniqueIDIndex > 1 _
         Then
            iDataRowsProcessed = iDataRowsProcessed + avUniqueIDsFound(3, iUniqueIDIndex - 1)
        End If
        
'       The count of data rows for the person being processed is in array
'       avUniqueIDsFound "column" 3. Row is iUniqueIDIndex
        iPersonRowsCount = avUniqueIDsFound(3, iUniqueIDIndex)
        
'       Initialize variable that keeps track of how many days were "skipped"
'       for a person being processed for the week being processed.
        iDaysMissing = 0
        
        bIsSkipDate = False

'       Process all data rows for a person.
        For iDataRow = 1 To iPersonRowsCount

'           Get the date for the current data row being processed. It is in the
'           avData in column 3, row iDataRow + iDataRowsProcessed.
            dCurrentDate = avData(3, iDataRow + iDataRowsProcessed)

            If iDataRow = iPersonRowsCount _
             Then

'               If processing the final data row for a given person
'               then next date is irrelavant so set it to zero.

                dNextDate = 0
            Else
                dNextDate = avData(3, iDataRow + iDataRowsProcessed + 1)
            End If

'           Determine if the current date = the next date.
'           Set bIsSameDate accordingly, unless it is the last
'           data row for the person being processed.
            If iDataRow = iPersonRowsCount _
             Then
                bIsSameDate = False
            Else
                bIsSameDate = dCurrentDate = dNextDate
            End If
                        
'           Gather the times for the person-day being processed.

'           Add a linefeed character if this is not the first
'           time that is being processed.
            If Len(sTimes) <> 0 Then sTimes = sTimes & Chr(10)

'           Add the next time to the sTimes string variable.
            sTimes = sTimes & _
             Format(rAnchorCellData.Offset(iDataRowsProcessed + iDataRow, 3).Value, "Short Time")

'           Increment counter iOneToFour keeping track of which time row
'           is being processed may be two or four (four if there are two
'           start times and two end times for a person for a day).
            iOneToFour = iOneToFour + 1

'           Only record times if the following conditions are met: 1. Not iOneToFour = 1,
'           2. Not iOneToFour = 3 and Not (iOneToFour = 2 And bIsSameDate).
'           So process if 1. iOneToFour = 2, and 2. not same date as previous data row being
'           processed or 3. iOneToFour = 4.

            If Not iOneToFour = 1 And Not iOneToFour = 3 And Not (iOneToFour = 2 And bIsSameDate) _
             Then
            
'               Reset the counter keeping track of how many times have been
'               encountered for the day being processed.
                iOneToFour = 0

'               Increment counter that keeps track of which column
'               the current day's data is to be placed into.
                iOneToSeven = iOneToSeven + 1

'               If there was a date skip then adjust iOneToSeven to
'               account for the column number by the number of days skipped.
                If bIsSkipDate Then iOneToSeven = iOneToSeven + iDaysMissing

'               Put the person's hours and date for the date being processed
'               into the two cells where that data is placed.
                With rAnchorCellResults

'                   Put the date into the cell in the results area.
                    With .Offset((iUniqueIDIndex * 4) - 2, iOneToSeven)
                        .Value = dCurrentDate
                        .HorizontalAlignment = xlCenter
                        .VerticalAlignment = xlCenter
                    End With

'                   Put the times into the cell in the results area.
                    With .Offset((iUniqueIDIndex * 4) - 1, iOneToSeven)
                        .Value = sTimes
                        .HorizontalAlignment = xlCenter
                        .VerticalAlignment = xlCenter
                    End With

                End With

'               We saved the times so clear the string variable sTimes
'               to prepare for the next date/times pair to process.
                sTimes = ""

'               Boolean flag bIsSkipDate indicates whether to skip a date (column)
'               for the next day's data.
                bIsSkipDate = False
                If dNextDate - dCurrentDate >= 2 _
                 Then
                    bIsSkipDate = True
                End If
                
'               If there is a skipped date determine how many days are skipped.
'               That value is used in the next iteration to determine how many
'               days to skip when putting date and time values into the results area.
                If bIsSkipDate _
                 Then
                    iDaysMissing = dNextDate - dCurrentDate - 1
                Else
                    iDaysMissing = 0
                End If
            
            End If

        Next iDataRow

'       Set up to process the seven days for the next person.
        iOneToSeven = 0
'
    Next iUniqueIDIndex

End Sub

Fill unique IDs array.

VBA Code:
Option Explicit
Option Base 1

Function FillUniqueIDsArray( _
    ByVal prAnchorCellData As Range, _
    ByVal pavData As Variant, _
    ByRef pavUniqueIDsFound As Variant)

'   Used for looping through data rows for a person.
    Dim iRow As Long
    
'   Used to keep track of the current ID being processed.
    Dim sCurrentID As String
    
'   Used to keep track of the previus ID that was processed.
    Dim sPreviousID As String
    
    Dim iUniqueIDsCount As Long
    
    Dim iDataRowsCount As Long
    
    Dim sUniqueID As String
    
    Dim iEntryIndex As Long

    Dim iEntriesCount As Long

    sCurrentID = ""
    
    sPreviousID = ""
    
    iUniqueIDsCount = 0
    
    iDataRowsCount = UBound(pavData, 2)
    
'   Iterate through all data rows for all people.
    For iRow = 1 To iDataRowsCount

'       Get the ID for the unique ID found.
        sCurrentID = pavData(1, iRow)

'       Process another uniqe ID if one is encountered.
        If sPreviousID <> sCurrentID _
         Then
            iUniqueIDsCount = iUniqueIDsCount + 1

'           Make the array bigger to accommodate the nbext uniquie ID encounterd.
            ReDim Preserve pavUniqueIDsFound(1 To 3, iUniqueIDsCount)
            
'           Into the array put the unique ID and the person's name. That data
'           was stored in the pavData array above.
            pavUniqueIDsFound(1, iUniqueIDsCount) = pavData(1, iRow)
            pavUniqueIDsFound(2, iUniqueIDsCount) = pavData(2, iRow)
            
        End If

'       Set previous ID for the next iteration.
        sPreviousID = sCurrentID

    Next iRow
    
'   Code above puts an extra "row" into the pavUniqueIDsFound array.
'   Remove it if it exists. This command causes  an error if the
'   correct number of "rows" is present.
    
    On Error Resume Next
    If pavUniqueIDsFound(2, iUniqueIDsCount) = "" _
     Then ReDim Preserve pavUniqueIDsFound(1 To 3, iUniqueIDsCount - 1)
    On Error GoTo 0
    
'   Get a count of the data rows for each person being processed.
    
'   Initialize count of data entries (rows) that have been processed.
    iEntriesCount = 0
    
'   Loop through all "rows" in the pavUniqueIDsFound array (one for
'   each person/unique ID).
    For iRow = 1 To UBound(pavUniqueIDsFound, 2)

'       Get the next unique ID from "column" 2 in the pavUniqueIDsFound
'       array.
        sUniqueID = pavUniqueIDsFound(1, iRow)
        
'       Initialize var keeping track of how many rows there are for a person.
        iEntryIndex = 0

'       Iterate through data rows until the ID value in the next data
'       row is different than the ID value in the current data row.
        With prAnchorCellData.Offset(iEntriesCount)

            Do While .Offset(iEntryIndex + 1).Value = sUniqueID

'               Current row being processed for the current person.
                iEntryIndex = iEntryIndex + 1

'               Current data row -- of all data rows -- being processed.
                iEntriesCount = iEntriesCount + 1

            Loop

        End With
        
        pavUniqueIDsFound(3, iRow) = iEntryIndex
'
    Next
    
End Function
 
Upvote 0
This is an alternative code:
VBA Code:
Option Explicit

Sub ConsolidatePerEmployee()
    Dim vIn As Variant, vOut As Variant
    Dim rIn As Range
    Dim lRi As Long, lRo As Long, lCi As Long, lCo As Long, i As Long, UBi As Long, lID
    Dim colID As Collection
    
    Set rIn = Range("B2")   '<<<< modify if required: top left cell of input data
    
    'load data into array for fast processing
    vIn = rIn.CurrentRegion.Value
    'get number of rows
    UBi = UBound(vIn, 1)
    
    'get all unique ID's
    Set colID = New Collection
    On Error Resume Next        'surpress error message when trying to add duplicate key to collection
    For lRi = 2 To UBi      'skip header row
        colID.Add vIn(lRi, 1), CStr(vIn(lRi, 1))
    Next lRi
    On Error GoTo 0     'reset error behaviour to normal
    
    'Size output array  <<<< This assumes one month of data (the 32 in the line below)
    '                   <<<< If it is for a week, change 32 to 8
    ReDim vOut(1 To colID.Count * 4, 1 To 32)
    
    'Now get the data for each person
    'First the 'header'
    For lID = 1 To colID.Count
        lRo = lRo + 1
        vOut(lRo, 3) = "ID"
        vOut(lRo, 5) = "Name"
        vOut(lRo + 2, 1) = "Date"
        For lCo = 1 To 31       '<<<< if it is for a week change 31 to 7
            vOut(lRo + 2, lCo + 1) = lCo
        Next lCo
        
        'set output row to name and ID nr row
        lRo = lRo + 1
        'ID nr and Name
        vOut(lRo, 3) = colID(lID)
        For lRi = 2 To UBi
            If vIn(lRi, 1) = colID(lID) Then Exit For
        Next lRi
        vOut(lRo, 5) = vIn(lRi, 2)
        
        'set output row to time log row
        lRo = lRo + 2
        'now process the times for each date
        For lRi = 2 To UBi
            If vIn(lRi, 1) = colID(lID) Then
                'get the day from date for the line and set the output column
                lCo = Day(vIn(lRi, 3)) + 1
                'Add the login time to the relevant day
                vOut(lRo, lCo) = vOut(lRo, lCo) & Format(vIn(lRi, 4), "hh:mm") & vbCrLf
            End If
        Next lRi
    Next lID
    'add new sheet for the output
    Sheets.Add after:=ActiveSheet
    'write output to sheet
    Range("A1").Resize(UBound(vOut, 1), UBound(vOut, 2)).Value = vOut
    
End Sub
 
Upvote 0

Forum statistics

Threads
1,215,429
Messages
6,124,838
Members
449,193
Latest member
MikeVol

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