简体   繁体   English

vba 小时和日期范围

[英]vba range of hours and dates

hi I have a table that I schedule workers at the workers are scheduled at a range of hours for example 11:00-18:00 and a range of dates for example 21/01/2021-26/01/2021 and I need to spot duplicates for example if the same worker is scheduled at 21/04/2021-22/04/2021 at 11:00:18:00 and 13:00-15:00 it would detect a duplicate schedule the table looks like this嗨,我有一张桌子,我安排工人的工人被安排在一系列时间,例如 11:00-18:00 和一系列日期,例如 21/01/2021-26/01/2021,我需要发现重复,例如,如果同一个工作人员被安排在 21/04/2021-22/04/2021 的 11:00:18:00 和 13:00-15:00,它将检测到重复的时间表,表格如下所示

在此处输入图像描述

my code right now spots only exact same schedule duplicate or once that start at the same hour我的代码现在只发现完全相同的时间表重复或一次在同一时间开始

Private Sub CommandButton1_Click()
Dim lrow As Long
Dim x As Integer
Dim y As Integer
Dim i As Integer

lrow = ActiveSheet.ListObjects("LeaveTracker").DataBodyRange.Rows.Count + 5
    shibuzim.ListObjects("LeaveTracker").ListColumns(2).DataBodyRange.Clear
For x = 5 To lrow
    For y = x + 1 To lrow
        If (Cells(x, 12).Value = Cells(y, 12).Value And _
           Cells(x, 13).Value = Cells(y, 13).Value And _
           Cells(x, 14).Value = Cells(y, 14).Value And _
           Cells(x, 17).Value = Cells(y, 17).Value And _
           Cells(x, 18).Value = Cells(y, 18).Value And _
           Cells(x, 20).Value = Cells(y, 20).Value) _
           Or _
               (Cells(x, 12).Value = Cells(y, 12).Value And _
                Cells(x, 13).Value = Cells(y, 13).Value And _
                Cells(x, 14).Value = Cells(y, 14).Value And _
                Left(Cells(x, 17).Value, 3) = Left(Cells(y, 17).Value, 3) And _
                Cells(x, 18).Value = Cells(y, 18).Value And _
                Cells(x, 20).Value = Cells(y, 20).Value) _
        Then
                Cells(x, 11).Value = "duplicate"
                Cells(y, 11).Value = "duplicate"
                MsgBox "line" & " " & x - 4 & " " & "with line" & " " & y - 4
        End If
    Next y
Next x

End Sub

This create a list of all shifts on a sheet named Check , sorts them by employee, start date, days and then checks them for shifts that start before the previous one ended.这将在名为Check的工作表上创建所有班次的列表,按员工、开始日期、天数对其进行排序,然后检查它们是否有在前一个结束之前开始的班次。

Option Explicit

Sub CheckDupl()

    Const COL_DUPL = 2 ' table column 2
    Const COl_EMPLOYEE = 3
    Const COL_START = 4
    Const COL_END = 5
    Const COL_HOURS = 8

    Dim wb As Workbook, ws As Worksheet, wsCheck As Worksheet
    Dim tbl As ListObject, lrow As Long
    Dim r As Long, p As Long, iDupl As Long, count As Long
    
    ' clear table
    Set wb = ThisWorkbook
    Set ws = wb.Sheets(1) ' or wb.ActiveSheet
    Set tbl = ws.ListObjects("LeaveTracker")
    With tbl
        lrow = .DataBodyRange.Rows.count
        .ListColumns(COL_DUPL).DataBodyRange.Clear
    End With

    Dim sEmploy As String, s As String
    Dim dtStart As Date, dtEnd As Date, dt As Date
    Dim bDupl As Boolean, arHours, dur As Single

    ' prepare output sheet
    Set wsCheck = wb.Sheets("Check")
    wsCheck.Cells.Clear
    wsCheck.Range("A1:F1") = Array("Employee", "Shift Start", "Shift End ", _
                                  "Days", "Table Row", "Duplicate")
    
    ' scan table
    iDupl = 2
    For r = 1 To lrow
        sEmploy = Trim(tbl.DataBodyRange(r, COl_EMPLOYEE))
        dtStart = tbl.DataBodyRange(r, COL_START)
        dtEnd = tbl.DataBodyRange(r, COL_END)

        ' get shift start/end times
        s = Replace(tbl.DataBodyRange(r, COL_HOURS), " ", "") 'remove spaces
        If Not s Like "##:##-##:##" Then
             MsgBox "Check times '" & s & "'", vbCritical, "Table Row " & r
             Exit Sub
        Else
            arHours = Split(s, "-")
        End If
    
        ' add each shift to duplicate sheet
        dt = dtStart
        Do While dt <= dtEnd
            With wsCheck.Cells(iDupl, 1)
                .Value = sEmploy
                .Offset(, 1) = CDate(Format(dt, "yyyy-mm-dd ") & arHours(0))
                .Offset(, 2) = CDate(Format(dt, "yyyy-mm-dd ") & arHours(1))
                .Offset(, 3) = dtEnd - dtStart
                .Offset(, 4) = r ' table row
                  ' sanity check
                If .Offset(, 2) - .Offset(, 1) < 0 Then
                    MsgBox "ERROR - End date before Start date for " & _
                           sEmploy, vbCritical, "Table Row " & r
                    Exit Sub
                End If
            End With
            dt = dt + 1
            iDupl = iDupl + 1
        Loop
    Next
    iDupl = iDupl - 1

    ' sort calendar by employee, start date, days
    ' check longer date ranges against shorter ones
    With wsCheck.Sort
        With .SortFields
             .Clear
            .Add key:=Range("A2:A" & iDupl), SortOn:=xlSortOnValues, _
                      Order:=xlAscending, DataOption:=xlSortNormal
            .Add key:=Range("B2:B" & iDupl), SortOn:=xlSortOnValues, _
                      Order:=xlAscending, DataOption:=xlSortNormal
            .Add key:=Range("D1:D" & iDupl), SortOn:=xlSortOnValues, _
                      Order:=xlDescending, DataOption:=xlSortNormal
        End With
        .SetRange Range("A1:F" & iDupl)
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With

    ' now check for overlaps
    With wsCheck
        p = 2
        For r = 3 To iDupl
           ' check start is before previous end for same employee
           If .Cells(r, 1) = .Cells(p, 1) _
               And .Cells(r, 2) < .Cells(p, 3) Then
               .Cells(r, 6) = "Overlap with row " & p

               ' update table
               tbl.DataBodyRange(.Cells(r, 5), COL_DUPL) = "Duplicate"
               count = count + 1
           Else
               p = r
           End If
        Next
        .Columns("A:F").AutoFit
        .Activate
        .Range("A1").Select
    End With
    MsgBox count & " duplicates found - see sheet " & wsCheck.Name, vbInformation

End Sub

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM