VB script code to save a specific email attachment from a given email

Status
Not open for further replies.

VZZ

New Member
Outlook version
Outlook 2016 32 bit
Email Account
Office 365 Exchange
Hi, I'm new to VBA and also this forum. I'm using a simple script code to save email attachments to a Drive folder and name them when they arrive, and activating it within an Outlook rule(run a script), its working fine.......when there is only one attachment in the email. Is there a script modification I can make to save the first attachment only or the fourth attachment only for example if there are multiple attachments in the given email? The code I'm using now cycles through all attachments in a given email and saves the last one, which is not necessarily always the one I need saved-typically its the first one. Thanks for any suggestions
 

Diane Poremsky

Senior Member
Outlook version
Outlook 2016 32 bit
Email Account
Office 365 Exchange
You can save a specific # - in place of the variable (often i), enter the number...
objAttachments.Item(3).SaveAsFile strFile

But if you know either the file name or extension you need saved, it would be better to check that as attachment positions have the potential to change.

if right(objAttachments.Item(i).FileName, 4) = "xlsx" then
objAttachments.Item(i).SaveAsFile strFile
end if
 

VZZ

New Member
Outlook version
Outlook 2016 32 bit
Email Account
Office 365 Exchange
Thank you Diane, appreciate your quick reply. I will try the # after Item; I thought about looking for the file type but I'm running a variation of the rule on multiple emails that come daily from different senders. Some have 2 or 3 xls or xlsx attachments, but I need to always save the first one(the code is naming the file the same name I specified within the code every time and saving over the previous file on my shared drive....but if multiple attachments are present, it doesn't stop after the first one....the last one ends up being the one saved).

If I decided to try looking for the specific file name to save instead of item #, what would that look like?(some of the files will follow the same naming pattern with current date at the end)
Thanks again
 

VZZ

New Member
Outlook version
Outlook 2016 32 bit
Email Account
Office 365 Exchange
Diane, I tried the Item #, but could not get it to work in my below code, could you please show me where I would insert it? Thanks



Code:
Public Sub saveAttachtoDiskRuleNATIONSTARscript(itm As Outlook.MailItem)

Dim objAtt As Outlook.Attachment
Dim saveFolder As String
Dim fso As Object

Dim file As String
Dim DateFormat As String

Dim enviro As String
enviro = CStr(Environ("XXX"))
saveFolder = enviro & "P:\XXX\"


Set fso = CreateObject("Scripting.FileSystemObject")
On Error Resume Next



For Each objAtt In itm.Attachments
file = saveFolder & "NationstarBE.xlsx"
objAtt.SaveAsFile file
   
Set objAtt = Nothing
Next
 
Set fso = Nothing
End Sub
 

VZZ

New Member
Outlook version
Outlook 2016 32 bit
Email Account
Office 365 Exchange
Diane, Looking for further guidance on this one on my last post, appreciated. Thanks
 

noobie

Member
Outlook version
Outlook 2013 32 bit
Email Account
Exchange Server 2013
Code:
Public Sub saveAttachtoDiskRuleNATIONSTARscript(itm As Outlook.MailItem)

Dim objAtt As Outlook.Attachment
Dim saveFolder As String
Dim fso As Object

Dim file As String
Dim DateFormat As String

Dim enviro As String
enviro = CStr(Environ("XXX"))
saveFolder = enviro & "P:\XXX\"


Set fso = CreateObject("Scripting.FileSystemObject")
On Error Resume Next



For Each objAtt In itm.Attachments
file = saveFolder & "NationstarBE.xlsx"
objAtt.SaveAsFile file
  
Set objAtt = Nothing
Next
 
Set fso = Nothing
End Sub
Hey, you will need to put the "Set objAtt = Nothing" out of the For-Loop. Put it a line before the "Set fso = Nothing"

Cheers,

noobie
 

VZZ

New Member
Outlook version
Outlook 2016 32 bit
Email Account
Office 365 Exchange
Thank you for the suggestion, however it didn't seem to do anything different. It still didn't stop after the first attachment and ended up saving the 3rd attachment out of 3.
 

noobie

Member
Outlook version
Outlook 2013 32 bit
Email Account
Exchange Server 2013
Thank you for the suggestion, however it didn't seem to do anything different. It still didn't stop after the first attachment and ended up saving the 3rd attachment out of 3.
Okay, but that's what Diane already suggested. You will need to specify the number. Also, it may be a tad little bit more complicated than you imagined, but let's try:

The (untested) code that I provide should loop through all the attachments of the MailItem and save the first Excel file it finds.

Code:
Public Sub saveAttachtoDiskRuleNATIONSTARscript(itm As Outlook.MailItem)

Dim objAtt As Outlook.Attachment
Dim saveFolder As String
Dim file As String
Dim DateFormat As String
Dim enviro As String
Dim oAttachment As Object
Dim i As Long

On Error Resume Next
enviro = CStr(Environ("XXX"))
saveFolder = enviro & "P:\XXX\"

For i = 1 To itm.Attachments.Count
   Set objAtt = itm.Attachments(i)
 
   If Right(objAtt.FileName, 4) = "xlsx" Or Right(objAtt.FileName, 3) = "xls" Then
     file = saveFolder & "NationstarBE.xlsx"
     objAtt.SaveAsFile file
   
     Exit Sub 'or simply write "End"

  End If

  Set objAtt = Nothing 'here, you will need to put the "Set objAtt = Nothing" within the loop.
 
Next i

End Sub
 

noobie

Member
Outlook version
Outlook 2013 32 bit
Email Account
Exchange Server 2013
Okay, okay, I should note that the End statement will end any procedures :D
So Exit Sub will be the statement you need :)
 

VZZ

New Member
Outlook version
Outlook 2016 32 bit
Email Account
Office 365 Exchange
Okay, okay, I should note that the End statement will end any procedures :D
So Exit Sub will be the statement you need :)
Just tested and that worked! Thank you for your help. So, if I wanted to tell it to save excel file item # 3 of 3 attachments for example, I would need to insert 3.......Set objAtt = itm.Attachments(3)?
Thanks again your help is much appreciated.
 

noobie

Member
Outlook version
Outlook 2013 32 bit
Email Account
Exchange Server 2013
Just tested and that worked! Thank you for your help. So, if I wanted to tell it to save excel file item # 3 of 3 attachments for example, I would need to insert 3.......Set objAtt = itm.Attachments(3)?
Thanks again your help is much appreciated.
It's not always that easy to grab a specific attachment.

Example: the MailItem does have 3 Excel files attached and one screenshot embedded. Now you have 4 attachments in total. And if Outlook does not get the order right, it may be that the screenshot is exactly the attachment #3. Sometimes, you even have attachments that are not visible within the MailItem, but hidden. I had to work trough such stuff myself, and it can be quite frustrating.

Now you have several options:

1) if you're sure that the MailItems do only have Excel files attached, then you can simply skip the For loop and grab attachment #3 (if there are at least 3 Excel files attached; you can check the attachment number with itm.Attachments.Count).

2) if it is not about the 3rd Excel file, but rather the last Excel file to be found, you can rewrite the loop:
For i = 1 To itm.Attachments.Count => For i = itm.Attachments.Count To 1 Step -1 will process it backwards.

3) if it is indeed about the 3rd Excel file, and you also have other attachments within the MailItem, then you will first have to filter for Excel files (i.e. to build an array where you e.g. store the Excel files' file names), and then grab the 3rd argument of the array (or rather the argument #2, as arrays start with 0).

To build a macro for option 3) can be a bit time-consuming, and I don't have a sample code for Outlook that I could provide.
 

noobie

Member
Outlook version
Outlook 2013 32 bit
Email Account
Exchange Server 2013
Okay, I tried to create such an array. I initially tried to store the attachments themselves within the array, and then just I would just have had to write 'a(2).SaveAsFile file', but that did not work. Hence I had to create some workaround:

1) Move through all attachments and store the file names in the array if the files are Excel files.
2) Get back the third array value as a string (but it is always a(2)='array value #3', as arrays start at 0).
3) Move through all attachments again and check for the file name, and then save as file.

Maybe @Diane Poremsky has a better idea, though :)

Code:
Public Sub saveAttachtoDiskRuleNATIONSTARscript(itm As Outlook.MailItem)

Dim objAtt As Outlook.Attachment
Dim saveFolder As String
Dim file As String
Dim enviro As String
Dim i As Long
Dim j As Long
Dim a As Variant
Dim chobjAtt As String

On Error Resume Next

Set selItems = Application.ActiveExplorer.Selection

enviro = CStr(Environ("XXX"))
saveFolder = enviro & "P:\XXX\"

file = saveFolder & "NationstarBE.xlsx"

For i = 1 To itm.Attachments.Count
 
    Set objAtt = itm.Attachments(i)
 
            If Right(objAtt.fileName, 4) = "xlsx" Or Right(objAtt.fileName, 3) = "xls" Then
             
                If IsEmpty(a) Then
 
                    a = Array(objAtt.fileName)
 
                Else
             
                    ReDim Preserve a(UBound(a) + 1)
                    a(UBound(a)) = objAtt.fileName
 
                End If
 
            End If
          
Next i

chobjAtt = a(2)

For j = 1 To itm.Attachments.Count

    Set objAtt = itm.Attachments(j)
 
        If objAtt.fileName = chobjAtt Then
     
            objAtt.SaveAsFile file
     
        End If

Next j

End Sub
 

noobie

Member
Outlook version
Outlook 2013 32 bit
Email Account
Exchange Server 2013
Oh, and I guess you can end the second for loop (with the j's) once you have found the specific attachment; efficiency :D

If objAtt.fileName = chobjAtt Then

objAtt.SaveAsFile file
Exit Sub

End If

It may be problematic when you have several Excel files with exactly the same file name, but well, let's first try it with this one ;)
 

VZZ

New Member
Outlook version
Outlook 2016 32 bit
Email Account
Office 365 Exchange
Oh, and I guess you can end the second for loop (with the j's) once you have found the specific attachment; efficiency :D

If objAtt.fileName = chobjAtt Then

objAtt.SaveAsFile file
Exit Sub

End If

It may be problematic when you have several Excel files with exactly the same file name, but well, let's first try it with this one ;)
Wow thank you for spending the extra time and n this, I'll play around with it.
 

noobie

Member
Outlook version
Outlook 2013 32 bit
Email Account
Exchange Server 2013
You're welcome :)
Just tell me if there are any problems.
 
Status
Not open for further replies.
Top