Sửa code : Lấy lịch trống trên outlook calendar bằng VBA

Liên hệ QC
Tôi tuân thủ nội quy khi đăng bài

bigbabol89

Thành viên thường trực
Tham gia
15/10/12
Bài viết
225
Được thích
34
Hi các anh chị,
Em sưu tầm được file này từ google :
- Lấy thời gian trống của 1 người nào đó ( họ đã chia sẻ lịch ) trên calendar outlook trong 1 ngày theo khai báo ( từ 9h sáng -> 17h chiều )
Tuy nhiên, chỉ lấy dữ liệu trong 1 ngày thì em vẫn phải đi dò nhiều ngày liên tục. Vì vậy, nhờ các anh chị sửa giúp em là :
- Lấy thời gian trống của 1 người nào đó ( họ đã chia sẻ lịch ) trên calendar outlook trong 2 tuần tính từ ngày khai báo ( từ 9h sáng -> 17h chiều ), nếu thêm không tính giờ nghỉ trưa nữa thì tốt quá ạ.
Rất mong các anh chị giúp đỡ ạ.
Em cám ơn ạ.
Mã:
Option Explicit

Private Sub cmdTimeslot_Click()
    Dim rng As Range                            ' Range listing employees
    Dim strEmp() As String                      ' Shared calendars
    Dim strTimeslot As String                   ' Available timeslots
    Dim i As Integer                            ' Counter
    Dim n As Integer                            ' Counter
   
   
    On Error Resume Next
    ActiveSheet.Range("dat_Timeslot").ClearContents
   
    On Error GoTo ErrHandler
    For Each rng In ActiveSheet.Range("lkp_Shared")
        ReDim Preserve strEmp(0 To i) As String
        strEmp(i) = rng.Formula
        i = i + 1
    Next rng
   
    strTimeslot = FindFreeTime(ActiveSheet.Range("lkp_Date").Value, strEmp())
   
    Do
        For i = 0 To 2
            Range("StartTimes").Offset(n - 1, i).Formula = Left(strTimeslot, InStr(1, strTimeslot, ";") - 1)
            strTimeslot = Mid(strTimeslot, InStr(1, strTimeslot, ";") + 1)
        Next i
       
        n = n + 1
    Loop Until InStr(1, strTimeslot, ";") = 0
   
    ActiveSheet.lstAvailable.ListFillRange = "dat_Timeslot"
   
    MsgBox "The list of available times for " & _
            Format(ActiveSheet.Range("lkp_Date").Value, "d-mmm-yyyy") & _
            " has been updated", vbInformation, "Available Timeslots"
   
   
ExitHere:
    Exit Sub
   
ErrHandler:
    MsgBox Err.Number & ": " & Err.Description
    Resume ExitHere
End Sub
Mã:
Option Explicit

