Общий экспорт Outlook в Excel - повторяющиеся события не экспортируются правильно

Я экспортирую данные календаря Outlook из общего календаря в Excel. Все работает отлично, за исключением того, что мой код экспортирует возвращенные элементы с их первоначальной датой публикации серии, а не для каждого экземпляра.

Я видел связанный пост "Как показать дату начала для INSTANCE повторяющейся серии?" но я не мог заставить это работать - я думаю, что мои глаза сейчас глючат, и мне нужна помощь...

Благодарю.

Sub Export_Calendar_Final()
Const SCRIPT_NAME = "Export Calendar to Excel"
Const xlAscending = 1
Const xlYes = 1
Dim olkFld As Object, _
    olkLst As Object, _
    olkRes As Object, _
    olkApt As Object, _
    olkRec As Object, _
    excApp As Object, _
    excWkb As Object, _
    excWks As Object, _
    lngRow As Long, _
    lngCnt As Long, _
    strFil As String, _
    strLst As String, _
    strDat As String, _
    datBeg As Date, _
    datEnd As Date, _
    arrTmp As Variant
Dim myNamespace As Outlook.NameSpace
Dim myRecipient As Outlook.Recipient
Set myNamespace = Application.GetNamespace("MAPI")
Set myRecipient = myNamespace.CreateRecipient("John Doe")
Dim CalendarFolder As Outlook.Folder
Set CalendarFolder = myNamespace.GetSharedDefaultFolder(myRecipient,     olFolderCalendar)
Dim CalendarItem As Outlook.AppointmentItem
Set CalendarItem = CalendarFolder.Items(1)
CalendarFolder.Items.Sort "[Start]"
CalendarFolder.Items.IncludeRecurrences = True

   datBeg = DateAdd("d", -14, Date)
    datEnd = Date

Dim RestictStr As String
RestrictStr = "[Start] >= '" & Format(datBeg, "ddddd h:nn AMPM") & "' AND [Start] <= '" & Format(datEnd, "ddddd h:nn AMPM") & "'"

Set olkRes = CalendarFolder.Items.Restrict(RestrictStr)


  strFil = "I:\Weekly Sales Order Reports\Sales Calendar Export\John Doe.xlsx" 'change folder and file name as needed

        Set excApp = CreateObject("Excel.Application")
        Set excWkb = excApp.Workbooks.Add()
        Set excWks = excWkb.Worksheets(1)
        'Write Excel Column Headers
        With excWks
            .Cells(1, 1) = "Subject"
            .Cells(1, 2) = "Start Date"
            .Cells(1, 3) = "Start Time"
            .Cells(1, 4) = "End Date"
            .Cells(1, 5) = "End Time"
            .Cells(1, 6) = "All day event"
            .Cells(1, 7) = "Required Attendees"
            .Cells(1, 8) = "Categories"
            .Cells(1, 9) = "Hours"
            .Cells(1, 10) = "Location"
            .Cells(1, 11) = "Mailbox"

        End With
        lngRow = 2

        For Each olkApt In olkRes
            'Only export appointments
            If olkApt.Class = olAppointment Then
                strLst = ""
                For Each olkRec In olkApt.Recipients
                    strLst = strLst & olkRec.Name & ", "
                Next
                If strLst <> "" Then strLst = Left(strLst, Len(strLst) - 2)
                'Add a row for each field in the message you want to export
                excWks.Cells(lngRow, 1) = olkApt.Subject
                excWks.Cells(lngRow, 2) = Format(olkApt.Start, "mm/dd/yyyy")
                excWks.Cells(lngRow, 3) = Format(olkApt.Start, "hh:nn:ss")
                excWks.Cells(lngRow, 4) = Format(olkApt.End, "mm/dd/yyyy")
                excWks.Cells(lngRow, 5) = Format(olkApt.End, "hh:nn:ss")
                excWks.Cells(lngRow, 6) = olkApt.AllDayEvent = bolAllDay
                excWks.Cells(lngRow, 7) = strLst
                excWks.Cells(lngRow, 8) = olkApt.Categories
                excWks.Cells(lngRow, 9) = DateDiff("n", olkApt.Start, olkApt.End) / 60
                excWks.Cells(lngRow, 9).NumberFormat = "0.00"
                excWks.Cells(lngRow, 10) = olkApt.Location
                excWks.Cells(lngRow, 11) = "John Doe"
                lngRow = lngRow + 1
                lngCnt = lngCnt + 1
            End If
        Next
                   excWks.Columns("A:H").AutoFit
        excWkb.SaveAs "I:\Weekly Sales Order Reports\Sales Calendar Export\John Doe.xlsx"
        excWkb.Close

        Set excWks = Nothing
        Set excWkb = Nothing
        Set excApp = Nothing
        Set olkApt = Nothing
        Set olkLst = Nothing
        Set olkFld = Nothing

        MsgBox "Process complete.  A total of " & lngCnt & " appointments were exported.", vbInformation + vbOKOnly, SCRIPT_NAME

