簡體   English   中英

Excel VBA - 循環遍歷 3 個特定的 Outlook 文件夾

[英]Excel VBA - Loop through 3 Specific outlook folders

我有一些代碼可以將 Outlook 郵件導出到 Excel 中,它可以完美運行,但我目前必須為 3 個不同文件夾(不是子文件夾)更改此代碼。 有沒有辦法可以指定它們並且代碼在所有 3.x 上運行。

這是我目前擁有的代碼

    Dim mailFolderItemsB As Object
    objOwner.Resolve
    If objOwner.Resolved Then
        Set mailFolderItemsB = objNamespace.GetSharedDefaultFolder(objOwner, olFolderInbox) _
                              .Parent.folders("Folder A") 'change this to B and then C once code has run.
    '.Parent.folders("Folder B")
    '.Parent.folders("Folder C")
    Set mailFolderItems = mailFolderItemsB.Items

如果忽略和道歉,這也可能是第二個問題。 是否可以在打開電子郵件然后更改時跟蹤更改,因為用戶經常打開郵件更改主題標題然后關閉。 想到一個 old.value 事件。

編輯 - 我的宏

Sub GetEmail()
 On Error GoTo ErrorHandler
Application.ScreenUpdating = False
Application.EnableEvents = False

Dim results() As String

  ' call function
  results = ExportEmails(True)

  ' paste onto worksheet
  Range(Cells(1, 1), Cells(UBound(results), UBound(results, 2))).Value = results
 Exit Sub
ErrorHandler:
    MsgBox Err.Description & " " & Err.Number, vbOKOnly + vbCritical, "Database Error"
End Sub

這是功能

