Search code examples
vbaoutlook

Not all mail items are saved when using subject as file name


I obtained the code from a tutorial online.
I tested it and updated variables specific to my local system.

There is a problem with the export.

Previously, I ran the code successfully.
All 128 items of the Outlook folder were obtained.

There are now 231 items in the Outlook folder.
The code repeatedly only obtains 162.

I can confirm;

  • all items are mail (not meeting or read receipts)
  • the 162 items obtained contains attachments - so it is not a limit on this basis
  • I refreshed and sync'd Outlook exchange with local machine several times.
  • previously, one mail item contained *** in the title. This broke the code, I adapted it as can be seen, and it ran without issue.

I considered

  • mail items are of a type that I have not defined?
  • there is an issue with the titles of the other mail items?
  • this code is limited by memory allocation?
  • the problem is the sync between Outlook exchange and local device
Sub ZipAllEmailsInAFolder()
    Dim objFolder As Outlook.Folder
    Dim objItem As Object
    Dim objMail As Outlook.MailItem
    Dim strSubject As String
    Dim varTempFolder As Variant
    Dim varZipFile As Variant
    Dim objShell As Object
    Dim objFileSystem As Object
   
    'Select an Outlook Folder
    Set objFolder = Outlook.Application.Session.PickFolder
 
    If Not (objFolder Is Nothing) Then
       'Create a temp folder
       varTempFolder = "C:\Users\thomdenm\Music\" & objFolder.Name & Format(Now, "YYMMDDHHMMSS")
       MkDir (varTempFolder)
       varTempFolder = varTempFolder & "\"
   
       'Save each email as msg file
       For Each objItem In objFolder.Items
 
           If TypeOf objItem Is MailItem Then
              Set objMail = objItem
              strSubject = objMail.Subject
              strSubject = Replace(strSubject, "/", " ")
              strSubject = Replace(strSubject, "\", " ")
              strSubject = Replace(strSubject, ":", "")
              strSubject = Replace(strSubject, "?", " ")
              strSubject = Replace(strSubject, Chr(34), " ")
              strSubject = Replace(strSubject, "*", " ")
 
              objMail.SaveAs varTempFolder & strSubject & ".msg", olMSG
           End If
       Next
 
       'Create a new ZIP file
       varZipFile = "C:\Users\thomdenm\Music\" & objFolder.Name & " Emails.zip"
       Open varZipFile For Output As #1
       Print #1, Chr$(80) & Chr$(75) & Chr$(5) & Chr$(6) & String(18, 0)
       Close #1
 
       'Add the exported msg files to the ZIP file
       Set objShell = CreateObject("Shell.Application")
       objShell.NameSpace(varZipFile).CopyHere objShell.NameSpace(varTempFolder).Items

       On Error Resume Next
       Do Until objShell.NameSpace(varZipFile).Items.Count = objShell.NameSpace(varTempFolder).Items.Count
          Application.Wait (Now + TimeValue("0:00:01"))
       Loop
       On Error GoTo 0
 
       'Delete the temp folder
       Set objFileSystem = CreateObject("Scripting.FileSystemObject")
       objFileSystem.DeleteFolder Left(varTempFolder, Len(varTempFolder) - 1)
    End If
End Sub

Solution

  • First of all, I'd remove the condition where you check for the item type or add others to make sure all items are processed. Or just add a counter to see how much items were checked through.

    counter = counter+1
    If TypeOf objItem Is MailItem Then
    

    Second, the On Error statement can help you identify the source of the problem if any error comes in.

    Third, it makes sense to split the logic where you get Outlook items and save them to a folder. The other piece of code can be extracted to a separate method , so following this way you can easily be sure that one or another method works correctly (the Outlook-related part).

    And, finally, the most important thing is that items can belong to the same conversation and have identical subject line which can lead to overwriting saved items in the folder. Is this the case?

    objMail.SaveAs varTempFolder & strSubject & ".msg", olMSG
    

    I'd recommend adding any ID to the file name so you can be sure no items are overwritten in the folder. For example, it can be current time or milliseconds and etc.