I need to build a rule script that saves an outlook attachment (excel specific) to a the user's hard drive. I then need to add a password to this excel attachment and then forward it.
Saving and forwarding emails/attachments is simple enough using the VBA Outlook developer tools (see below). However, I am running into issues with adding a password to this attachment. Is this possible or do I need an outside script/program to do this task? Furthermore, do you have any other suggestions?
Public Sub saveAttachtoDisk(itm As Outlook.MailItem)
Dim objAtt As Outlook.Attachment
Dim saveFolder As String
saveFolder = "c:\"
For Each objAtt In itm.Attachments
objAtt.SaveAsFile saveFolder & "\" & objAtt.DisplayName
Set objAtt = Nothing
Next
Call SendEmail
End Sub
Public Sub SendEmail()
Dim olApp As Outlook.Application
Dim olMail As Outlook.MailItem
Dim blRunning As Boolean
'get application
blRunning = True
On Error Resume Next
Set olApp = GetObject(, "Outlook.Application")
If olApp Is Nothing Then
Set olApp = New Outlook.Application
blRunning = False
End If
On Error GoTo 0
Set olMail = olApp.CreateItem(olMailItem)
With olMail
.Subject = "My email with attachment"
.Recipients.Add "jlanz#mmyemail.com"
.Attachments.Add "C:\test123.xlsx"
.Body = "Here is an email"
.Send
End With
If Not blRunning Then olApp.Quit
Set olApp = Nothing
Set olMail = Nothing
End Sub
As per my comment you need to add a reference to the excel library. Then you can set a password using the example below.
Sub ProtectExcelWorkbook(filePath As String)
Dim pw As String
pw = "password"
Dim eApp As Excel.Application
Dim eBook As Excel.Workbook
Set eApp = New Excel.Application
Set eBook = eApp.Workbooks.Open(filePath)
eBook.Password = pw
eBook.Save
Set eBook = Nothing
eApp.Quit
Set eApp = Nothing
End Sub
Public Sub saveAttachtoDisk(itm As Outlook.MailItem)
Dim objAtt As Outlook.Attachment
Dim saveFolder As String
saveFolder = "c:\"
For Each objAtt In itm.Attachments
objAtt.SaveAsFile saveFolder & "\" & objAtt.DisplayName
ProtectExcelWorkbook saveFolder & "\" & objAtt.DisplayName
Set objAtt = Nothing
Next
Call SendEmail
End Sub
Related
Good afternoon,
I am trying to find a way to realize the following project:
When I receive an email with attachments and with a certain word in the subject, create a folder and download the attachments to that folder.
But so far I only got an error '424' - Object required on the line:
If TypeName(olMail) = "Mailterm" And myMail.Subject Like "*" & "prueba" & "*" And olMail.Attachments.Count > 0 Then
If I remove the part:
And myMail.Subject Like "*" & "prueba" & "*"
And run again that error disappears, however I get an error:
Run-time erro '13':
Type mismatch
Highlighting:
Next olMail
I am not an expert on VBA but if you could help me it would be appreciated.
Option Explicit
Sub Download_Attachments()
Dim ns As NameSpace
Dim olFolder_Inbox As Folder
Dim olMail As Object
Dim olAttachment As Attachment
Dim fso As Object
Dim File_Saved_Folder_Path As String
Dim sFolderName As String
sFolderName = Format(Now, "yyyyMMdd")
File_Saved_Folder_Path = "C:\Users\agonzalezp\Documents\prueba" & "\" & sFolderName
Set ns = GetNamespace("MAPI")
Set olFolder_Inbox = ns.GetDefaultFolder(olFolderInbox)
Set fso = CreateObject("Scripting.FileSystemObject")
For Each olMail In olFolder_Inbox.Items
If TypeName(olMail) = "MailItem" Then
If olMail.Subject Like "*" & "prueba" & "*" Then 'And olMail.Attachments.Count > 0
fso.CreateFolder (File_Saved_Folder_Path)
For Each olAttachment In olMail.Attachments
Select Case UCase(fso.GetExtensionName(olAttachment.FileName))
Case "XLSX", "XLSM"
olAttachment.SaveAsFile (File_Saved_Folder_Path)
End Select
Next olAttachment
End If
End If
Next olMail
Set olFolder_Inbox = Nothing
Set ns = Nothing
Set fso = Nothing
End Sub
Thanks to all of you for your collaboration and help.
Finally the code has been working as follows:
Public Sub Download_Attachments()
'If execute in excel, for sample.
'ADD 'Tools > References... Microsoft Outlook 16.0 Object Library
On Error GoTo Err_Control
Dim OutlookOpened As Boolean
Dim outApp As Outlook.Application
Dim outNs As Outlook.Namespace
Dim outFolder As Outlook.MAPIFolder
Dim outAttachment As Outlook.Attachment
Dim outItem As Object
Dim DestinationFolderName As String
Dim saveFolder As String
Dim outMailItem As Outlook.MailItem
Dim inputDate As String, subjectFilter As String, sFolderName As String
Dim FSO As Object
Dim SourceFileName As String, DestinFileName As String
Set FSO = CreateObject("Scripting.FileSystemObject")
Set FSO = CreateObject("Scripting.Filesystemobject")
sFolderName = Format(Now, "yyyyMMdd")
sMailName = Format(Now, "dd/MM/yyyy")
DestinationFolderName = "C:\Users\agonzalezp\Documents\Automatizaciones"
saveFolder = DestinationFolderName & "\" & sFolderName
subjectFilter = "NUEVA" & " " & sMailName 'REPLACE WORD SUBJECT TO FIND
OutlookOpened = False
On Error Resume Next
Set outApp = GetObject(, "Outlook.Application")
If Err.Number <> 0 Then
Set outApp = New Outlook.Application
OutlookOpened = True
End If
On Error GoTo Err_Control
If outApp Is Nothing Then
MsgBox "Cannot start Outlook.", vbExclamation
Exit Sub
End If
Set outNs = outApp.GetNamespace("MAPI")
Set outFolder = outNs.GetDefaultFolder(olFolderInbox)
If Not outFolder Is Nothing Then
For Each outItem In outFolder.Items
If outItem.Class = Outlook.OlObjectClass.olMail Then
Set outMailItem = outItem
If InStr(1, outMailItem.Subject, subjectFilter) > 0 Then 'removed the quotes around subjectFilter
For Each outAttachment In outMailItem.Attachments
If Dir(saveFolder, vbDirectory) = "" Then FSO.CreateFolder (saveFolder)
outAttachment.SaveAsFile saveFolder & " - " & outAttachment.fileName
Set outAttachment = Nothing
Next
End If
End If
Next
End If
SourceFileName = "C:\Users\agonzalezp\Documents\Automatizaciones\*.xlsx"
DestinFileName = saveFolder
FSO.MoveFile SourceFileName, DestinFileName
If OutlookOpened Then outApp.Quit
Set outApp = Nothing
Err_Control:
If Err.Number <> 0 Then
'MsgBox Err.Description
End If
End Sub
God afternow, Alejandro,
Try this, for me work, i try use split words your code but not good working, and find this solucion, I only insert create folder, respost is on site:
Save attachments to a folder and rename them David e jogold
Public Sub Download_Attachments()
'If execute in excel, for sample.
'ADD 'Tools > References... Microsoft Outlook 16.0 Object Library
On Error GoTo Err_Control
Dim OutlookOpened As Boolean
Dim outApp As Outlook.Application
Dim outNs As Outlook.Namespace
Dim outFolder As Outlook.MAPIFolder
Dim outAttachment As Outlook.attachment
Dim outItem As Object
Dim saveFolder As String
Dim outMailItem As Outlook.MailItem
Dim inputDate As String, subjectFilter As String, sFolderName As String
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
sFolderName = Format(Now, "yyyyMMdd")
saveFolder = "C:\DOCUMENTOS\Outlook_Anexos" & "\" & sFolderName 'REPLACE YOUR PATCH
If Right(saveFolder, 1) <> "\" Then saveFolder = saveFolder & "\"
subjectFilter = ("Aplicaciones") 'REPLACE WORD SUBJECT TO FIND
OutlookOpened = False
On Error Resume Next
Set outApp = GetObject(, "Outlook.Application")
If Err.Number <> 0 Then
Set outApp = New Outlook.Application
OutlookOpened = True
End If
On Error GoTo Err_Control
If outApp Is Nothing Then
MsgBox "Cannot start Outlook.", vbExclamation
Exit Sub
End If
Set outNs = outApp.GetNamespace("MAPI")
Set outFolder = outNs.GetDefaultFolder(olFolderInbox)
If Not outFolder Is Nothing Then
For Each outItem In outFolder.Items
If outItem.Class = Outlook.OlObjectClass.olMail Then
Set outMailItem = outItem
If InStr(1, outMailItem.Subject, subjectFilter) > 0 Then 'removed the quotes around subjectFilter
For Each outAttachment In outMailItem.Attachments
If Dir(saveFolder, vbDirectory) = "" Then fso.CreateFolder (saveFolder)
outAttachment.SaveAsFile saveFolder & outAttachment.Filename
Set outAttachment = Nothing
Next
End If
End If
Next
End If
If OutlookOpened Then outApp.Quit
Set outApp = Nothing
Err_Control:
If Err.Number <> 0 Then
MsgBox Err.Description
End If
End Sub
Good afternoon Julio Gadioli Soares,
I have tried the code you have provided and it does work, but not as I expected.
I have managed to download the files without the permissions problem, but the files are not saved inside the folder that has been previously created, but outside.
Besides, their names have been changed.
Public Sub Download_Attachments()
'If execute in excel, for sample.
'ADD 'Tools > References... Microsoft Outlook 16.0 Object Library
On Error GoTo Err_Control
Dim OutlookOpened As Boolean
Dim outApp As Outlook.Application
Dim outNs As Outlook.NameSpace
Dim outFolder As Outlook.MAPIFolder
Dim outAttachment As Outlook.Attachment
Dim outItem As Object
Dim saveFolder As String
Dim outMailItem As Outlook.MailItem
Dim inputDate As String, subjectFilter As String, sFolderName As String
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
sFolderName = Format(Now, "yyyyMMdd")
saveFolder = "C:\Users\agonzalezp\Documents\prueba" & "\" & sFolderName
subjectFilter = ("NUEVA") 'REPLACE WORD SUBJECT TO FIND
OutlookOpened = False
On Error Resume Next
Set outApp = GetObject(, "Outlook.Application")
If Err.Number <> 0 Then
Set outApp = New Outlook.Application
OutlookOpened = True
End If
On Error GoTo Err_Control
If outApp Is Nothing Then
MsgBox "Cannot start Outlook.", vbExclamation
Exit Sub
End If
Set outNs = outApp.GetNamespace("MAPI")
Set outFolder = outNs.GetDefaultFolder(olFolderInbox)
If Not outFolder Is Nothing Then
For Each outItem In outFolder.Items
If outItem.Class = Outlook.OlObjectClass.olMail Then
Set outMailItem = outItem
If InStr(1, outMailItem.Subject, subjectFilter) > 0 Then 'removed the quotes around subjectFilter
For Each outAttachment In outMailItem.Attachments
If Dir(saveFolder, vbDirectory) = "" Then fso.CreateFolder (saveFolder)
outAttachment.SaveAsFile saveFolder & outAttachment.FileName
Set outAttachment = Nothing
Next
End If
End If
Next
End If
If OutlookOpened Then outApp.Quit
Set outApp = Nothing
Err_Control:
If Err.Number <> 0 Then
MsgBox Err.Description
End If
End Sub
I get a generated report by Oracle web app every week. I got a macro working to extract that attachment report from my email, but for some reason the date filter doesn't do anything and it saves all the attachments with the email subject "VERIPRD: XXVER Veritiv Aging Report Main: PETROP01" (which is the subject of the report that I want, but I get this weekly, and I only need to extract the most current one)
Also, the report comes with a .out extension which can be opened up with Excel, but if I save that file within the macros as xlsx it gets corrupted.
So what I need is for this macro to actually filter by date, and Subject line (mentioned above), save the .out file as an Excel file titled "Aging Report" and, if there's already an "Aging Report" in destination folder, to replace that previous excel file and not prompt with a message asking me if I want to replace it.
Here's the code I have so far which I put in MS outlook:
Public Sub Extract_Outlook_Email_Attachments()
Dim OutlookOpened As Boolean
Dim outApp As Outlook.Application
Dim outNs As Outlook.NameSpace
Dim outFolder As Outlook.MAPIFolder
Dim outAttachment As Outlook.attachment
Dim outItem As Object
Dim saveFolder As String
saveFolder = "C:\Users\borjax01\Desktop\aging reports"
Dim outMailItem As Outlook.MailItem
Dim inputDate As String, subjectFilter As String
If Right(saveFolder, 1) <> "\" Then saveFolder = saveFolder & "\" & "Aging
Report.out"
inputDate = InputBox("Enter date to filter the email subject", "Extract
Outlook email attachments")
If inputDate = "" Then Exit Sub
InputDateFilter = inputDate
subjectFilter = ("VERIPRD : XXVER Veritiv Aging Report Main : PETROP01")
OutlookOpened = False
On Error Resume Next
Set outApp = GetObject(, "Outlook.Application")
If Err.Number <> 0 Then
Set outApp = New Outlook.Application
OutlookOpened = True
End If
On Error GoTo 0
If outApp Is Nothing Then
MsgBox "Cannot start Outlook.", vbExclamation
Exit Sub
End If
Set outNs = outApp.GetNamespace("MAPI")
Set outFolder = outNs.PickFolder
If Not outFolder Is Nothing Then
For Each outItem In outFolder.Items
If outItem.Class = Outlook.OlObjectClass.olMail Then
Set outMailItem = outItem
If outMailItem.Subject = subjectFilter Then
Debug.Print outMailItem.Subject
For Each outAttachment In outMailItem.Attachments
outAttachment.SaveAsFile saveFolder
Set outAttachment = Nothing
Next
End If
End If
Next
End If
If OutlookOpened Then outApp.Quit
Set outApp = Nothing
End Sub
A post might get answers more quickly if broken into multiple single questions as is expected in this Q & A.
Public Sub Extract_Outlook_Email_Attachments()
Dim OutlookOpened As Boolean
Dim OutApp As outlook.Application
Dim outNs As outlook.Namespace
Dim outFolder As outlook.MAPIFolder
Dim outAttachment As outlook.Attachment
Dim outItem As Object
Dim saveFolder As String
Dim outMailItem As outlook.MailItem
Dim inputDate As String, subjectFilter As String
Dim fldrItems As Items
Dim resultItems As Items
Dim strFilter As String
saveFolder = "C:\Users\borjax01\Desktop\aging reports"
saveFolder = "H:\test2"
'If Right(saveFolder, 1) <> "\" Then saveFolder = saveFolder & "\" & "Aging Report.out"
If Right(saveFolder, 1) <> "\" Then saveFolder = saveFolder & "\"
' subjectFilter = ("VERIPRD : XXVER Veritiv Aging Report Main : PETROP01")
' No "Re:" nor "Fw:"
subjectFilter = "VERIPRD : XXVER Veritiv Aging Report Main : PETROP01"
OutlookOpened = False
On Error Resume Next
Set OutApp = getObject(, "Outlook.Application")
If Err.number <> 0 Then
Set OutApp = New outlook.Application
OutlookOpened = True
End If
On Error GoTo 0
If OutApp Is Nothing Then
MsgBox "Cannot start Outlook.", vbExclamation
Exit Sub
End If
Set outNs = OutApp.GetNamespace("MAPI")
Set outFolder = outNs.PickFolder
If Not outFolder Is Nothing Then
Set fldrItems = outFolder.Items
strFilter = "[Subject] = '" & subjectFilter & "'"
Debug.Print strFilter
Set resultItems = fldrItems.Restrict(strFilter)
'Debug.Print resultItems.count
resultItems.Sort "[ReceivedTime]", True
For Each outItem In resultItems
If outItem.Class = outlook.OlObjectClass.olMail Then
Set outMailItem = outItem
If outMailItem.subject = subjectFilter Then
Debug.Print " outMailItem.subject: " & outMailItem.subject
Debug.Print " outMailItem.ReceivedTime: " & outMailItem.ReceivedTime
For Each outAttachment In outMailItem.Attachments
Debug.Print " outAttachment.DisplayName: " & outAttachment.DisplayName
If InStr(outAttachment.DisplayNamem, ".out") Then
outAttachment.SaveAsFile saveFolder & outAttachment.DisplayName
Exit Sub '<-- exit when most recent is saved
End If
Next
End If
End If
Next
End If
If OutlookOpened Then OutApp.Quit
Set OutApp = Nothing
End Sub
I save items I receive on my hard drive and name them differently.
Trying to import the items back into Outlook gives me an error:
Compile Error User-Defined type not defined.
on
Dim Savefolder As Outlook.Folder
In my first module
Public Sub saveAttachtoDisk(itm As Outlook.MailItem)
Dim objAtt As Outlook.Attachment
Dim Savefolder As String
Savefolder = "c:\temp"
For Each objAtt In itm.Attachments
stFileName = Savefolder & "\" & objAtt.DisplayName
i = 0
JumpHere:
If Dir(stFileName) = "" Then
objAtt.SaveAsFile stFileName
Else
i = i + 1
stFileName = Savefolder & "\" & objAtt.DisplayName & " - " & i
GoTo JumpHere
End If
Set objAtt = Nothing
Next
End Sub
In my second module
Sub ImportMessagesInFolder()
Dim fso As Scripting.FileSystemObject
Dim SourceFolder As Scripting.Folder
Dim SourceFolderName As String
Dim FileItem As Scripting.file
Dim strFile, strFileType As String
Dim oMsg As Object
Dim copiedMsg As MailItem
Dim Savefolder As Outlook.Folder
Set fso = New Scripting.FileSystemObject
'Source folder
SourceFolderName = "C:\temp"
Set SourceFolder = fso.GetFolder(SourceFolderName)
'Set the Outlook folder name
Set Savefolder = Session.GetDefaultFolder(olFolderInbox).Folders("Extra")
Set Savefolder = Application.ActiveExplorer.CurrentFolder
For Each FileItem In SourceFolder.Files
Set oMsg = Session.OpenSharedItem(FileItem.Path)
On Error Resume Next
Set copiedMsg = oMsg.Copy
copiedMsg.Move Savefolder
Set copiedMsg = Nothing
oMsg.Delete
Set oMsg = Nothing
Next FileItem
Set FileItem = Nothing
Set SourceFolder = Nothing
Set fso = Nothing
End Sub
Use Outlook.MAPIFolder instead.
I've got a rule + script setup in outlook. The rule looks for specific words in the email subject and then runs the script (defined in Modules) below. But it seems to be only working for my personal inbox and not a group inbox. The below is the code that works.
The lines in comments are me trying to work it out.
Public Sub saveAttachtoDisk(item As Outlook.MailItem)
Dim objAtt As Outlook.Attachment
Dim saveFolder As String
saveFolder = "d:\temp\"
Dim objNS As Outlook.NameSpace
Set Items = objNS.GetDefaultFolder(olFolderInbox).Items
'Set objNS = olApp.GetNamespace("MAPI")
'Set myRecipient = objNS.CreateRecipient("XXXXXXX")
'myRecipient.Resolve
'set Items = objNS.GetSharedDefaultFolder(myRecipient, olFolderInbox).Items
'Dim itm As Outlook.MailItem
' If TypeName(item) = "MailItem" Then
' Set itm = item
For Each objAtt In itm.Attachments
objAtt.SaveAsFile saveFolder & "\" & objAtt.DisplayName
Set objAtt = Nothing
Next
End Sub
This is how to go and read the email subject to launch further code :
Public Sub saveAttachtoDisk()
Dim olApp As Outlook.Application, _
oNS As Outlook.NameSpace, _
oFld As Outlook.Folder, _
oMails As Outlook.Items, _
oMail As Outlook.MailItem, _
oAtt As Outlook.Attachment, _
SaveFolder As String
SaveFolder = "d:\temp\"
On Error Resume Next
Set olApp = GetObject(, "Outlook.Application")
If Err.Number > 0 Then Set olApp = CreateObject("Outlook.Application")
On Error GoTo 0
Set oNS = olApp.GetNamespace("MAPI")
Set oFld = oNS.GetDefaultFolder(olFolderInbox)
Set oMails = oFld.Items
For Each oMail In oMails
If InStr(1, oMail.Subject, "Txt_to_Find") Then
'----Your code comes here
For Each oAtt In oMail.Attachments
oAtt.SaveAsFile SaveFolder & "\" & oAtt.DisplayName
Set oAtt = Nothing
Next oAtt
Else
End If
Next oMail
End Sub
Basic question - I have a script that saves attachments from selected emails in outlook, I want it to save the attachments automatically when they come in instead (I'll create a rule in outlook to run the script when an email comes in), any help would be appreciated!
Public Sub script()
Dim saveFolder As String
Dim objAtt As Outlook.attachment
Dim itm As Outlook.MailItem
Dim dateFormat
dateFormat = Format(Now, "yymmdd ")
saveFolder = "C:\temp"
For Each itm In ActiveExplorer.Selection
For Each objAtt In itm.Attachments
If objAtt.Size > 5200 Then
objAtt.SaveAsFile saveFolder & "\" & dateFormat & objAtt.DisplayName
Set objAtt = Nothing
End If
Next objAtt
Next itm
End Sub
You need to pass an item as a parameter. So, the code should look like the following one:
Public Sub script(itm as Outlook.MailItem)
Dim saveFolder As String
Dim objAtt As Outlook.attachment
Dim dateFormat
dateFormat = Format(Now, "yymmdd ")
saveFolder = "D:\temp"
For Each objAtt In itm.Attachments
If objAtt.Size > 5200 Then
objAtt.SaveAsFile saveFolder & "\" & dateFormat & objAtt.DisplayName
Set objAtt = Nothing
End If
Next objAtt
End Sub
And don't save attachments on the C: drive, it requires admin privileges on the latest Windows OS. Choose another drive/folder.
I am not sure that you can use a rule for this. I think you will need to hook up an Outlook event. To do this you would use code like the following;
Private WithEvents olItems As Outlook.Items
Private Sub Application_Startup()
Dim olApp As Outlook.Application
Dim objNS As Outlook.NameSpace
Set olApp = Outlook.Application
Set objNS = olApp.GetNamespace("MAPI")
' this is for your local Inbox - if you have more inboxes you need to set it for each one
Set olItems = objNS.GetDefaultFolder(olFolderInbox).Items
End Sub
'You can add this because you used "WithEvents" to declare olItems
Private Sub olItems_ItemAdd(ByVal item As Object)
Dim olMailItem As Outlook.MailItem
'this event will fire for all items so you need to make sure you have a mail item.
If TypeName(item) = "MailItem" Then
Set olMailItem = item
Dim saveFolder As String
Dim objAtt As Outlook.attachment
Dim dateFormat
dateFormat = Format(Now, "yymmdd ")
saveFolder = "D:\temp"
For Each objAtt In olMailItem.Attachments
If objAtt.Size > 5200 Then
objAtt.SaveAsFile saveFolder & "\" & dateFormat & objAtt.DisplayName
Set objAtt = Nothing
End If
Next objAtt
End If
End Sub