Как создать собственные подпапки и сохранить вложения электронной почты в те папки, которые хранятся на моем компьютере? - PullRequest
0 голосов
/ 01 мая 2018

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

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

Возможно ли, чтобы при выборе места сохранения вложений скрипт создавал подпапку для каждого письма, а затем помещал вложения в эту папку? Я хотел бы использовать SenderName для каждого имени подпапки и добавить дату в конец? Пример, "SubFolderXYZ_04-30-2018".

Кроме того, есть ли способ сделать так, чтобы дата в подпапке соответствовала дате получения электронного письма, а не "сегодняшней" дате?

Option Explicit

If VBA7 Then
    Private lHwnd As LongPtr
    Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, _
    ByVal lpWindowName As String) As LongPtr
Else
    Private lHwnd As Long    
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, _
    ByVal lpWindowName As String) As Long
End If

' The class name of Outlook window.  
Private Const olAppCLSN As String = "rctrl_renwnd32"
' Windows desktop - the virtual folder that is the root of the namespace.  
Private Const CSIDL_DESKTOP = &H0
' Only return file system directories. If the user selects folders that are not part of the file system, the OK button is grayed.  
Private Const BIF_RETURNONLYFSDIRS = &H1
' Do not include network folders below the domain level in the dialog box's tree view control.  
Private Const BIF_DONTGOBELOWDOMAIN = &H2
' The maximum length for a path is 260 characters.  
Private Const MAX_PATH = 260

'  Returns the number of attachements in the selection.  
Public Function SaveAttachmentsFromSelection() As Long
Dim objFSO              As Object       ' Computer's file system object.  
Dim objShell            As Object       ' Windows Shell application object.  
Dim objFolder           As Object       ' The selected folder object from Browse for Folder dialog box.  
Dim objItem             As Object       ' A specific member of a Collection object either by position or by key.  
Dim selItems            As Selection    ' A collection of Outlook item objects in a folder.  
Dim atmt                As Attachment   ' A document or link to a document contained in an Outlook item.  
Dim strAtmtPath         As String       ' The full saving path of the attachment.  
Dim strAtmtFullName     As String       ' The full name of an attachment.  
Dim strAtmtName(1)      As String       ' strAtmtName(0): to save the name; strAtmtName(1): to save the file extension. They are separated by dot of an attachment file name.  
Dim strAtmtNameTemp     As String       ' To save a temporary attachment file name.  
Dim intDotPosition      As Integer      ' The dot position in an attachment name.  
Dim atmts               As Attachments  ' A set of Attachment objects that represent the attachments in an Outlook item.  
Dim lCountEachItem      As Long         ' The number of attachments in each Outlook item.  
Dim lCountAllItems      As Long         ' The number of attachments in all Outlook items.  
Dim strFolderPath       As String       ' The selected folder path.  
Dim blnIsEnd            As Boolean      ' End all code execution.  
Dim blnIsSave           As Boolean      ' Consider if it is need to save.  

blnIsEnd = False
blnIsSave = False
lCountAllItems = 0

On Error Resume Next

Set selItems = ActiveExplorer.Selection