Function ExportEmails(Optional headerRow As Boolean = False) As String()
    Dim objOutlook As Object ' Outlook.Application
    Dim objNamespace As Object ' Outlook.Namespace
    Dim strFolderName As Object
    Dim objMailbox As Object
    Dim objFolder As Object
    'Dim mailFolderItems As Object ' Outlook.items
    Dim folderItem As Object
    Dim msg As Object ' Outlook.MailItem
    Dim tempString() As String
    Dim i As Long
    Dim numRows As Long
    Dim startRow As Long
    Dim jAttach As Long ' counter for attachments
    Dim debugMsg As Integer
    
    ' select output results worksheet and clear previous results
    Sheets("Outlook Results").Select
    Sheets("Outlook Results").Cells.ClearContents
    Range("A1").Select
    Set objOutlook = CreateObject("Outlook.Application")
    Set objNamespace = objOutlook.GetNamespace("MAPI")
    
    Dim OutApp As outlook.Application
    Dim objOwner As outlook.Recipient
    
    Set OutApp = New outlook.Application
    Set objOwner = objNamespace.CreateRecipient("EmailAddess@CompanyName.com")
    
    Dim mailFolderItemsB As Object, f, mailFolderItems
    
    objOwner.Resolve
    If objOwner.Resolved Then
    
        For Each f In Array("Folder A", "Folder B", "Folder C")
            Set mailFolderItemsB = objNamespace.GetSharedDefaultFolder(objOwner, olFolderInbox) _
                     .Parent.folders(f) 'change this to B and then C once code has run.
            Set mailFolderItems = mailFolderItemsB.Items
    
      ' if calling procedure wants header row
      If headerRow Then
        startRow = 1
      Else
        startRow = 0
      End If
    
      numRows = mailFolderItems.Count
    
      ReDim tempString(1 To (numRows + startRow), 1 To 100)
    
      ' loop through folder items
      For i = 1 To numRows
    
        Set folderItem = mailFolderItems.Item(i)
    
        If IsMail(folderItem) Then
          Set msg = folderItem
    
    End If
        With msg
          tempString(i + startRow, 1) = .subject
          tempString(i + startRow, 2) = Replace(.body, vbLf, "")
          tempString(i + startRow, 3) = .Categories
          tempString(i + startRow, 4) = .cc
          tempString(i + startRow, 5) = .entryid
          tempString(i + startRow, 6) = .ConversationID ' .ConversationTopic 'conversationID  or conversationindex.propertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x007D001E") '.ConversationIndex
          tempString(i + startRow, 7) = .LastModificationTime 'sent
          tempString(i + startRow, 8) = .ReceivedByName
          tempString(i + startRow, 9) = .ReceivedOnBehalfOfName
          tempString(i + startRow, 10) = .ReceivedTime
          tempString(i + startRow, 11) = .SenderEmailAddress
          tempString(i + startRow, 12) = .SenderName
          tempString(i + startRow, 13) = .SentOn
          tempString(i + startRow, 14) = .To
          tempString(i + startRow, 15) = .propertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x1035001E")
    
        End With
        ' adding file attachment names where they exist
    If msg.Attachments.Count > 0 Then
        For jAttach = 1 To msg.Attachments.Count
           
    'get pdf and xlsx files
    Dim sAttachment As String
    sAttachment = msg.Attachments.Item(jAttach).DisplayName
        If Right(sAttachment, 4) = ".pdf" Or Right(sAttachment, 5) = ".xlsx" Then
    
    tempString(i + startRow, 21 + jAttach) = msg.Attachments.Item(jAttach).DisplayName
    
    End If
            
            Next jAttach
    
        End If
    
      Next i
    
      ' first row of array should be header values
      If headerRow Then
    
       tempString(1, 1) = "Subject"
          tempString(1, 2) = "Body"
          tempString(1, 3) = "Categories"
          tempString(1, 4) = "CC"
          tempString(1, 5) = "CreationTime"
          tempString(1, 6) = "ConversationID"
          tempString(1, 7) = "LastModificationTime"
          tempString(1, 8) = "ReceivedByName"
          tempString(1, 9) = "ReceivedOnBehalfOfName"
          tempString(1, 10) = "ReceivedTime"
          tempString(1, 11) = "SenderEmailAddress"
          tempString(1, 12) = "SenderName"
          tempString(1, 13) = "SentOn"
          tempString(1, 14) = "To"
          tempString(1, 15) = "ID"
          tempString(1, 16) = "Number of Attachments"
        tempString(1, 17) = "Attachment 1 Filename"
        tempString(1, 18) = "Attachment 2 Filename"
        tempString(1, 19) = "Attachment 3 Filename"
        tempString(1, 20) = "Attachment 4 Filename"
        tempString(1, 21) = "Attachment 5 Filename"
        tempString(1, 22) = "Attachment 6 Filename"
        tempString(1, 23) = "Attachment 7 Filename"
        tempString(1, 24) = "Attachment 8 Filename"
        tempString(1, 25) = "Attachment 9 Filename"
        tempString(1, 26) = "Attachment 10 Filename"
        tempString(1, 27) = "Attachment 11 Filename"
        tempString(1, 28) = "Attachment 12 Filename"
        tempString(1, 29) = "Attachment 13 Filename"
        tempString(1, 30) = "Attachment 14 Filename"
        tempString(1, 31) = "Attachment 15 Filename"
        tempString(1, 32) = "Attachment 16 Filename"
        tempString(1, 33) = "Attachment 17 Filename"
        tempString(1, 34) = "Attachment 18 Filename"
        tempString(1, 35) = "Attachment 19 Filename"
        tempString(1, 36) = "Attachment 20 Filename"
    End If
         Next f
    End If
    
      ExportEmails = tempString
    
        Range("A2").Select
        ActiveWindow.FreezePanes = True
        Rows("1:1").Select
    
    End Function

像這樣的東西:

Dim mailFolderItemsB As Object, f, mailFolderItems 

'...
objOwner.Resolve
If objOwner.Resolved Then

    For Each f in Array("Folder A","Folder B","Folder C")
        Set mailFolderItemsB = objNamespace.GetSharedDefaultFolder(objOwner, olFolderInbox) _
                 .Parent.folders(f) 'change this to B and then C once code has run.
        Set mailFolderItems = mailFolderItemsB.Items

        'something happens here...

    Next f
End If

編輯:你有一個巨大的功能,它做得太多了。 試試這個重新設計的例子

Sub ProcessEmails()

    Dim OutApp As Outlook.Application
    Dim objOwner As Outlook.Recipient
    Dim objOutlook As Object ' Outlook.Application
    Dim objNamespace As Object ' Outlook.Namespace
    Dim strFolderName As Object
    Dim objMailbox As Object
    Dim objFolder As Object, data
    Dim wsResults As Worksheet
    Dim mailFolderInbox As Object, f, dataRow As Long
    
    ' select output results worksheet and clear previous results
    Set wsResults = ThisWorkbook.Sheets("Outlook Results")
    wsResults.Cells.ClearContents
    
    Set objOutlook = CreateObject("Outlook.Application")
    Set objNamespace = objOutlook.GetNamespace("MAPI")
    
    Set OutApp = New Outlook.Application
    Set objOwner = objNamespace.CreateRecipient("EmailAddess@CompanyName.com")
    
    objOwner.Resolve
    If objOwner.Resolved Then
    
        Set mailFolderInbox = objNamespace.GetSharedDefaultFolder(objOwner, olFolderInbox)
        dataRow = 1 'start putting data on this row
        For Each f In Array("Folder A", "Folder B", "Folder C")
            data = MailData(mailFolderInbox.Parent.Folders(f), True)
            If Not IsEmpty(data) Then
                wsResults.Cells(dataRow, 1).Resize(UBound(data, 1), UBound(data, 2)).Value = data
                dataRow = dataRow + UBound(data, 1) 'next data dump position
            End If
        Next f 'next folder
    End If
