


Option Explicit
#If VBA7 Then
    Private Declare PtrSafe Function DeleteFile Lib "kernel32" Alias "DeleteFileA" (ByVal lpFileName As String) As Long
    Private Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As LongPtr, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As LongPtr
#Else
    Private Declare Function DeleteFile Lib "kernel32" Alias "DeleteFileA" (ByVal lpFileName As String) As Long
    Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
#End If
Private Sub PrintEmailBodyAndAttachments()
    Dim objMail As Outlook.MailItem
    Dim objSel As Outlook.Selection
    Dim objAtt As Outlook.Attachment
    Dim i As LongPtr, j As LongPtr, lngNumAtt As LongPtr
    Dim strAttFilePath As String
    i = 1
    SetDefaultPrinter "Tên máy in"
    Set objSel = Application.ActiveExplorer.Selection
    For i = 1 To objSel.Count
        If TypeOf objSel.Item(i) Is Outlook.MailItem Then
            Set objMail = objSel.Item(i)
            With objMail
                .PrintOut
                If .Attachments.Count > 0 Then
                    For j = 1 To .Attachments.Count
                        Set objAtt = .Attachments.Item(j)
                        strAttFilePath = Environ$("TEMP") & "\" & objAtt.FileName
                        objAtt.SaveAsFile strAttFilePath
                        Select Case GetFileExtension(strAttFilePath)
                            Case ".xls", ".xlsm", ".xlsb", ".xlsx", ".doc", ".docx", ".docm", ".pdf"
                                ShellExecute 0, "print", strAttFilePath, vbNullString, vbNullString, 0
                        End Select
                        DeleteFile strAttFilePath
                    Next
                End If
            End With
        End If
    Next
    Set objMail = Nothing
    Set objSel = Nothing
    Set objAtt = Nothing
End Sub
Private Sub SetDefaultPrinter(PrinterName As String, Optional ComputerName As String = ".")
    Dim Printer As Object, Printers As Object, WMIService As Object
    Set WMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & ComputerName & "\root\cimv2")
    Set Printers = WMIService.ExecQuery("Select * from Win32_Printer Where Name = '" & PrinterName & "'")
    For Each Printer In Printers
        Printer.SetDefaultPrinter
    Next
    Set Printer = Nothing
    Set Printers = Nothing
    Set WMIService = Nothing
End Sub
Private Function GetFileExtension(FileName As String) As String
    On Error Resume Next
    GetFileExtension = Mid(FileName, InStrRev(FileName, "."))
    If Err.Number = 5 Then
        GetFileExtension = vbNullString
    End If