End Sub

1 ответ

Ваша проблема: в папке календаря есть только одна запись для повторяющегося элемента, и вы не запрашиваете ни одного из свойств повторяющегося элемента.

Если вы ищете одну запись для каждого повторения в вашем рабочем листе, вам придется сгенерировать их. Вам понадобится конечная дата, если вы не хотите, чтобы записи "навсегда" повторялись до 4500 года, и какая-то рабочая таблица после завершения обработки всех элементов календаря.

Я не помню обстоятельств, в которых я кодировал макрос ниже. Это явно исследование элементов календаря, а не попытка создать красивый результат. Я ставлю Debug.Assert False утверждение в верхней части каждого пути через мой код и закомментируйте эти утверждения, когда я с ними сталкиваюсь. Я, кажется, сгенерировал тестовые записи для большинства различных типов повторения, хотя комментарий Have not thought repeating multi-day appointments through предлагает не все.

Я обновил строку 12 с учетом моего текущего рабочего стола, чтобы этот код работал с Office 2016 и Windows 10, а также с более старыми версиями, для которых он был написан. Вам нужно будет обновить строку 12, чтобы обратиться к папке в вашей системе.

Попробуйте этот код в своем общем календаре, а затем найдите его для функций, необходимых для обновления кода.

Option Explicit
Sub DspCalandarItems()

  Dim ItemCrnt As Object
  Dim ItemCrntClass As Long
  Dim FileOut As Object
  Dim FolderSrc As MAPIFolder
  Dim FSO As FileSystemObject
  Dim RecurrPattCrnt As RecurrencePattern

  Set FSO = CreateObject("Scripting.FileSystemObject")
  Set FileOut = FSO.CreateTextFile("c:\users\Admin\Desktop\Appointments.txt", True)

  With GetNamespace("MAPI")

    Set FolderSrc = .GetDefaultFolder(olFolderCalendar)
    FileOut.WriteLine ("Number of items: " & FolderSrc.Items.Count)

    For Each ItemCrnt In FolderSrc.Items

      With ItemCrnt

        ' Occasionally I get syncronisation
        ' errors.  This code avoids them.
        ItemCrntClass = 0
        On Error Resume Next
        ItemCrntClass = .Class
        On Error GoTo 0

        ' I have never found anything but appointments in
        ' Calendar but test just in case
        If ItemCrntClass = olAppointment Then

          Select Case .RecurrenceState
            Case olApptException
              FileOut.WriteLine ("Recurrence state is Exception")
              If .AllDayEvent Then
                FileOut.WriteLine ("All day " & Format(.Start, "ddd d mmm yy"))
                Debug.Assert False
              ElseIf Day(.Start) = Day(.End) Then
                ' Appointment starts and finishes on same day
                If Format(.Start, "hh:mm") <> Format(.End, "hh:mm") Then
                  ' Different start and end times on same day
                  FileOut.Write ("From " & Format(.Start, "hh:mm") & " to " & _
                                           Format(.End, "hh:mm") & " on " & Format(.Start, "ddd d mmm yy"))
                  Debug.Assert False
                Else
                  ' Start and end time the same
                  Debug.Assert False
                  FileOut.Write ("At " & Format(.Start, "hh:mm") & " on " & Format(.Start, "ddd d mmm yy"))
                End If
              Else
                ' Different start and end dates.
                FileOut.Write ("From " & Format(.Start, "hh:mm") & " on " & Format(.Start, "ddd d mmm yy") & " to " & _
                                         Format(.End, "hh:mm") & " on " & Format(.End, "ddd d mmm yy"))
              End If
              Debug.Assert False
            Case olApptMaster
              Set RecurrPattCrnt = .GetRecurrencePattern
              Debug.Assert Year(RecurrPattCrnt.PatternStartDate) = Year(.Start)
              Debug.Assert Month(RecurrPattCrnt.PatternStartDate) = Month(.Start)
              Debug.Assert Day(RecurrPattCrnt.PatternStartDate) = Day(.Start)
              If .AllDayEvent Then
                FileOut.Write ("All day ")
              ElseIf Day(.Start) = Day(.End) Then
                Debug.Assert False
                ' Appointment starts and finishes on same day
                If Format(.Start, "hh:mm") <> Format(.End, "hh:mm") Then
                  ' Different start and end times on same day
                  FileOut.Write ("From " & Format(.Start, "hh:mm") & " to " & _
                                           Format(.End, "hh:mm") & " ")
                  Debug.Assert False
                Else
                  ' Start and end time the same
                  FileOut.Write ("At " & Format(.Start, "hh:mm") & " ")
                  Debug.Assert False
                End If
              ElseIf DateDiff("d", .Start, .End) = 1 And Format(.Start, "hh:mm") = "00:00" And _
                                                         Format(.End, "hh:mm") = "00:00" Then
                FileOut.Write ("All day ")
                'Debug.Assert False
              Else
                ' Have not thought repeating multi-day appointments through
                Debug.Assert False
                FileOut.Write ("XXX From " & Format(.Start, "hh:mm") & " on " & Format(.Start, "ddd d mmm yy") & " to " & _
                                         Format(.End, "hh:mm") & " on " & Format(.End, "ddd d mmm yy"))
              End If
              Select Case RecurrPattCrnt.RecurrenceType
                Case olRecursDaily
                  FileOut.Write ("daily")
                Case olRecursMonthly
                Case olRecursMonthNth
                  FileOut.Write ("nth monthly")
                Case olRecursWeekly
                  FileOut.Write ("weekly")
                  Debug.Assert False
                Case olRecursYearly
                  'Debug.Assert False
                  FileOut.Write ("yearly")
              End Select  ' RecurrPattCrnt.RecurrenceType
              FileOut.Write (" from " & Format(RecurrPattCrnt.PatternStartDate, "ddd d mmm yy"))
              If Year(RecurrPattCrnt.PatternEndDate) = 4500 Then
                ' For ever
                'Debug.Assert False
              Else
                FileOut.Write (" to " & Format(RecurrPattCrnt.PatternEndDate, "ddd d mmm yy"))
                'Debug.Assert False
              End If
            Case olApptNotRecurring
              If .AllDayEvent Then
                FileOut.Write ("All day " & Format(.Start, "ddd d mmm yy"))
                'Debug.Assert False
              ElseIf Day(.Start) = Day(.End) Then
                ' Appointment starts and finishes on same day
                If Format(.Start, "hh:mm") <> Format(.End, "hh:mm") Then
                  ' Different start and end times on same day
                  FileOut.Write ("From " & Format(.Start, "hh:mm") & " to " & _
                                           Format(.End, "hh:mm") & " on " & Format(.Start, "ddd d mmm yy"))
                  'Debug.Assert False
                Else
                  ' Start and end time the same
                  FileOut.Write ("At " & Format(.Start, "hh:mm") & " on " & Format(.Start, "ddd d mmm yy"))
                  'Debug.Assert False
                End If
              Else
                ' Different start and end dates.
                FileOut.Write ("From " & Format(.Start, "hh:mm") & " on " & Format(.Start, "ddd d mmm yy") & " to " & _
                                         Format(.End, "hh:mm") & " on " & Format(.End, "ddd d mmm yy"))
                'Debug.Assert False
              End If
            Case olApptOccurrence
              FileOut.WriteLine ("Occurrence")
              Debug.Assert False
            Case Else
              Debug.Print ("Unknown recurrence state " & .RecurrenceState)
              Debug.Assert False
              FileOut.WriteLine ("Unknown recurrence state " & .RecurrenceState)
          End Select  ' .RecurrenceState
          If .Subject <> "" Then
            FileOut.Write ("  " & .Subject)
          Else
            FileOut.Write ("  ""No subject""")
          End If
          If .Location <> "" Then
            FileOut.Write (" at " & .Location)
          Else
            FileOut.Write (" at undefined location")
          End If
          FileOut.WriteLine ("")
          If .Body <> "" Then
            FileOut.WriteLine ("  Body: " & .Body)
          End If

        End If ' ItemCrntClass = olAppointment

      End With  ' ItemCrnt

    Next ItemCrnt

  End With  ' GetNamespace("MAPI")

  FileOut.Close

End Sub
Другие вопросы по тегам