End Sub

'Given an Outlook folder object, return an array of data about the contained
'  mail items.  Optionally add a header row to the array.
Function MailData(objFolder As Object, Optional headerRow As Boolean = False)
    
    Dim colMail As New Collection, itm As Object, data(), dataRow As Long, i As Long
    Dim arrHdr, dn, attNum As Long
    
    'only want mail items, so collect them in a Collection
    For Each itm In objFolder.Items
        If TypeName(itm) = "MailItem" Then colMail.Add itm
    Next itm
    If colMail.Count = 0 Then
        MailData = Empty 'nothing to report
        Exit Function
    End If
    
    dataRow = IIf(headerRow, 2, 1) 'data "row" for mail#1
    ReDim data(1 To colMail.Count + (dataRow - 1), 1 To 36)
    
    If headerRow Then 'adding a header "row"?
        arrHdr = Array("Subject", "Body", "Categories", "CC", "EntryId", _
                   "ConversationID", "LastModificationTime", "ReceivedByName", _
                   "ReceivedOnBehalfOfName", "ReceivedTime", "SenderEmailAddress", _
                   "SenderName", "SentOn", "To", "ID", "Number of Attachments")
        For i = 0 To UBound(arrHdr)
            data(1, i + 1) = arrHdr(i)
        Next i
        For i = 1 To 20
            data(1, 16 + i) = "Attachment " & i & " Filename"
        Next i
    End If
    
    For Each itm In colMail 'process all the mailitems found
        With itm
            data(dataRow, 1) = .Subject
            data(dataRow, 2) = Replace(.body, vbLf, "")
            data(dataRow, 3) = .Categories
            data(dataRow, 4) = .cc
            data(dataRow, 5) = .entryid
            data(dataRow, 6) = .ConversationID ' .ConversationTopic 'conversationID  or conversationindex.propertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x007D001E") '.ConversationIndex
            data(dataRow, 7) = .LastModificationTime 'sent
            data(dataRow, 8) = .ReceivedByName
            data(dataRow, 9) = .ReceivedOnBehalfOfName
            data(dataRow, 10) = .ReceivedTime
            data(dataRow, 11) = .SenderEmailAddress
            data(dataRow, 12) = .SenderName
            data(dataRow, 13) = .SentOn
            data(dataRow, 14) = .to
            data(dataRow, 15) = .propertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x1035001E")
            data(dataRow, 16) = .attachments.Count
            attNum = 0
            For i = 1 To .attachments.Count
                dn = .attachments(i).DisplayName
                If dn Like "*.xlsx" Or dn Like "*.pdf" Then
                    attNum = attNum + 1
                    If attNum > 20 Then Exit For 'too many attachments...
                    data(dataRow, 16 + attNum) = dn
                End If
            Next i
            dataRow = dataRow + 1
        End With
    Next itm
    MailData = data
End Function

首先,您需要為用戶檢索共享的默認文件夾 - 這是一個常見的操作,應該連續重復 3 次:

Dim mailFolderItemsB As Object
objOwner.Resolve
If objOwner.Resolved Then
    Set mailSharedInboxFolder = objNamespace.GetSharedDefaultFolder(objOwner, olFolderInbox) 

然后,您可以獲取三個文件夾的父文件夾:

Set mailSharedParentInboxFolder = mailSharedInboxFolder.Parent

最后你可以得到三個文件夾:

Set mailFolderItemsA = mailSharedParentInboxFolder.folders("Folder A")
Set mailFolderItemsB = mailSharedParentInboxFolder.folders("Folder B")
Set mailFolderItemsC = mailSharedParentInboxFolder.folders("Folder C")
'
Set mailFolderItems = mailFolderItemsB.Items

我建議避免在一行代碼中使用多個點。 因此,您將能夠輕松排除故障並優化整體性能。


對於跟蹤項目更改,我建議創建一個檢查器包裝器,請參閱為檢查器實現包裝器並在每個檢查器中跟蹤項目級事件以獲取更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM