View Single Post
 
Old 11-17-2014, 11:45 PM
gmayor's Avatar
gmayor gmayor is offline Windows 7 64bit Office 2010 32bit
Expert
 
Join Date: Aug 2014
Posts: 4,142
gmayor has much to be proud ofgmayor has much to be proud ofgmayor has much to be proud ofgmayor has much to be proud ofgmayor has much to be proud ofgmayor has much to be proud ofgmayor has much to be proud ofgmayor has much to be proud ofgmayor has much to be proud of
Default

OK - the following should do the job provided the Outlook folder only contains mail items and as you have multiple Outlook folders to process, the macro creates subfolders in the selected Root folder into which the PDFs from that Outlook folder are saved. I have not corrected for illegal Windows filename characters in the Outlook folder names, or for folders that contain items other than mail items.

There are two similar subs. One is run from a rule, the other from the macro ProcessFolder, which does as its name implies. It prompts for the mail folder to process

Because you have been talking about thousands of files I have added a progress indicator. You will need to download the attachment and import the userform it contains into the Outlook project.

Replace all the earlier code with the following and note the change of Sub names shoud you have already created the rule for the original version.

The ProcessFolder macro should now sort the folder in reverse order and process any PDFs attached to the messages, overwriting any existing PDFs of the same names

Code:
Option Explicit

Sub SavePDFAttachmentToDisk(Item As Outlook.MailItem)
'Use this macro as a script attached to a rule
Dim olkAttachment As Outlook.Attachment
Dim objFSO As Object
Dim strRootFolderPath As String
Dim strFilename As String
'Change the following path to match your environment
Const strRootFolderPath As String = "Y:\"
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    If Item.Attachments.Count > 0 Then
        For Each olkAttachment In Item.Attachments
            If objFSO.GetExtensionName(LCase(olkAttachment.Filename)) = "pdf" Then
                strFilename = strRootFolderPath & olkAttachment.Filename
                olkAttachment.SaveAsFile strFilename
            End If
        Next
    End If
    Set objFSO = Nothing
    Set olkAttachment = Nothing
lbl_Exit:
    Exit Sub
End Sub

Sub SaveAttachmentsFromFolderToDisk(Item As Outlook.MailItem, strFolderPath As String)
'Use this macro to process the folders, called from ProcessFolder
Dim olkAttachment As Outlook.Attachment
Dim objFSO As Object
Dim strFilename As String

    Set objFSO = CreateObject("Scripting.FileSystemObject")
    If Item.Attachments.Count > 0 Then
        For Each olkAttachment In Item.Attachments
            If objFSO.GetExtensionName(LCase(olkAttachment.Filename)) = "pdf" Then
                strFilename = strFolderPath & olkAttachment.Filename
                olkAttachment.SaveAsFile strFilename
            End If
        Next
    End If
    Set objFSO = Nothing
    Set olkAttachment = Nothing
lbl_Exit:
    Exit Sub
End Sub

Sub ProcessFolder()
Dim olFolder As Outlook.MAPIFolder
Dim olItem As Outlook.MailItem
Dim olItems As Outlook.Items
Dim olNS As Outlook.NameSpace
Dim i As Long
Dim oFrm As New frmProgress
Dim PortionDone As Double
Dim strFolder As String
Const strRootFolder As String = "Y:\"

    If Not FolderExists(strRootFolder) Then
        If Len(strRootFolder) = 3 Then
            MsgBox "The drive letter " & strRootFolder & " does not exist on this PC." & vbCr & vbCr & _
                   "Restore the drive and run the process again."
            GoTo lbl_Exit
        End If
    End If
    Set olNS = GetNamespace("MAPI")
    Set olFolder = olNS.PickFolder
    strFolder = olFolder.Name

    If Not FolderExists(strRootFolder & strFolder) Then
        CreateFolders strRootFolder & strFolder
    End If
    Set olItems = olFolder.Items
    olItems.Sort "[Received]", True
    oFrm.Show vbModeless
    For i = 1 To olItems.Count
        Set olItem = olItems(i)
        PortionDone = i / olItems.Count
        oFrm.lblProgress.Width = oFrm.fmeProgress.Width * PortionDone
        oFrm.Caption = "Processing message " & i & " of " & olItems.Count
        SaveAttachmentsFromFolderToDisk olItem, strRootFolder & strFolder & "\"
        DoEvents
    Next i
    Unload oFrm
lbl_Exit:
    Exit Sub
End Sub

Private Function FolderExists(ByVal PathName As String) As Boolean
Dim nAttr As Long
    On Error GoTo NoFolder
    nAttr = GetAttr(PathName)
    If (nAttr And vbDirectory) = vbDirectory Then
        FolderExists = True
    End If
NoFolder:
    Exit Function
End Function

Private Function CreateFolders(strPath As String)
Dim strTempPath As String
Dim lngPath As Long
Dim vPath As Variant
    vPath = Split(strPath, "\")
    strPath = vPath(0) & "\"
    For lngPath = 1 To UBound(vPath)
        strPath = strPath & vPath(lngPath) & "\"
        If Not FolderExists(strPath) Then MkDir strPath
    Next lngPath
lbl_Exit:
    Exit Function
End Function
Attached Files
File Type: zip Userform.zip (1.2 KB, 13 views)
__________________
Graham Mayor - MS MVP (Word) (2002-2019)
Visit my web site for more programming tips and ready made processes www.gmayor.com
Reply With Quote