Function FindFreeTime(dtmAppt As Date, strEmp() As String) As String
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' Purpose:      Capture all available timeslots (between appointments) on
'               nominated day
'
' Inputs:       dtmAppt         Date to search
'               strEmp          Array containing all employee calendars to
'                                   search
'
' Assumptions:  * User must have access to the appropriate shared calendars in
'                 Outlook
'               * Free timeslot must be >= default appointment time
'               * Free timeslot must be between default start and end times for
'                 appointments
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Dim objOL As New Outlook.Application    ' Outlook
    Dim objNS As NameSpace                  ' Namespace
    Dim OLFldr As Outlook.MAPIFolder        ' Calendar folder
    Dim OLAppt As Object                    ' Single appointment
    Dim OLRecip As Outlook.Recipient        ' Outlook user name
    Dim OLAppts As Outlook.Items            ' Appointment collection
    Dim strDay As String                    ' Day for appointment
    Dim strList As String                   ' List of all available timeslots
    Dim dtmNext As Date                     ' Next available time
    Dim intDuration As Integer              ' Duration of free timeslot
    Dim i As Integer                        ' Counter
    
    Const C_Procedure = "FindFreeTime"      ' Procedure name
    Const C_dtmFirstAppt = #9:00:00 AM#     ' First appointment time
    Const C_dtmLastAppt = #7:00:00 PM#      ' Last appointment time
    Const C_intDefaultAppt = 120            ' Default appointment duration
    
    
    On Error GoTo ErrHandler
    
        ' list box column headings
    strList = "Employee;Start Time;End Time;"
        
        ' get full span of selected day
    strDay = "[Start] >= '" & dtmAppt & "' and " & _
             "[Start] < '" & dtmAppt & " 11:59 pm'"
    
        ' loop through shared Calendar for all Employees in array
    Set objNS = objOL.GetNamespace("MAPI")
    
    For i = 0 To UBound(strEmp)
        On Error GoTo ErrHandler
        Set OLRecip = objNS.CreateRecipient(strEmp(i))
        
        On Error Resume Next
        Set OLFldr = objNS.GetSharedDefaultFolder(OLRecip, olFolderCalendar)
        
            ' calendar not shared
        If Err.Number <> 0 Then
            strList = strList & strEmp(i) & _
                ";Calendar not shared;Calendar not shared;"

            GoTo NextEmp
        End If
        
        On Error GoTo ErrHandler
        Set OLAppts = OLFldr.Items
        
        dtmNext = C_dtmFirstAppt
    
            ' Sort the collection (required by IncludeRecurrences)
        OLAppts.Sort "[Start]"
        
            ' Make sure recurring appointments are included
        OLAppts.IncludeRecurrences = True
        
            ' Filter the collection to include only the day's appointments
        Set OLAppts = OLAppts.Restrict(strDay)
        
            ' Sort it again to put recurring appointments in correct order
        OLAppts.Sort "[Start]"
        
        With OLAppts
                ' capture subject, start time and duration of each item
            Set OLAppt = .GetFirst
            
            Do While TypeName(OLAppt) <> "Nothing"
                    ' find first free timeslot
                Select Case DateValue(dtmAppt)
                    Case DateValue(Format(OLAppt.Start, "dd/mm/yyyy"))
                        If Format(dtmNext, "Hh:Nn") < _
                            Format(OLAppt.Start, "Hh:Nn") Then
                                
                                ' find gap before next appointment starts
                            If Format(OLAppt.Start, "Hh:Nn") < _
                                    Format(C_dtmLastAppt, "Hh:Nn") Then
                                intDuration = DateDiff("n", dtmNext, _
                                                Format(OLAppt.Start, "Hh:Nn"))
                            Else
                                intDuration = DateDiff("n", dtmNext, _
                                                Format(C_dtmLastAppt, "Hh:Nn"))
                            End If
                            
                                ' can we fit an appointment into the gap?
                            If intDuration >= C_intDefaultAppt Then
                                strList = strList & strEmp(i) & _
                                    ";" & Format(dtmNext, "Hh:Nn ampm") & _
                                    ";" & Format(DateAdd("n", intDuration, _
                                            dtmNext), "Hh:Nn ampm") & ";"
                            End If
                        End If
                    
                            ' find first available time after appointment
                        dtmNext = DateAdd("n", OLAppt.Duration + intDuration, _
                                        dtmNext)

                            ' don't go beyond last possible appointment time
                        If dtmNext > C_dtmLastAppt Then
                            Exit Do
                        End If
                End Select
                
                intDuration = 0
                
                Set OLAppt = .GetNext
            Loop
        End With

            ' capture remainder of day
        intDuration = DateDiff("n", dtmNext, Format(C_dtmLastAppt, "Hh:Nn"))

        If intDuration >= C_intDefaultAppt Then
            strList = strList & strEmp(i) & _
                ";" & Format(dtmNext, "Hh:Nn ampm") & _
                ";" & Format(DateAdd("n", intDuration, dtmNext), "Hh:Nn ampm") & _
                ";"
        End If

NextEmp:
        ' add note for unavailable Employee
        If InStr(1, strList, strEmp(i)) = 0 Then
            strList = strList & strEmp(i) & _
                ";Unavailable this day;Unavailable this day;"
        End If
    Next i
    
    FindFreeTime = strList
    
    
ExitHere:
    On Error Resume Next
    Set OLAppt = Nothing
    Set OLAppts = Nothing
    Set objNS = Nothing
    Set objOL = Nothing
    Exit Function
    
ErrHandler:
    MsgBox Err.Number & ": " & C_Procedure & vbCrLf & Err.Description
    Resume ExitHere
End Function
 

File đính kèm

  • ShowTimeslot.xls
    53.5 KB · Đọc: 2
Web KT

Bài viết mới nhất

Back
Top Bottom