If Err.Number = 0 Then

    ' Get the handle of Outlook window.  
    lHwnd = FindWindow(olAppCLSN, vbNullString)

    If lHwnd <> 0 Then

        ' /* Create a Shell application object to pop-up BrowseForFolder dialog box. */  
        Set objShell = CreateObject("Shell.Application")
        Set objFSO = CreateObject("Scripting.FileSystemObject")
        Set objFolder = objShell.BrowseForFolder(lHwnd, "Select folder to save attachments:", _
                                                 BIF_RETURNONLYFSDIRS + BIF_DONTGOBELOWDOMAIN, CSIDL_DESKTOP)

        ' /* Failed to create the Shell application. */  
        If Err.Number <> 0 Then
            MsgBox "Run-time error '" & CStr(Err.Number) & " (0x" & CStr(Hex(Err.Number)) & ")':" & vbNewLine & _
                   Err.Description & ".", vbCritical, "Error from Attachment Saver"
            blnIsEnd = True
            GoTo PROC_EXIT
        End If

        If objFolder Is Nothing Then
            strFolderPath = ""
            blnIsEnd = True
            GoTo PROC_EXIT
        Else
            strFolderPath = CGPath(objFolder.Self.Path)

            ' /* Go through each item in the selection. */  
            For Each objItem In selItems
                lCountEachItem = objItem.Attachments.Count

                ' /* If the current item contains attachments. */  
                If lCountEachItem > 0 Then
                    Set atmts = objItem.Attachments

                    ' /* Go through each attachment in the current item. */  
                    For Each atmt In atmts

                        ' Get the full name of the current attachment.  
                        strAtmtFullName = atmt.FileName

                        ' Find the dot postion in atmtFullName.  
                        intDotPosition = InStrRev(strAtmtFullName, ".")

                        ' Get the name.  
                        strAtmtName(0) = Left$(strAtmtFullName, intDotPosition - 1)
                        ' Get the file extension.
                        strAtmtName(1) = Right$(strAtmtFullName, Len(strAtmtFullName) - intDotPosition)
                        ' Get the full saving path of the current attachment.  
                        strAtmtPath = strFolderPath & atmt.FileName

                        ' /* If the length of the saving path is not larger than 260 characters.*/  
                        If Len(strAtmtPath) <= MAX_PATH Then
                            ' True: This attachment can be saved.  
                            blnIsSave = True

                            ' /* Loop until getting the file name which does not exist in the folder. */  
                            Do While objFSO.FileExists(strAtmtPath)
                                strAtmtNameTemp = strAtmtName(0) & _
                                                  Format(Now, "_mm-dd-yyyy")
                                strAtmtPath = strFolderPath & strAtmtNameTemp & "." & strAtmtName(1)

                                ' /* If the length of the saving path is over 260 characters.*/  
                                If Len(strAtmtPath) > MAX_PATH Then
                                    lCountEachItem = lCountEachItem - 1
                                    ' False: This attachment cannot be saved.  
                                    blnIsSave = False
                                    Exit Do
                                End If
                            Loop

                            ' /* Save the current attachment if it is a valid file name. */  
                            If blnIsSave Then atmt.SaveAsFile strAtmtPath
                        Else
                            lCountEachItem = lCountEachItem - 1
                        End If
                    Next
                End If

                ' Count the number of attachments in all Outlook items.  
                lCountAllItems = lCountAllItems + lCountEachItem
            Next
        End If
    Else
        MsgBox "Failed to get the handle of Outlook window!", vbCritical, "Error from Attachment Saver"
        blnIsEnd = True
        GoTo PROC_EXIT
    End If

' /* For run-time error:  
'    The Explorer has been closed and cannot be used for further operations.  
'    Review your code and restart Outlook. */  
Else
    MsgBox "Please select an Outlook item at least.", vbExclamation, "Message from Attachment Saver"
    blnIsEnd = True
End If

PROC_EXIT:
SaveAttachmentsFromSelection = lCountAllItems

' /* Release memory. */  
If Not (objFSO Is Nothing) Then Set objFSO = Nothing
If Not (objItem Is Nothing) Then Set objItem = Nothing
If Not (selItems Is Nothing) Then Set selItems = Nothing
If Not (atmt Is Nothing) Then Set atmt = Nothing
If Not (atmts Is Nothing) Then Set atmts = Nothing

' /* End all code execution if the value of blnIsEnd is True. */  
If blnIsEnd Then End
End Function

' Convert general path.  
Public Function CGPath(ByVal Path As String) As String
    If Right(Path, 1) <> "\" Then Path = Path & "\"
    CGPath = Path
End Function

' Run this macro for saving attachments.  
Public Sub ExecuteSaving()
    Dim lNum As Long

    lNum = SaveAttachmentsFromSelection

    If lNum > 0 Then
        MsgBox CStr(lNum) & " attachment(s) was(were) saved successfully.", vbInformation, "Message from Attachment Saver"
    Else
        MsgBox "No attachment(s) in the selected Outlook items.", vbInformation, "Message from Attachment Saver"
    End If
End Sub

1 Ответ

0 голосов
/ 01 мая 2018

Чтобы получить дату получения электронного письма, работайте с MailItem.ReceivedTime Property (Outlook) , затем отформатируйте его следующим образом: Format(objItem.ReceivedTime, "DD-MM-YYYY")

для папки используйте базовую функцию, которая проверяет, существует ли папка, или создайте ее, используя Свойство MailItem.SenderName (Outlook)

Пример

Private Function CreateDir(strFolderPath As String)
    Dim Elm As Variant
    Dim CheckPath As String

    CheckPath = ""
    For Each Elm In Split(strFolderPath, "\")
        CheckPath = CheckPath & Elm & "\"

        Debug.Print CheckPath & " Folder Exist"

        If Len(Dir(CheckPath, vbDirectory)) = 0 Then
            MkDir CheckPath
            Debug.Print CheckPath & " Folder Created"
        End If
    Next
End Function

В вашем коде внесите эти изменения

' /* Go through each item in the selection. */
For Each objItem In selItems

    Dim ResetPath As String
        ResetPath = strFolderPath

    strFolderPath = strFolderPath & objItem.SenderName & "_" & _
                             Format(objItem.ReceivedTime, "DD-MM-YYYY")

    CreateDir strFolderPath

    lCountEachItem = objItem.Attachments.Count

И это должно быть

strAtmtPath = strFolderPath & "\" & atmt.FileName

и следующие

    ' Count the number of attachments in all Outlook items.
    lCountAllItems = lCountAllItems + lCountEachItem
    strFolderPath = ResetPath ' reset
Next
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...