Quản lý email outlook qua VBA cần giúp đỡ (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

Tôi tuân thủ nội quy khi đăng bài

dohungmo

Thành viên mới
Tham gia
4/4/13
Bài viết
41
Được thích
1
Nhờ anh/chị hỗ trợ viết giúp em một file VBA có thể tích hợp với Outlook để hỗ trợ quản lý email hàng ngày một cách thuận tiện hơn. Cụ thể, em cần file này thực hiện được các chức năng sau:
  1. Hiển thị địa chỉ email của người gửi.
  2. Hiển thị tiêu đề email (Subject).
  3. Hiển thị đường link dẫn trực tiếp đến email trong Outlook.
  4. Hiển thị tên tệp đính kèm (nếu có).
  5. Hiển thị ngày và giờ nhận email.
  6. Có nút “Refresh” để cập nhật danh sách email mới.
  7. Cập nhật email theo kiểu tích lũy:
    • Ví dụ: nếu bắt đầu sử dụng file từ ngày 01/05/2024, thì file chỉ cập nhật các email nhận sau ngày này, và không lấy các email trước thời điểm đó.
    • Mỗi lần nhấn “Refresh”, danh sách email mới sẽ được bổ sung thêm vào file, không làm mất các email đã được lưu trước đó.
Em cảm ơn.
 

File đính kèm

Lần chỉnh sửa cuối:
Giải pháp
Nhờ anh/chị hỗ trợ viết giúp em một file VBA có thể tích hợp với Outlook để hỗ trợ quản lý email hàng ngày một cách thuận tiện hơn. Cụ thể, em cần file này thực hiện được các chức năng sau:
  1. Hiển thị địa chỉ email của người gửi.
  2. Hiển thị tiêu đề email (Subject).
  3. Hiển thị đường link dẫn trực tiếp đến email trong Outlook.
  4. Hiển thị tên tệp đính kèm (nếu có).
  5. Hiển thị ngày và giờ nhận email.
  6. Có nút “Refresh” để cập nhật danh sách email mới.
  7. Cập nhật email theo kiểu tích lũy:
    • Ví dụ: nếu bắt đầu sử dụng file từ ngày 01/05/2024, thì file chỉ cập nhật các email nhận sau ngày này, và không lấy các email trước thời điểm đó.
    • Mỗi lần nhấn “Refresh”, danh sách email mới sẽ được bổ sung thêm vào file, không làm...
Bác ơi , giờ em mơi phát hiện ra , nó chỉ quét trong inbox thôi . Còn trong subfolder thì nó không quét nên mới có tình trạng này. Việc này xử lý thế nào bác.
Lần này dùng phương thức AdvancedSearch là chuẩn nhất, cho phép quét hết thư mục con nằm trong thư mục mẹ được chọn. Tuy chậm và triển khai phức tạp hơn so với những phương thức tìm kiếm khác như Folder.GetTable, Folder.Items.Find hay Folder.Items.Restrict, nhưng nó vẫn nhanh hơn so với việc tìm chay bằng tay (duyệt tất cả item trong thư mục trong vòng lặp).
Mã:
Option Explicit

Public SearchComplete As Boolean

Public Sub ListMails()
    SearchComplete = False
    Dim objSh As Excel.Worksheet
    On Error Resume Next
    Set objSh = Sheet1
    If Err.Number <> 0 Then
        Call MsgBox("The required worksheet 'Sheet1' was not found.", vbExclamation, "Error: Worksheet Not Found")
        Exit Sub
    End If
    On Error GoTo 0
    Dim dblTimeOut As Double
    dblTimeOut = objSh.Range("C3").Value2
    If dblTimeOut <= 0 Then
        Call MsgBox("Invalid timeout", vbExclamation, "Error")
        Exit Sub
    End If
    Dim objOlApp As Outlook.Application
    On Error Resume Next
    Set objOlApp = GetObject(, "Outlook.Application")
    If Err.Number = 429 Then
        Call MsgBox("This macro requires a running instance of Outlook. Please try again later!", vbExclamation, "Error: Outlook Not Running")
        Exit Sub
    End If
    On Error GoTo 0
    Dim objFld As Outlook.Folder
    Set objFld = objOlApp.Session.PickFolder
    If objFld Is Nothing Then
        Call MsgBox("Please select a folder to continue", vbExclamation, "Error: Folder Not Specified")
        Exit Sub
    End If
    objSh.Range("C1").Value2 = objFld.FolderPath
    Dim dteDate As Date
    dteDate = CDate(objSh.Range("C2").Value2)
    Dim colItems As Collection
    Set colItems = GetMailsByDateUsingAdvancedSearch(objOlApp, objFld, dteDate, dblTimeOut)
    If colItems.Count = 0 Then
        Call MsgBox("No mail item was found that matched the criteria 'after " & CStr(dteDate) & "'", vbInformation, "Search Result")
        Exit Sub
    End If
    Dim lngLastRow As Long, lngRowsCount As Long
    lngRowsCount = objSh.Rows.Count
    lngLastRow = objSh.Cells(lngRowsCount, 1).End(xlUp).Row
    If lngLastRow > 5 Then objSh.Range("A5:G" & CStr(lngLastRow)).ClearContents
    Dim arrResult As Variant, i As Long, j As Long, objResult As MailInfo, strAttFileNames As String
    ReDim arrResult(1 To colItems.Count, 1 To 7) As Variant
    For i = 1 To colItems.Count
        arrResult(i, 1) = i
        Set objResult = colItems.Item(i)
        arrResult(i, 2) = objResult.SenderEmailAddress
        arrResult(i, 3) = objResult.Subject
        If objResult.HasAttachments Then
            For j = 1 To objResult.Attachments.Count
                If j = objResult.Attachments.Count Then
                    strAttFileNames = strAttFileNames & objResult.Attachments.Item(j)
                Else: strAttFileNames = strAttFileNames & objResult.Attachments.Item(j) & ", "
                End If
            Next
            arrResult(i, 4) = strAttFileNames
        End If
        arrResult(i, 5) = objResult.EntryId
        arrResult(i, 6) = objResult.ReceivedTime
    Next
    objSh.Range("A5").Resize(UBound(arrResult), UBound(arrResult, 2)).Value2 = arrResult
    lngLastRow = objSh.Cells(lngRowsCount, 1).End(xlUp).Row
    Dim objCell As Excel.Range, objLinkRange As Excel.Range
    Set objLinkRange = objSh.Range("E5:E" & CStr(lngLastRow))
    For Each objCell In objLinkRange
        objSh.Hyperlinks.Add objCell, "", objCell.Value2, "Open Mail", "Click here to open mail from Outlook"
    Next
End Sub

Private Function GetMailsByDateUsingAdvancedSearch(ByVal OlApp As Outlook.Application, ByVal Fld As Outlook.Folder, ByVal DateVal As Date, ByVal TimeOut As Double) As Collection
    If OlApp Is Nothing Or Fld Is Nothing Then Exit Function
    Dim objMail As Outlook.MailItem
    Dim dteDate As Date, objPA As Outlook.PropertyAccessor
    Set objMail = OlApp.CreateItem(olMailItem)
    Set objPA = objMail.PropertyAccessor
    dteDate = objPA.LocalTimeToUTC(DateVal)
    objMail.Close olDiscard
    Dim strFilter As String
    strFilter = Quote("urn:schemas:httpmail:datereceived") & " >= " & SingleQuote(dteDate)
    Dim objSearch As Outlook.Search, colResults As Collection
    Set colResults = New Collection
    Set objSearch = OlApp.AdvancedSearch(SingleQuote(Fld.FolderPath), strFilter, True, "SearchAllMailItems")
    Dim dteCurrentTime As Date, dteStartTime As Date
    dteStartTime = Now
    While SearchComplete = False
        DoEvents
        dteCurrentTime = Now
        If DateDiff("s", dteStartTime, dteCurrentTime, vbMonday, vbFirstJan1) >= TimeOut Then
            Set GetMailsByDateUsingAdvancedSearch = colResults
            Exit Function
        End If
    Wend
    Dim objAtt As Outlook.Attachment, objMailInfo As MailInfo, objItem As Object, i As Long
    Dim objResults As Outlook.Results
    Set objResults = objSearch.Results
    If objResults.Count > 0 Then
        For i = 1 To objResults.Count
            Set objItem = objResults.Item(i)
            If TypeOf objItem Is Outlook.MailItem Then
                Set objMail = objItem
                Set objMailInfo = New MailInfo
                With objMailInfo
                    .Subject = objMail.Subject
                    .SenderEmailAddress = objMail.SenderEmailAddress
                    .ReceivedTime = objMail.ReceivedTime
                    If objMail.Attachments.Count > 0 Then
                        .HasAttachments = True
                        For Each objAtt In objMail.Attachments
                            .Attachments.Add objAtt.Filename
                        Next
                    End If
                    .EntryId = objMail.EntryId
                    objMail.Close olDiscard
                End With
                colResults.Add objMailInfo
            End If
        Next
    End If
    Set GetMailsByDateUsingAdvancedSearch = colResults
End Function

Private Function Quote(ByVal Text As String) As String
    Quote = Chr(34) & Text & Chr(34)
End Function

Private Function SingleQuote(ByVal Text As String) As String
    SingleQuote = Chr(39) & Text & Chr(39)
End Function

Lưu ý: Phải mở sẵn Outlook trước khi mở tệp chứa macro.
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom