I'm trying to extract an Excel report from an Outlook email, and save it in a folder called "OLAttachments" in my Documents folder.
I also need it to overwrite the previous day's file. These email attachments have the same name each day.
This is what I have so far. Each time the email comes through, it saves a new file, whereas I would like to overwrite the existing file.
Public Sub SaveAttachmentsToDisk(MItem As Outlook.MailItem)
Dim oAttachment As Outlook.Attachment
Dim sSaveFolder As String
sSaveFolder = "C:\Users\fmustapha\Documents\Outlook Attachments"
For Each oAttachment In MItem.Attachments
oAttachment.SaveAsFile sSaveFolder & oAttachment.DisplayName
Next
End Sub
I do this on my server, I receive an email each night that has an Excel file attached, that auto forwards to my server where this outlook code saves off the attachment. Note there is a clause in there to make sure the file comes from me and to make sure it's an Excel file:
Private WithEvents olItems As Outlook.Items
Private Sub Application_Startup()
Dim objNS As Outlook.NameSpace
Set objNS = GetNamespace("MAPI")
Set olItems = objNS.GetDefaultFolder(olFolderInbox).Items
Set objNS = Nothing
End Sub
Private Sub olItems_ItemAdd(ByVal Item As Object)
Dim NewMail As Outlook.MailItem
Dim Atts As Attachments
Dim Att As Attachment
Dim strPath As String
Dim strName As String
If Item.Class = olMail Then
Set NewMail = Item
End If
strPath = "C:\Reporting Archive\Sales Files\"
If NewMail.Sender = "Dan Donoghue" Then
Set Atts = Item.Attachments
If Atts.Count > 0 Then
For Each Att In Atts
If InStr(LCase(Att.FileName), ".xls") > 0 Then Att.SaveAsFile strPath & Att.FileName
Next
End If
End If
End Sub
It goes in ThisOutlookSession in the VBE, once you have put it in close and reopen outlook and it will work.
To save over the top I would recommend you delete the existing file first (you can use the kill command for this then simply save the new one).
You would do that by replacing this:
If InStr(LCase(Att.FileName), ".xls") > 0 Then Att.SaveAsFile strPath & Att.FileName
with this:
If InStr(LCase(Att.FileName), ".xls") > 0 Then
Kill strPath & Att.FileName
Att.SaveAsFile strPath & Att.FileName
End If
in my code
You can setup a rule that triggers this job in any frequency you want (you probably don't want the rule to run in seconds, but more like 1x per day, overnight, etc.)
Public Sub SaveAttachmentsToDisk(MItem As Outlook.MailItem)
Dim oAttachment As Outlook.Attachment
Dim sSaveFolder As String
sSaveFolder = "C:\Users\DT168\Documents\outlook-attachments\"
For Each oAttachment In MItem.Attachments
oAttachment.SaveAsFile sSaveFolder & oAttachment.DisplayName
Next
End Sub
https://www.extendoffice.com/documents/outlook/3747-outlook-auto-download-save-attachments-to-folder.html#a1
Try using Date function Which Returns a Variant (Date) containing the current system date. MSDN
Example
oAttachment.SaveAsFile sSaveFolder & "New Members" & " " & Format(Date - 1, "MM-DD-YYYY")
Related
The intent is to use a rule to trigger a script that saves the attached files of an email if the created date is equal to today. Next, the script would delete all items from the folder that do not have the same created date.
I can run the code, but it doesn't do anything.
Public Sub SaveAttachments(MItem As Outlook.MailItem)
Dim oAttachment As Outlook.Attachment
Dim sSaveFolder As String
Dim today As Date 'today's date
Dim adate As Date 'date of attachment
today = Date
sSaveFolder = "filepath"
For Each oAttachment In MItem.Attachments
adate = oAttachment.DateCreated
If DateDiff("d", today, adate) = 0 Then
oAttachment.SaveAsFile sSaveFolder & oAttachment.DisplayName
End If
Next oAttachment
Dim objFSO, objFolder, objfile As Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(sSaveFolder)
For Each objfile In objFolder.files
If Format(objfile.DateCreated, "DD-MM-YYYY") <> Format(Date, "DD-MM-YYYY") Then
Kill objfile
End If
Next objfile
End Sub
I figured it out.
Public Sub SaveAttachmentsToDisk(MItem As Outlook.MailItem)
Dim oAttachment As Outlook.Attachment
Dim sSaveFolder As String
Dim keepfile As String
sSaveFolder = "filepath"
For Each oAttachment In MItem.Attachments
sdate = MItem.SentOn
If Format(sdate, "DD-MM-YYYY") = Format(Date, "DD-MM-YYYY") Then
oAttachment.SaveAsFile sSaveFolder & oAttachment.DisplayName
keepfile = oAttachment.DisplayName
End If
Next oAttachment
Dim objFSO, objFolder, objfile As Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(sSaveFolder)
For Each objfile In objFolder.files
If InStr(objfile.Name, keepfile) = 0 Then
Kill objfile
End If
Next objfile
End Sub
The Attachment class from the Outlook object model doesn't provide the DateCreated property.
I'm completely new to VB and I'm trying to extract the attachment which is saved available inside the .msg file using the below code.
Could someone help me if this is the right approach to do this ?
I'm facing below compiler errors. Could someone help me how to resolve this issue ?
Outlook.Attachment is not defined.
End Sub' must be preceded by a matching 'Sub'
Reference to a non-shared member requires an object reference.
Statement cannot appear within a method body. End of method assumed
Method arguments must be enclosed in parentheses.
Type 'Outlook.MailItem' is not defined.
Sub SaveOlAttachments()
Dim msg As Outlook.MailItem
Dim att As Outlook.Attachment
Dim strFilePath As String
Dim strAttPath As String
Dim strFile As String
strFilePath = "C:\Users\...\Desktop\Test\"
strAttPath = "C:\Users\...\extracted attachment\"
strFile = Dir(strFilePath & "<Doc Name>.msg")
Do While Len(strFile) > 0
msg = Application.CreateItemFromTemplate(strFilePath & strFile)
If msg.Attachments.Count > 0 Then
For Each att In msg.Attachments
att.SaveAsFile strAttPath & att.FileName
Next
End If
strFile = Dir
Loop
End Sub
First of all, check out the file path where you try to find the template:
msg = Application.CreateItemFromTemplate(strFilePath & strFile)
The strFilePath string may include the file name already:
strFile = Dir(strFilePath & "<Doc Name>.msg")
Second, make sure attachments are saved using unique file names:
att.SaveAsFile strAttPath & att.FileName
The FileName string can be the same in different emails. I'd recommend adding IDs or the current time and etc. to the file name to uniquely name attached files on the disk.
Here is the code we use to grab a daily report attachment. I left a few commented statements in case you might need them (we didn't).
Sub Extract_Outlook_Email_Attachments()
On Error GoTo ErrHandler
Dim OutlookApp As Outlook.Application
Dim OutlookNamespace As Namespace
Dim folder As MAPIFolder
Dim OutlookMail As Variant
Dim i As Integer
Dim olNS As Outlook.Namespace
Dim objOwner As Outlook.Recipient
Set OutlookApp = New Outlook.Application
Set OutlookNamespace = OutlookApp.GetNamespace("MAPI")
Dim saveFolder As String
saveFolder = strAttPath ' SAVE THE ATTACHMENT TO
'this bit is added to get a shared email
Set objOwner = OutlookNamespace.CreateRecipient("SHARED FOLDER NAME")
objOwner.Resolve
If objOwner.Resolved Then
Debug.Print "Outlook GB Fulfillment is good."
Set folder = OutlookNamespace.GetSharedDefaultFolder(objOwner, olFolderInbox) 'can use olFolderInbox or olFolderSentMail
End If
'Write mail to spreadsheet - create named range, from and to dates on the spreadsheet
i = 1
For Each OutlookMail In folder.Items
' Debug.Print "SenderEmailAddress: " & OutlookMail.SenderEmailAddress
'If OutlookMail.SenderEmailAddress = "no-reply#OurCompany.com" Then
If OutlookMail.subject = "Daily Report" Then
' If OutlookMail.SenderName = "no-reply#OurCompany.com" And OutlookMail.Subject = "Daily New Subscriber Plan Election Fulfillment" And OutlookMail.Attachments(1) = "NewSubscriberPlanElectionFulfillment_Subscription.xls" Then
Debug.Print "Received: " & OutlookMail.ReceivedTime
Debug.Print "Attach: " & OutlookMail.Attachments(1)
dateformat = Format(OutlookMail.ReceivedTime, "m-d-yy")
Debug.Print dateformat
FName = dateformat & " " & OutlookMail.Attachments(1).fileName
Debug.Print "FName: " & FName
Dim strFileExists As String
strFileExists = Dir(saveFolder & FName)
If strFileExists = "" Then
' MsgBox "The selected file doesn't exist"
Else
' MsgBox "The selected file exists"
Exit Sub
End If
OutlookMail.Attachments(1).SaveAsFile saveFolder & FName
Set outAttachment = Nothing
End If
Next OutlookMail
Set folder = Nothing
Set OutlookNamespace = Nothing
Set OutlookApp = Nothing
ErrHandler:
Debug.Print Err.Description
End Sub
Instead of using CreateItemFromTemplate, you can use Namespace.OpenSharedItem to open an MSG file.
You also need to add Outlook to your VB.Net project references.
An Outlook rule executes code every time an e-mail from a certain sender is received. It would automatically extract the PDF attachment from e-mails and put them into a specified folder.
We've been using it for a good 9 months.
From around 10/22 it crashes on the line For Each oAttachment In MItem.Attachments with Error 424 Object Required. in the DAKSave portion.
I have tried changing the folder to a local folder, same error. This error also occurs on different computers when I try using the code (including a computer which WAS able to use that specific code previously).
I have enabled EnableUnsafeClientMailRules in regedit.
Why isn't it working? Why was it working until now?
Public Sub SaveAttachmentsToDisk(MItem As Outlook.MailItem)
Dim oAttachment As Outlook.Attachment
Dim sSaveFolder As String
sSaveFolder = "S:\Fax\FAX AUTODUMP\"
For Each oAttachment In MItem.Attachments
oAttachment.SaveAsFile sSaveFolder & oAttachment.DisplayName
Next
End Sub
Sub DAKSave()
Dim oAttachment As Outlook.Attachment
Dim sSaveFolder As String
sSaveFolder = "S:\Fax\FAX AUTODUMP\"
For Each oAttachment In MItem.Attachments
oAttachment.SaveAsFile sSaveFolder & oAttachment.DisplayName
Next
End Sub
I'm open to suggestions that would accomplish the same automated task.
Your missing mail Item object, so try to work with ActiveExplorer.Selection.Item(1)
Option Explicit
Sub DAKSave()
Dim sSaveFolder As String
sSaveFolder = "S:\Fax\FAX AUTODUMP\"
Dim MItem As Outlook.MailItem
Set MItem = ActiveExplorer.Selection.Item(1)
Dim oAttachment As Outlook.attachment
For Each oAttachment In MItem.Attachments
oAttachment.SaveAsFile sSaveFolder & oAttachment.DisplayName
Next
End Sub
MItem is not passed as a parameter to the DAKSave sub. MItem is undefined in DAKSave. It is only available in the SaveAttachmentsToDisk sub.
I'm trying to create a macro to download attachments from email I recieve and THEN delete the email.
I've got the macro to download the attachment, however, I don't know how to make it delete the email AFTER it downloads. When I use a rule, it deletes the email BEFORE downloading the attachment.
Here's what I've got:
Public Sub SaveAttachmentsToDisk(MItem As Outlook.MailItem)
Dim oAttachment As Outlook.Attachment
Dim sSaveFolder As String
sSaveFolder = "S:\Training and Curriculum\Staff Training Files\01 scans\"
For Each oAttachment In MItem.Attachments
oAttachment.SaveAsFile sSaveFolder & oAttachment.DisplayName
Next
End Sub
From what I can tell on that sub, you are passing MItem as the Outlook.MailItem object, which if I read your question correctly, is the item you want deleted. After your next in your loop, you should just be able to do MItem.Delete, which will delete that particular item after saving the file.
Public Sub SaveAttachmentsToDisk(MItem As Outlook.MailItem)
Dim oAttachment As Outlook.Attachment
Dim sSaveFolder As String
sSaveFolder = "S:\Training and Curriculum\Staff Training Files\01 scans\"
For Each oAttachment In MItem.Attachments
oAttachment.SaveAsFile sSaveFolder & oAttachment.DisplayName
Next
MItem.Delete 'This is the delete command
End Sub
Here is the MSDN documentation on MailItem.Delete - MSDN MailItem Delete Method
Below is the script to download an attachment from mails in Outlook.
Public Sub SaveAttachmentsToDisk(MItem As Outlook.MailItem)
Dim oAttachment As Outlook.Attachment
Dim sSaveFolder As String
Dim dateFormat
dateFormat = Format(Now, "yyyy-mm-dd")
sSaveFolder = "c:\My\temp\"
For Each oAttachment In MItem.Attachments
oAttachment.SaveAsFile sSaveFolder & oAttachment.DisplayName
Next
End Sub
It downloads and stores in the path which is mentioned in my code only when attachment has different name.
For example, I received mail with attachment as 'List.csv'. With same name I received mail around 10 times.
But only one file (most recent one) got saved in the path.
Final code which works for me.
Public Sub saveAttachtoDisk(itm As Outlook.MailItem)
Dim objAtt As Outlook.Attachment
Dim saveFolder As String
Dim dt30daysAgo As Date
dt30daysAgo = DateAdd("d", -30, Now)
saveFolder = "c:\My\temp"
For Each objAtt In itm.Attachments
If itm.ReceivedTime > dt30daysAgo Then
If objAtt.FileName <> "list.csv" Then
objAtt.SaveAsFile saveFolder & "\" & objAtt.FileName
Else
objAtt.SaveAsFile saveFolder & "\" & itm.Subject & objAtt.FileName
End If
End If
Next
End Sub
You are just overwritting any existing file having the same name.
A very simple solution is to append the current date/time to the file name prior to save it.
To download attachments from the last 30 days only, add a check at the beginning of the procedure to compare the Mail's ReceivedTime with the date 30 days ago, and exit the procedure if received time is lower.
Public Sub SaveAttachmentsToDisk(MItem As Outlook.MailItem)
Dim oAttachment As Outlook.Attachment
Dim sSaveFolder As String
Dim dt30daysAgo As Date
dt30daysAgo = DateAdd("d", 30, Now)
If MItem.ReceivedTime < dt30daysAgo Then Exit Sub
sSaveFolder = "c:\My\temp\"
For Each oAttachment In MItem.Attachments
oAttachment.SaveAsFile sSaveFolder & Format(Now, "YYYY-MM-DD_hh-nn-ss") & oAttachment.DisplayName
Next
End Sub
But the check on ReceivedTime is not well placed, you should ideally do this this on the calling procedure.