End Function
Vừa chen ngang, vừa không đúng chủ đề.bạn giải giùm mình bài này với. Dùng hàm gì để đếm số hành khách ở cột nơi đến ra cột số hành khách/chuyến. Như dòng đầu có 4 hành khách. Ngăn cách giữa các hành khách là dấu +
Có nhiều cách viết code VBA trong trường hợp này, ở đây tôi xin trình bày một cách như sau (giả sử tệp đính kèm chỉ bao gồm phần mở rộng ".xls", ".xlsm", ".xlsb", ".xlsx", ".doc", ".docx", ".docm", ".pdf":
Chọn những thư cần in trong Outlook.
Mã:Option Explicit #If VBA7 Then Private Declare PtrSafe Function DeleteFile Lib "kernel32" Alias "DeleteFileA" (ByVal lpFileName As String) As Long Private Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As LongPtr, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As LongPtr #Else Private Declare Function DeleteFile Lib "kernel32" Alias "DeleteFileA" (ByVal lpFileName As String) As Long Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long #End If Private Sub PrintEmailBodyAndAttachments() Dim objMail As Outlook.MailItem Dim objSel As Outlook.Selection Dim objAtt As Outlook.Attachment Dim i As LongPtr, j As LongPtr, lngNumAtt As LongPtr Dim strAttFilePath As String i = 1 SetDefaultPrinter "Tên máy in" Set objSel = Application.ActiveExplorer.Selection For i = 1 To objSel.Count If TypeOf objSel.Item(i) Is Outlook.MailItem Then Set objMail = objSel.Item(i) With objMail .PrintOut If .Attachments.Count > 0 Then For j = 1 To .Attachments.Count Set objAtt = .Attachments.Item(j) strAttFilePath = Environ$("TEMP") & "\" & objAtt.FileName objAtt.SaveAsFile strAttFilePath Select Case GetFileExtension(strAttFilePath) Case ".xls", ".xlsm", ".xlsb", ".xlsx", ".doc", ".docx", ".docm", ".pdf" ShellExecute 0, "print", strAttFilePath, vbNullString, vbNullString, 0 End Select DeleteFile strAttFilePath Next End If End With End If Next Set objMail = Nothing Set objSel = Nothing Set objAtt = Nothing End Sub Private Sub SetDefaultPrinter(PrinterName As String, Optional ComputerName As String = ".") Dim Printer As Object, Printers As Object, WMIService As Object Set WMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & ComputerName & "\root\cimv2") Set Printers = WMIService.ExecQuery("Select * from Win32_Printer Where Name = '" & PrinterName & "'") For Each Printer In Printers Printer.SetDefaultPrinter Next Set Printer = Nothing Set Printers = Nothing Set WMIService = Nothing End Sub Private Function GetFileExtension(FileName As String) As String On Error Resume Next GetFileExtension = Mid(FileName, InStrRev(FileName, ".")) If Err.Number = 5 Then GetFileExtension = vbNullString End If End Function



Đặt code dưới đây vào Module trong trình soạn thảo VBE của Outlook (nhớ kích hoạt tab Developer):Có cách nào lấy toàn bộ file đính kèm từ 1 địa chỉ mail gửi đến không bạn.
Nếu được nhờ bạn hướng dẫn giúp.
Option Explicit
Public Sub DownloadAttachments(SenderEmailAddress As String)
    Dim objMail As Outlook.MailItem
    Dim objAtt As Outlook.Attachment
    Dim objFSO As Object
    Dim strRCDatePath As String, strFolderPath As String, strSenderPath As String
    Dim i As Long, j As Long
    Dim strFilter As String, strSenderEmailAddress As String
    Dim colItems As Outlook.Items
    Dim objInbox As Outlook.Folder
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    strFolderPath = Environ$("USERPROFILE") & "\Documents\OutlookAttachments\" 'Thu muc luu tap tin dinh kem, mac dinh: C:\<nguoidung>
    If Not objFSO.FolderExists(strFolderPath) Then objFSO.CreateFolder strFolderPath
    Const PR_SENDER_EMAIL_ADDRESS As String = "http://schemas.microsoft.com/mapi/proptag/0x0C1F001F"
    Const PR_HASATTACH As String = "http://schemas.microsoft.com/mapi/proptag/0x0E1B000B"
    strSenderEmailAddress = SenderEmailAddress 'Dia chi email nguoi gui
    strFilter = "@SQL=" & Quote(PR_SENDER_EMAIL_ADDRESS) & " = '" & strSenderEmailAddress & "' AND " & Quote(PR_HASATTACH) & "=1"
    Set objInbox = Application.Session.GetDefaultFolder(olFolderInbox)
    Set colItems = objInbox.Items.Restrict(strFilter)
    For j = 1 To colItems.Count
        Set objMail = colItems.Item(j)
        With objMail
            If Not objFSO.FolderExists(strFolderPath & GetDateFromReceivedTime(.ReceivedTime)) Then
                strRCDatePath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime)
                objFSO.CreateFolder strRCDatePath
            Else: strRCDatePath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime)
            End If
            If Not objFSO.FolderExists(strFolderPath & GetDateFromReceivedTime(.ReceivedTime) & "\" & .SenderName) Then
                strSenderPath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime) & "\" & .SenderName
                objFSO.CreateFolder strSenderPath
            Else: strSenderPath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime) & "\" & .SenderName
            End If
            For i = 1 To .Attachments.Count
                Set objAtt = .Attachments.Item(i)
                If objFSO.FileExists(strSenderPath & "\" & objAtt.filename) Then
                    objFSO.DeleteFile strSenderPath & "\" & objAtt.filename
                End If
                objAtt.SaveAsFile strSenderPath & "\" & objAtt.filename
            Next i
        End With
    Next
    Shell "explorer """ & strFolderPath & "", vbNormalFocus
End Sub
Private Function Quote(Text As String) As String
    Quote = Chr(34) & Text & Chr(34)
End Function
Private Function GetDateFromReceivedTime(ReceivedDateString As String) As String
    Dim RDString As String
    RDString = Trim(Format(Left(ReceivedDateString, InStr(ReceivedDateString, " ")), "dd-mm-yyyy"))
    GetDateFromReceivedTime = RDString
End FunctionPrivate Sub Test()
    Call DownloadAttachments("abc@gmail.com")
End Sub



Thật tuyệt vời, những dòng code của anh chạy cực nhanh và chính xác.Đặt code dưới đây vào Module trong trình soạn thảo VBE của Outlook (nhớ kích hoạt tab Developer):
Lưu ý: Macro này sẽ tìm kiếm các email trong thư mục Inbox mặc định trong Outlook.
Mã:Option Explicit Public Sub DownloadAttachments(SenderEmailAddress As String) Dim objMail As Outlook.MailItem Dim objAtt As Outlook.Attachment Dim objFSO As Object Dim strRCDatePath As String, strFolderPath As String, strSenderPath As String Dim i As Long, j As Long Dim strFilter As String, strSenderEmailAddress As String Dim colItems As Outlook.Items Dim objInbox As Outlook.Folder Set objFSO = CreateObject("Scripting.FileSystemObject") strFolderPath = Environ$("USERPROFILE") & "\Documents\OutlookAttachments\" 'Thu muc luu tap tin dinh kem, mac dinh: C:\<nguoidung> If Not objFSO.FolderExists(strFolderPath) Then objFSO.CreateFolder strFolderPath Const PR_SENDER_EMAIL_ADDRESS As String = "http://schemas.microsoft.com/mapi/proptag/0x0C1F001F" Const PR_HASATTACH As String = "http://schemas.microsoft.com/mapi/proptag/0x0E1B000B" strSenderEmailAddress = SenderEmailAddress 'Dia chi email nguoi gui strFilter = "@SQL=" & Quote(PR_SENDER_EMAIL_ADDRESS) & " = '" & strSenderEmailAddress & "' AND " & Quote(PR_HASATTACH) & "=1" Set objInbox = Application.Session.GetDefaultFolder(olFolderInbox) Set colItems = objInbox.Items.Restrict(strFilter) For j = 1 To colItems.Count Set objMail = colItems.Item(j) With objMail If Not objFSO.FolderExists(strFolderPath & GetDateFromReceivedTime(.ReceivedTime)) Then strRCDatePath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime) objFSO.CreateFolder strRCDatePath Else: strRCDatePath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime) End If If Not objFSO.FolderExists(strFolderPath & GetDateFromReceivedTime(.ReceivedTime) & "\" & .SenderName) Then strSenderPath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime) & "\" & .SenderName objFSO.CreateFolder strSenderPath Else: strSenderPath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime) & "\" & .SenderName End If For i = 1 To .Attachments.Count Set objAtt = .Attachments.Item(i) If objFSO.FileExists(strSenderPath & "\" & objAtt.filename) Then objFSO.DeleteFile strSenderPath & "\" & objAtt.filename End If objAtt.SaveAsFile strSenderPath & "\" & objAtt.filename Next i End With Next Shell "explorer """ & strFolderPath & "", vbNormalFocus End Sub Private Function Quote(Text As String) As String Quote = Chr(34) & Text & Chr(34) End Function Private Function GetDateFromReceivedTime(ReceivedDateString As String) As String Dim RDString As String RDString = Trim(Format(Left(ReceivedDateString, InStr(ReceivedDateString, " ")), "dd-mm-yyyy")) GetDateFromReceivedTime = RDString End Function
Khi chạy thủ tục, thay tham số SenderEmailAddress thành địa chỉ email thích hợp, ví dụ:
Mã:Private Sub Test() Call DownloadAttachments("abc@gmail.com") End Sub



Sửa lại một chút macro ở trên.Thật tuyệt vời, những dòng code của anh chạy cực nhanh và chính xác.
Nhờ anh chỉ giúp em nếu muốn thay đổi thư mục mặc định tìm kiếm là Inbox sang 1 thư mục cá nhân khác, và giới hạn thời gian tìm kiếm thì phải sửa code như thế nào ạ.
Option Explicit
Public Sub DownloadAttachments(SenderEmailAddress As String, StartDate As Date, EndDate As Date)
    Dim objMail As Outlook.MailItem
    Dim objAtt As Outlook.Attachment
    Dim objPA As Outlook.PropertyAccessor
    Dim objFSO As Object
    Dim strRCDatePath As String, strFolderPath As String, strSenderPath As String
    Dim dteStartDate As Date, dteEndDate As Date, dteStartDateUTC As Date, dteEndDateUTC As Date
    Dim i As Long, j As Long
    Dim strFilter As String, strSenderEmailAddress As String
    Dim colItems As Outlook.Items
    Dim objFolder As Outlook.Folder
    Const PR_SENDER_EMAIL_ADDRESS As String = "http://schemas.microsoft.com/mapi/proptag/0x0C1F001F"
    Const PR_HASATTACH As String = "http://schemas.microsoft.com/mapi/proptag/0x0E1B000B"
    dteStartDate = StartDate 'Ngay bat dau, vd: #1/1#2021#
    dteEndDate = EndDate 'Ngay ket thuc, vd: #1/1/2022#
    Set objMail = Application.CreateItem(olMailItem)
    With objMail
        Set objPA = .PropertyAccessor
        dteStartDateUTC = objPA.LocalTimeToUTC(dteStartDate)
        dteEndDateUTC = objPA.LocalTimeToUTC(dteEndDate)
        .Close olDiscard
    End With
    strSenderEmailAddress = SenderEmailAddress 'Dia chi email nguoi gui
    strFilter = "@SQL=" & Quote(PR_SENDER_EMAIL_ADDRESS) & " = '" & strSenderEmailAddress & "' AND " & Quote(PR_HASATTACH) & "=1 AND " & _
                Quote("urn:schemas:httpmail:datereceived") & " > " & Chr(39) & dteStartDateUTC & Chr(39) & " And " & Quote("urn:schemas:httpmail:datereceived") & " < " & Chr(39) & dteEndDateUTC & Chr(39)
    strFolderPath = Environ$("USERPROFILE") & "\Documents\OutlookAttachments\" 'Thu muc luu tap tin dinh kem, mac dinh: C:\<nguoidung>
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    If Not objFSO.FolderExists(strFolderPath) Then objFSO.CreateFolder strFolderPath
    On Error Resume Next
    Set objFolder = Application.Session.PickFolder
    If Not objFolder Is Nothing Then
        Set colItems = objFolder.Items.Restrict(strFilter)
        For j = 1 To colItems.Count
            Set objMail = colItems.Item(j)
            With objMail
                If Not objFSO.FolderExists(strFolderPath & GetDateFromReceivedTime(.ReceivedTime)) Then
                    strRCDatePath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime)
                    objFSO.CreateFolder strRCDatePath
                Else: strRCDatePath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime)
                End If
                If Not objFSO.FolderExists(strFolderPath & GetDateFromReceivedTime(.ReceivedTime) & "\" & .SenderName) Then
                    strSenderPath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime) & "\" & .SenderName
                    objFSO.CreateFolder strSenderPath
                Else: strSenderPath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime) & "\" & .SenderName
                End If
                For i = 1 To .Attachments.Count
                    Set objAtt = .Attachments.Item(i)
                    If objFSO.FileExists(strSenderPath & "\" & objAtt.DisplayName) Then
                        objFSO.DeleteFile strSenderPath & "\" & objAtt.DisplayName
                    End If
                    objAtt.SaveAsFile strSenderPath & "\" & objAtt.DisplayName
                Next i
            End With
        Next
        Shell "explorer """ & strFolderPath & "", vbNormalFocus
    End If
End Sub
Private Function Quote(Text As String) As String
    Quote = Chr(34) & Text & Chr(34)
End Function
Private Function GetDateFromReceivedTime(ReceivedDateString As String) As String
    Dim RDString As String
    RDString = Trim(Format(Left(ReceivedDateString, InStr(ReceivedDateString, " ")), "dd-mm-yyyy"))
    GetDateFromReceivedTime = RDString
End FunctionPrivate Sub Test()
    Call DownloadAttachments("abc@gmail.com", #1/1/2021#, #1/1/2022#)
End Sub



Cảm ơn anh rất nhiều, code chạy rất chính xác ạ.Sửa lại một chút macro ở trên.
Code dưới đây hiển thị hộp thoại chọn thư mục email để tìm kiếm:
Mã:Option Explicit Public Sub DownloadAttachments(SenderEmailAddress As String, StartDate As Date, EndDate As Date) Dim objMail As Outlook.MailItem Dim objAtt As Outlook.Attachment Dim objPA As Outlook.PropertyAccessor Dim objFSO As Object Dim strRCDatePath As String, strFolderPath As String, strSenderPath As String Dim dteStartDate As Date, dteEndDate As Date, dteStartDateUTC As Date, dteEndDateUTC As Date Dim i As Long, j As Long Dim strFilter As String, strSenderEmailAddress As String Dim colItems As Outlook.Items Dim objFolder As Outlook.Folder Const PR_SENDER_EMAIL_ADDRESS As String = "http://schemas.microsoft.com/mapi/proptag/0x0C1F001F" Const PR_HASATTACH As String = "http://schemas.microsoft.com/mapi/proptag/0x0E1B000B" dteStartDate = StartDate 'Ngay bat dau, vd: #1/1#2021# dteEndDate = EndDate 'Ngay ket thuc, vd: #1/1/2022# Set objMail = Application.CreateItem(olMailItem) With objMail Set objPA = .PropertyAccessor dteStartDateUTC = objPA.LocalTimeToUTC(dteStartDate) dteEndDateUTC = objPA.LocalTimeToUTC(dteEndDate) .Close olDiscard End With strSenderEmailAddress = SenderEmailAddress 'Dia chi email nguoi gui strFilter = "@SQL=" & Quote(PR_SENDER_EMAIL_ADDRESS) & " = '" & strSenderEmailAddress & "' AND " & Quote(PR_HASATTACH) & "=1 AND " & _ Quote("urn:schemas:httpmail:datereceived") & " > " & Chr(39) & dteStartDateUTC & Chr(39) & " And " & Quote("urn:schemas:httpmail:datereceived") & " < " & Chr(39) & dteEndDateUTC & Chr(39) strFolderPath = Environ$("USERPROFILE") & "\Documents\OutlookAttachments\" 'Thu muc luu tap tin dinh kem, mac dinh: C:\<nguoidung> Set objFSO = CreateObject("Scripting.FileSystemObject") If Not objFSO.FolderExists(strFolderPath) Then objFSO.CreateFolder strFolderPath On Error Resume Next Set objFolder = Application.Session.PickFolder If Not objFolder Is Nothing Then Set colItems = objFolder.Items.Restrict(strFilter) For j = 1 To colItems.Count Set objMail = colItems.Item(j) With objMail If Not objFSO.FolderExists(strFolderPath & GetDateFromReceivedTime(.ReceivedTime)) Then strRCDatePath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime) objFSO.CreateFolder strRCDatePath Else: strRCDatePath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime) End If If Not objFSO.FolderExists(strFolderPath & GetDateFromReceivedTime(.ReceivedTime) & "\" & .SenderName) Then strSenderPath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime) & "\" & .SenderName objFSO.CreateFolder strSenderPath Else: strSenderPath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime) & "\" & .SenderName End If For i = 1 To .Attachments.Count Set objAtt = .Attachments.Item(i) If objFSO.FileExists(strSenderPath & "\" & objAtt.DisplayName) Then objFSO.DeleteFile strSenderPath & "\" & objAtt.DisplayName End If objAtt.SaveAsFile strSenderPath & "\" & objAtt.DisplayName Next i End With Next Shell "explorer """ & strFolderPath & "", vbNormalFocus End If End Sub Private Function Quote(Text As String) As String Quote = Chr(34) & Text & Chr(34) End Function Private Function GetDateFromReceivedTime(ReceivedDateString As String) As String Dim RDString As String RDString = Trim(Format(Left(ReceivedDateString, InStr(ReceivedDateString, " ")), "dd-mm-yyyy")) GetDateFromReceivedTime = RDString End Function
Sử dụng macro để tìm kiếm và tải xuống tập tin đính kèm từ SenderEmailAddress, trong khoảng thời gian từ ngày StartDate đến ngày EndDate:
Mã:Private Sub Test() Call DownloadAttachments("abc@gmail.com", #1/1/2021#, #1/1/2022#) End Sub

Cho mình hỏi chút.Sửa lại một chút macro ở trên.
Code dưới đây hiển thị hộp thoại chọn thư mục email để tìm kiếm:
Mã:Option Explicit Public Sub DownloadAttachments(SenderEmailAddress As String, StartDate As Date, EndDate As Date) Dim objMail As Outlook.MailItem Dim objAtt As Outlook.Attachment Dim objPA As Outlook.PropertyAccessor Dim objFSO As Object Dim strRCDatePath As String, strFolderPath As String, strSenderPath As String Dim dteStartDate As Date, dteEndDate As Date, dteStartDateUTC As Date, dteEndDateUTC As Date Dim i As Long, j As Long Dim strFilter As String, strSenderEmailAddress As String Dim colItems As Outlook.Items Dim objFolder As Outlook.Folder Const PR_SENDER_EMAIL_ADDRESS As String = "http://schemas.microsoft.com/mapi/proptag/0x0C1F001F" Const PR_HASATTACH As String = "http://schemas.microsoft.com/mapi/proptag/0x0E1B000B" dteStartDate = StartDate 'Ngay bat dau, vd: #1/1#2021# dteEndDate = EndDate 'Ngay ket thuc, vd: #1/1/2022# Set objMail = Application.CreateItem(olMailItem) With objMail Set objPA = .PropertyAccessor dteStartDateUTC = objPA.LocalTimeToUTC(dteStartDate) dteEndDateUTC = objPA.LocalTimeToUTC(dteEndDate) .Close olDiscard End With strSenderEmailAddress = SenderEmailAddress 'Dia chi email nguoi gui strFilter = "@SQL=" & Quote(PR_SENDER_EMAIL_ADDRESS) & " = '" & strSenderEmailAddress & "' AND " & Quote(PR_HASATTACH) & "=1 AND " & _ Quote("urn:schemas:httpmail:datereceived") & " > " & Chr(39) & dteStartDateUTC & Chr(39) & " And " & Quote("urn:schemas:httpmail:datereceived") & " < " & Chr(39) & dteEndDateUTC & Chr(39) strFolderPath = Environ$("USERPROFILE") & "\Documents\OutlookAttachments\" 'Thu muc luu tap tin dinh kem, mac dinh: C:\<nguoidung> Set objFSO = CreateObject("Scripting.FileSystemObject") If Not objFSO.FolderExists(strFolderPath) Then objFSO.CreateFolder strFolderPath On Error Resume Next Set objFolder = Application.Session.PickFolder If Not objFolder Is Nothing Then Set colItems = objFolder.Items.Restrict(strFilter) For j = 1 To colItems.Count Set objMail = colItems.Item(j) With objMail If Not objFSO.FolderExists(strFolderPath & GetDateFromReceivedTime(.ReceivedTime)) Then strRCDatePath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime) objFSO.CreateFolder strRCDatePath Else: strRCDatePath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime) End If If Not objFSO.FolderExists(strFolderPath & GetDateFromReceivedTime(.ReceivedTime) & "\" & .SenderName) Then strSenderPath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime) & "\" & .SenderName objFSO.CreateFolder strSenderPath Else: strSenderPath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime) & "\" & .SenderName End If For i = 1 To .Attachments.Count Set objAtt = .Attachments.Item(i) If objFSO.FileExists(strSenderPath & "\" & objAtt.DisplayName) Then objFSO.DeleteFile strSenderPath & "\" & objAtt.DisplayName End If objAtt.SaveAsFile strSenderPath & "\" & objAtt.DisplayName Next i End With Next Shell "explorer """ & strFolderPath & "", vbNormalFocus End If End Sub Private Function Quote(Text As String) As String Quote = Chr(34) & Text & Chr(34) End Function Private Function GetDateFromReceivedTime(ReceivedDateString As String) As String Dim RDString As String RDString = Trim(Format(Left(ReceivedDateString, InStr(ReceivedDateString, " ")), "dd-mm-yyyy")) GetDateFromReceivedTime = RDString End Function
Sử dụng macro để tìm kiếm và tải xuống tập tin đính kèm từ SenderEmailAddress, trong khoảng thời gian từ ngày StartDate đến ngày EndDate:
Mã:Private Sub Test() Call DownloadAttachments("abc@gmail.com", #1/1/2021#, #1/1/2022#) End Sub




Lạ nhỉ, thông thường những thư mục đó chỉ được tạo khi tìm được những email thỏa mãn tiêu chí tìm kiếm. Bạn thử chạy lại xem sao nhé.Cho mình hỏi chút.
Khi mình chạy code thì chỉ tạo ra foder ngày có mail đến thôi. Còn file đính kèm thì không có.
Mình chỉ coppy dán code và thay đổi địa chỉ mail. Không rõ là có cần chỉnh sửa gì nữa không.
Nhờ bạn chỉ giúp.
View attachment 284038


Em chào Anh,Sửa lại một chút macro ở trên.
Code dưới đây hiển thị hộp thoại chọn thư mục email để tìm kiếm:
Mã:Option Explicit Public Sub DownloadAttachments(SenderEmailAddress As String, StartDate As Date, EndDate As Date) Dim objMail As Outlook.MailItem Dim objAtt As Outlook.Attachment Dim objPA As Outlook.PropertyAccessor Dim objFSO As Object Dim strRCDatePath As String, strFolderPath As String, strSenderPath As String Dim dteStartDate As Date, dteEndDate As Date, dteStartDateUTC As Date, dteEndDateUTC As Date Dim i As Long, j As Long Dim strFilter As String, strSenderEmailAddress As String Dim colItems As Outlook.Items Dim objFolder As Outlook.Folder Const PR_SENDER_EMAIL_ADDRESS As String = "http://schemas.microsoft.com/mapi/proptag/0x0C1F001F" Const PR_HASATTACH As String = "http://schemas.microsoft.com/mapi/proptag/0x0E1B000B" dteStartDate = StartDate 'Ngay bat dau, vd: #1/1#2021# dteEndDate = EndDate 'Ngay ket thuc, vd: #1/1/2022# Set objMail = Application.CreateItem(olMailItem) With objMail Set objPA = .PropertyAccessor dteStartDateUTC = objPA.LocalTimeToUTC(dteStartDate) dteEndDateUTC = objPA.LocalTimeToUTC(dteEndDate) .Close olDiscard End With strSenderEmailAddress = SenderEmailAddress 'Dia chi email nguoi gui strFilter = "@SQL=" & Quote(PR_SENDER_EMAIL_ADDRESS) & " = '" & strSenderEmailAddress & "' AND " & Quote(PR_HASATTACH) & "=1 AND " & _ Quote("urn:schemas:httpmail:datereceived") & " > " & Chr(39) & dteStartDateUTC & Chr(39) & " And " & Quote("urn:schemas:httpmail:datereceived") & " < " & Chr(39) & dteEndDateUTC & Chr(39) strFolderPath = Environ$("USERPROFILE") & "\Documents\OutlookAttachments\" 'Thu muc luu tap tin dinh kem, mac dinh: C:\<nguoidung> Set objFSO = CreateObject("Scripting.FileSystemObject") If Not objFSO.FolderExists(strFolderPath) Then objFSO.CreateFolder strFolderPath On Error Resume Next Set objFolder = Application.Session.PickFolder If Not objFolder Is Nothing Then Set colItems = objFolder.Items.Restrict(strFilter) For j = 1 To colItems.Count Set objMail = colItems.Item(j) With objMail If Not objFSO.FolderExists(strFolderPath & GetDateFromReceivedTime(.ReceivedTime)) Then strRCDatePath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime) objFSO.CreateFolder strRCDatePath Else: strRCDatePath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime) End If If Not objFSO.FolderExists(strFolderPath & GetDateFromReceivedTime(.ReceivedTime) & "\" & .SenderName) Then strSenderPath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime) & "\" & .SenderName objFSO.CreateFolder strSenderPath Else: strSenderPath = strFolderPath & GetDateFromReceivedTime(.ReceivedTime) & "\" & .SenderName End If For i = 1 To .Attachments.Count Set objAtt = .Attachments.Item(i) If objFSO.FileExists(strSenderPath & "\" & objAtt.DisplayName) Then objFSO.DeleteFile strSenderPath & "\" & objAtt.DisplayName End If objAtt.SaveAsFile strSenderPath & "\" & objAtt.DisplayName Next i End With Next Shell "explorer """ & strFolderPath & "", vbNormalFocus End If End Sub Private Function Quote(Text As String) As String Quote = Chr(34) & Text & Chr(34) End Function Private Function GetDateFromReceivedTime(ReceivedDateString As String) As String Dim RDString As String RDString = Trim(Format(Left(ReceivedDateString, InStr(ReceivedDateString, " ")), "dd-mm-yyyy")) GetDateFromReceivedTime = RDString End Function
Sử dụng macro để tìm kiếm và tải xuống tập tin đính kèm từ SenderEmailAddress, trong khoảng thời gian từ ngày StartDate đến ngày EndDate:
Mã:Private Sub Test() Call DownloadAttachments("abc@gmail.com", #1/1/2021#, #1/1/2022#) End Sub



Thử code này xem sao nhé, bởi vì bạn sử dụng tài khoản email chuyên dùng để nhận tệp đính kèm nên mình bỏ điều kiện lọc địa chỉ email, chỉ giữ lại điều kiện khoảng ngày, và tất cả những tệp đính kèm thỏa mãn yêu cầu là tệp Excel và tệp pdf đều sẽ được lưu vào chung một thư mục.Em chào Anh,
Giống như code này nếu chỉ muốn lấy những file đính kèm dạng excel và pdf (Hoặc tìm và lọc theo dạng tên file) trong nguyên 1 thư mục luôn thì có được không ạ, vì như bên em sử dụng những địa chỉ email chuyên để nhận file từ nhiều khách hàng, hàng ngày em phải trích lưu những file đính kèm của nhiều bên gửi tới hộp mail chung đó nên việc chỉ định lấy theo từng Sender sẽ không hiệu quả. Mong anh hướng dẫn giúp.
Option Explicit
Public Sub DownloadAttachments(StartDate As Date, EndDate As Date)
    Dim objMail As Outlook.MailItem
    Dim objAtt As Outlook.Attachment
    Dim objPA As Outlook.PropertyAccessor
    Dim objFSO As Object
    Dim strFolderPath As String, strDateTimeFolder As String
    Dim dteStartDate As Date, dteEndDate As Date, dteStartDateUTC As Date, dteEndDateUTC As Date
    Dim i As Long, j As Long
    Dim strFilter As String
    Dim colItems As Outlook.Items
    Dim objFolder As Outlook.Folder
    Const PR_HASATTACH As String = "http://schemas.microsoft.com/mapi/proptag/0x0E1B000B"
    dteStartDate = StartDate 'Ngay bat dau, vd: #1/1#2021#
    dteEndDate = EndDate 'Ngay ket thuc, vd: #1/1/2022#
    Set objMail = Application.CreateItem(olMailItem)
    With objMail
        Set objPA = .PropertyAccessor
        dteStartDateUTC = objPA.LocalTimeToUTC(dteStartDate)
        dteEndDateUTC = objPA.LocalTimeToUTC(dteEndDate)
        .Close olDiscard
    End With
    strFilter = "@SQL=" & Quote(PR_HASATTACH) & "=1 AND " & _
                Quote("urn:schemas:httpmail:datereceived") & " > " & Chr(39) & dteStartDateUTC & Chr(39) & " And " & Quote("urn:schemas:httpmail:datereceived") & " < " & Chr(39) & dteEndDateUTC & Chr(39)
    strFolderPath = Environ$("USERPROFILE") & "\Documents\OutlookAttachments\" 'Thu muc luu tap tin dinh kem, mac dinh: C:\<nguoidung>
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    If Not objFSO.FolderExists(strFolderPath) Then objFSO.CreateFolder strFolderPath
    If Not objFSO.FolderExists(strFolderPath & Format$(Now, "dd-mm-yyyy hh.nn.ss")) Then
        strDateTimeFolder = strFolderPath & Format$(Now, "dd-mm-yyyy hh.nn.ss")
        objFSO.CreateFolder strDateTimeFolder
    Else: strDateTimeFolder = strFolderPath & Format$(Now, "dd-mm-yyyy hh.nn.ss")
    End If
    On Error Resume Next
    Set objFolder = Application.Session.PickFolder
    If Not objFolder Is Nothing Then
        Set colItems = objFolder.Items.Restrict(strFilter)
        For j = 1 To colItems.Count
            Set objMail = colItems.Item(j)
            With objMail
                For i = 1 To .Attachments.Count
                    Set objAtt = .Attachments.Item(i)
                    Select Case objFSO.GetExtensionName(objAtt.filename)
                        Case "xlsx", "xls", "xlsm", "pdf"
                            If objFSO.FileExists(strDateTimeFolder & "\" & objAtt.filename) Then
                                objFSO.DeleteFile strDateTimeFolder & "\" & objAtt.filename
                            End If
                            objAtt.SaveAsFile strDateTimeFolder & "\" & objAtt.filename
                    End Select
                Next i
            End With
        Next
        Shell "explorer """ & strFolderPath & "", vbNormalFocus
    End If
End Sub
Private Function Quote(Text As String) As String
    Quote = Chr(34) & Text & Chr(34)
End FunctionNếu hàng ngày phải trích lưu những tệp đính kèm như thế này thì bạn nên viết macro để Outlook tự động tải xuống tệp đính kèm mỗi khi nhận được email là được.hàng ngày em phải trích lưu những file đính kèm của nhiều bên gửi tới hộp mail chung đó nên việc chỉ định lấy theo từng Sender sẽ không hiệu quả.


Em cảm ơn anh, em đã chạy thử và thấy mã code của anh đã lấy được các file đính kèm gom chung vào 1 thư mục, kết quả đã đúng ạ. Chỉ lưu ý là muốn lấy dữ liệu tới ngày nào thì phải gõ EndDate sau hôm đó 1 ngày.Nếu hàng ngày phải trích lưu những tệp đính kèm như thế này thì bạn nên viết macro để Outlook tự động tải xuống tệp đính kèm mỗi khi nhận được email là được.



Nếu bạn có thắc mắc gì về Outlook VBA, bạn có thể liên hệ với mình để được giải quyết.Em cảm ơn anh, em đã chạy thử và thấy mã code của anh đã lấy được các file đính kèm gom chung vào 1 thư mục, kết quả đã đúng ạ. Chỉ lưu ý là muốn lấy dữ liệu tới ngày nào thì phải gõ EndDate sau hôm đó 1 ngày.
Hiện tại em cũng mới học VBA căn bản, giáo trình và video hướng dẫn của Excel rất nhiều, tuy nhiên về phần Outlook thì lại ít tài liệu hướng dẫn hơn. Cảm ơn anh đã chỉ dẫn, em sẽ cố gắng thêm.



À quên nữa, bổ sung thêm cái này.Em cảm ơn anh, em đã chạy thử và thấy mã code của anh đã lấy được các file đính kèm gom chung vào 1 thư mục, kết quả đã đúng ạ. Chỉ lưu ý là muốn lấy dữ liệu tới ngày nào thì phải gõ EndDate sau hôm đó 1 ngày.
Hiện tại em cũng mới học VBA căn bản, giáo trình và video hướng dẫn của Excel rất nhiều, tuy nhiên về phần Outlook thì lại ít tài liệu hướng dẫn hơn. Cảm ơn anh đã chỉ dẫn, em sẽ cố gắng thêm.

Option Explicit
Public Enum DateTimeMacro
    Today
    Tomorrow
    Yesterday
    Next7days
    Last7days
    NextWeek
    ThisWeek
    LastWeek
    NextMonth
    ThisMonth
    LastMonth
End Enum
Public Sub DownloadAttachments(Optional UseDateTimeMacro As Boolean = False, Optional DateTimeMacro As DateTimeMacro, Optional StartDate As Date, Optional EndDate As Date)
    Dim objMail As Outlook.MailItem
    Dim objAtt As Outlook.Attachment
    Dim objPA As Outlook.PropertyAccessor
    Dim objFSO As Object
    Dim strFolderPath As String, strDateTimeFolder As String
    Dim dteStartDate As Date, dteEndDate As Date, dteStartDateUTC As Date, dteEndDateUTC As Date
    Dim i As Long, j As Long
    Dim strFilter As String
    Dim colItems As Outlook.Items
    Dim objFolder As Outlook.Folder
    Dim strDateTimeMacro As String
    Const PR_HASATTACH As String = "http://schemas.microsoft.com/mapi/proptag/0x0E1B000B"
    If UseDateTimeMacro = False Then
        dteStartDate = StartDate 'Ngay bat dau, vd: #1/1#2021#
        dteEndDate = EndDate 'Ngay ket thuc, vd: #1/1/2022#
        Set objMail = Application.CreateItem(olMailItem)
        With objMail
            Set objPA = .PropertyAccessor
            dteStartDateUTC = objPA.LocalTimeToUTC(dteStartDate)
            dteEndDateUTC = objPA.LocalTimeToUTC(dteEndDate)
            .Close olDiscard
        End With
        strFilter = "@SQL=" & Quote(PR_HASATTACH) & "=1 AND " & _
                Quote("urn:schemas:httpmail:datereceived") & " > " & Chr(39) & dteStartDateUTC & Chr(39) & " And " & Quote("urn:schemas:httpmail:datereceived") & " < " & Chr(39) & dteEndDateUTC & Chr(39)
    Else
        Select Case DateTimeMacro
            Case Today
                strDateTimeMacro = "%today(" & Quote("urn:schemas:httpmail:datereceived") & ")%"
            Case Tomorrow
                strDateTimeMacro = "%tomorrow(" & Quote("urn:schemas:httpmail:datereceived") & ")%"
            Case Yesterday
                strDateTimeMacro = "%yesterday(" & Quote("urn:schemas:httpmail:datereceived") & ")%"
            Case Next7days
                strDateTimeMacro = "%next7days(" & Quote("urn:schemas:httpmail:datereceived") & ")%"
            Case Last7days
                strDateTimeMacro = "%last7days(" & Quote("urn:schemas:httpmail:datereceived") & ")%"
            Case NextWeek
                strDateTimeMacro = "%nextweek(" & Quote("urn:schemas:httpmail:datereceived") & ")%"
            Case ThisWeek
                strDateTimeMacro = "%thisweek(" & Quote("urn:schemas:httpmail:datereceived") & ")%"
            Case LastWeek
                strDateTimeMacro = "%lastweek(" & Quote("urn:schemas:httpmail:datereceived") & ")%"
            Case NextMonth
                strDateTimeMacro = "%nextmonth(" & Quote("urn:schemas:httpmail:datereceived") & ")%"
            Case ThisMonth
                strDateTimeMacro = "%thismonth(" & Quote("urn:schemas:httpmail:datereceived") & ")%"
            Case LastMonth
                strDateTimeMacro = "%lastmonth(" & Quote("urn:schemas:httpmail:datereceived") & ")%"
        End Select
        strFilter = "@SQL=" & strDateTimeMacro & " AND " & Quote(PR_HASATTACH) & "=1 "
    End If
    strFolderPath = Environ$("USERPROFILE") & "\Documents\OutlookAttachments\" 'Thu muc luu tap tin dinh kem, mac dinh: C:\<nguoidung>
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    If Not objFSO.FolderExists(strFolderPath) Then objFSO.CreateFolder strFolderPath
    If Not objFSO.FolderExists(strFolderPath & Format$(Now, "dd-mm-yyyy hh.nn.ss")) Then
        strDateTimeFolder = strFolderPath & Format$(Now, "dd-mm-yyyy hh.nn.ss")
        objFSO.CreateFolder strDateTimeFolder
    Else: strDateTimeFolder = strFolderPath & Format$(Now, "dd-mm-yyyy hh.nn.ss")
    End If
    On Error Resume Next
    Set objFolder = Application.Session.PickFolder
    If Not objFolder Is Nothing And objFolder.DefaultItemType = olMailItem Then
        Set colItems = objFolder.Items.Restrict(strFilter)
        For j = 1 To colItems.Count
            Set objMail = colItems.Item(j)
            With objMail
                For i = 1 To .Attachments.Count
                    Set objAtt = .Attachments.Item(i)
                    Select Case objFSO.GetExtensionName(objAtt.filename)
                        Case "xlsx", "xls", "xlsm", "pdf"
                            If objFSO.FileExists(strDateTimeFolder & "\" & objAtt.filename) Then
                                objFSO.DeleteFile strDateTimeFolder & "\" & objAtt.filename
                            End If
                            objAtt.SaveAsFile strDateTimeFolder & "\" & objAtt.filename
                    End Select
                Next i
            End With
        Next
        Shell "explorer """ & strFolderPath & "", vbNormalFocus
    Else: MsgBox "You must select a folder that contains email items only.", vbExclamation, "Error: Invalid Folder"
    End If
End Sub
Private Function Quote(Text As String) As String
    Quote = Chr(34) & Text & Chr(34)
End FunctionPrivate Sub SaveEmailAttachments()
    Call DownloadAttachments(UseDateTimeMacro:=True, DateTimeMacro:=Today)
End Sub