Auto saving Outlook attachments VBA - vba

I've been playing around with the below code in an attempt to save files which we receive daily in Outlook. The code seems to run fine, however, when I go to check the destination folder there are no attachments saved.
How can I modify the code to save the attachments to the specified folder?
Private WithEvents Items 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")
Set Items = objNS.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub Items_ItemAdd(ByVal item As Object)
On Error GoTo ErrorHandler
'Only act if it's a MailItem
Dim Msg As Outlook.MailItem
If TypeName(item) = "MailItem" Then
Set Msg = item
'Change variables to match need. Comment or delete any part unnecessary.
If (Msg.SenderName = "made-up-email#some_domain.com") And _
(Msg.Subject = "Test") And _
(Msg.Attachments.Count >= 1) Then
'Set folder to save in.
Dim olDestFldr As Outlook.MAPIFolder
Dim myAttachments As Outlook.Attachments
Dim Att As String
'location to save in. Can be root drive or mapped network drive.
Const attPath As String = "T:\London File3 Group\Client Reporting\Test"
' save attachment
Set myAttachments = item.Attachments
Att = myAttachments.item(1).DisplayName
myAttachments.item(1).SaveAsFile attPath & Att
' mark as read
Msg.UnRead = False
End If
End If
End Sub

This code should work, something you may not have done is added this to the ThisOutlookSession object. Don't add to a standard module.
Private WithEvents InboxItems As Outlook.Items
Const attPath As String = "T:\London File3 Group\Client Reporting\Test\"
Private Sub Application_Startup()
Dim outlookApp As Outlook.Application: Set outlookApp = Outlook.Application
Dim objectNS As Outlook.NameSpace: Set objectNS = outlookApp.GetNamespace("MAPI")
Set InboxItems = objectNS.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub InboxItems_ItemAdd(ByVal Item As Object)
Dim Msg As Outlook.MailItem: Set Msg = Item
Dim olDestFldr As Outlook.MAPIFolder
Dim myAttachments As Outlook.Attachments
Dim Filename As String
If Not TypeName(Msg) = "MailItem" Then Exit Sub
If (Msg.SenderName = "made-up-email#some_domain.com") And (Msg.Subject = "Test") And (Msg.Attachments.Count >= 1) Then
Set myAttachments = Item.Attachments
Filename = myAttachments.Item(1).DisplayName
myAttachments.Item(1).SaveAsFile attPath & Filename
Msg.UnRead = False
End If
End Sub

Related

Save attachments to a new Windows folder?

Every time I receive an email with the subject "Test", I want to:
Automatically extract all attachments and store them in its own new created folder.
Automatically copy the email inside this new folder
Automatically add a Word document inside this new folder.
The folder must be named by the date received.
The code I have copies all attachments in a pre-selected folder, but it doesn't create a personal folder for them.
Private WithEvents Items 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")
Set Items = objNS.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub Items_ItemAdd(ByVal item As Object)
On Error GoTo ErrorHandler
'Only act if it's a MailItem
Dim Msg As Outlook.MailItem
If TypeName(item) = "MailItem" Then
Set Msg = item
'Change variables to match need. Comment or delete any part unnecessary.
If (Msg.Subject = "Heures") And _
(Msg.Attachments.Count >= 1) Then
'Set folder to save in.
Dim olDestFldr As Outlook.MAPIFolder
Dim myAttachments As Outlook.Attachments
Dim Att As Variant
Const attPath As String = "C:\Users\NASC02\Test\"
' save attachment
Set myAttachments = item.Attachments
For Each Att In myAttachments
Att.SaveAsFile attPath & Att.FileName
Next
' mark as read
Msg.UnRead = False
End If
End If
ProgramExit:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ProgramExit
End Sub
The code
Set myAttachments = item.Attachments
Att = myAttachments.item(1).DisplayName
myAttachments.item(1).SaveAsFile attPath & Att
needs to be changed to
Set myAttachments = item.Attachments
for each Att in myAttachments
Att.SaveAsFile attPath & Att.FileName
next

Runtime error "-2147024809" Moving Sent Mails To SentMail-Folder of secondary account

I have two accounts open in Outlook.
When I send a Mail via the secondary account it appears in the sent folder of the primary account.
I want to move the sent mail to the sent folder of the secondary account whenever I send mail.
Option Explicit
Private WithEvents inboxItems As Outlook.Items
Private Sub Application_Startup()
Dim outlookApp As Outlook.Application
Dim objectNS As Outlook.NameSpace
Set outlookApp = Outlook.Application
Set objectNS = outlookApp.GetNamespace("MAPI")
Set inboxItems = objectNS.GetDefaultFolder(olFolderSentMail).Items
End Sub
Private Sub inboxItems_ItemAdd(ByVal Item As Object)
On Error GoTo ErrorHandler
Dim Folder As Outlook.Folder
If TypeName(Item) = "MailItem" Then
If Item.SenderName = "MY SECONDARY EMAIL" Then
Dim NS As Outlook.NameSpace
Dim objOwner As Outlook.Recipient
Dim newFolder As Outlook.Folder
Set NS = Application.GetNamespace("MAPI")
Set objOwner = NS.CreateRecipient("mysecondary#email.de")
objOwner.Resolve
If objOwner.Resolved Then
Set newFolder = NS.GetSharedDefaultFolder(objOwner, olFolderSentMail)
MsgBox (newFolder)
Item.Move newFolder
End If
End If
End If
ExitNewItem:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ExitNewItem
End Sub
I get this Error message:
-2147024809 - Unfortunately there is a problem. You can try again
It shows that the line Set newFolder = NS.GetSharedDefaultFolder(objOwner, olFolderSentMail) is causing this problem.
The error is MAPI_E_INVALID_PARAMETER. Most likely that means the specified mailbox is not an Exchange mailbox or it belongs to a different Exchange org.
If that mailbox is already opened in the current profile, you can access that Store object (and use Store.GetDefaultFolder) from the Namespace.Stores collection.
Dmitry Streblechenko's answer worked!
Here is how I did it if anyone got the same problem:
Option Explicit
Private WithEvents inboxItems As Outlook.Items
Private Sub Application_Startup()
Dim outlookApp As Outlook.Application
Dim objectNS As Outlook.NameSpace
Set outlookApp = Outlook.Application
Set objectNS = outlookApp.GetNamespace("MAPI")
Set inboxItems = objectNS.GetDefaultFolder(olFolderSentMail).Items
End Sub
Sub inboxItems_ItemAdd(ByVal Item As Object)
If TypeName(Item) = "MailItem" Then
If Item.SenderName = "SENDERNAME" Then
Dim NS As Outlook.NameSpace
Dim objOwner As Outlook.Recipient
Dim newFolder As Outlook.Folder
Dim colStores As Outlook.Stores
Dim oStore As Outlook.Store
Dim oRoot As Outlook.Folder
Set NS = Application.GetNamespace("MAPI")
Set objOwner = NS.CreateRecipient("secondary#email.de")
Set colStores = Application.Session.Stores
For Each oStore In colStores
Set oRoot = oStore.GetRootFolder
If oStore = "SECONDARY EMAIL NAME" Then
Call EnumerateFolders(oRoot, Item)
End If
Next
End If
End If
End Sub
Sub EnumerateFolders(ByVal oFolder As Outlook.Folder, Item)
Dim folders As Outlook.folders
Dim Folder As Outlook.Folder
Dim foldercount As Integer
Set folders = oFolder.folders
foldercount = folders.Count
For Each Folder In folders
If Folder.FolderPath = "\\SECONDARY EMAIL NAME\Sent Items" Then
Item.Move Folder
End If
Next
End Sub

How to reference a subfolder of a shared mailbox?

I want to save Outlook attachments to a shared drive.
The below script saves attachments from my own inbox. I want to save attachments from a subfolder of a shared mailbox.
Private WithEvents InboxItems As Outlook.Items
Const attPath As String = "T:\London File3 Group\Client Reporting\Test\ABI Daily\"
Private Sub Application_Startup()
Dim outlookApp As Outlook.Application: Set outlookApp = Outlook.Application
Dim objectNS As Outlook.NameSpace: Set objectNS = outlookApp.GetNamespace("MAPI")
Set InboxItems = objectNS.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub InboxItems_ItemAdd(ByVal Item As Object)
Dim Msg As Outlook.MailItem: Set Msg = Item
Dim olDestFldr As Outlook.MAPIFolder
Dim myAttachments As Outlook.Attachments
Dim Filename As String
If Not TypeName(Msg) = "MailItem" Then Exit Sub
If (Msg.Subject Like "*Trade*") Or (Msg.Subject Like "*Trades*") Or _
(Msg.Subject Like "*Article 59*") Or (Msg.Subject Like "*Val*") Or _
(Msg.Subject Like "*Valuation*") Or (Msg.Subject Like "*Trading*") Or _
(Msg.Subject Like "*St James*") Then
Set myAttachments = Item.Attachments
Filename = myAttachments.Item(1).DisplayName
myAttachments.Item(1).SaveAsFile attPath & Filename
Msg.UnRead = False
End If
End Sub
Work with GetSharedDefaultFolder Method which Returns a MAPIFolder object that represents the specified default folder for the specified user. This method is used in a delegation scenario, where one user has delegated access to another user for one or more of their default folders
Example
Private WithEvents InboxItems As Outlook.Items
Const attPath As String = "T:\London File3 Group\Client Reporting\Test\ABI Daily\"
Private Sub Application_Startup()
Dim outlookApp As Outlook.Application: Set outlookApp = Outlook.Application
Dim objectNS As Outlook.NameSpace: Set objectNS = outlookApp.GetNamespace("MAPI")
Dim ShrdRecip As Outlook.Recipient: Set ShrdRecip = objectNS.CreateRecipient("0m3r#email.com")
Set InboxItems = GetSharedDefaultFolder(ShrdRecip, olFolderInbox).Items
End Sub
Edit
Example for subfolder
Private WithEvents Items As Outlook.Items
Private Sub Application_Startup()
Dim olNs As Outlook.NameSpace
Dim ShrdRecip As Outlook.Recipient
Dim Inbox As Outlook.MAPIFolder
Set olNs = Application.GetNamespace("MAPI")
Set ShrdRecip = olNs.CreateRecipient("0m3r#email.com")
Set Inbox = olNs.GetSharedDefaultFolder(ShrdRecip, olFolderInbox) _
.Folders("FolderName")
Set Items = Inbox.Items
End Sub
Private Sub Items_ItemAdd(ByVal Item As Object)
If TypeOf Item Is Outlook.MailItem Then
Debug.Print Item.Subject ' print on Immediate window
End If
End Sub

Move Outlook incoming message to folder that starts with the same codes

I am trying to automate moving incoming messages to a designated subfolder in Outlook.
Messages that contain a projectnumber in the format P000.0000 should be moved to the Inbox's subfolder that starts with the same projectnumber.
The subfolders will be pre-created by hand, so the user can decide which projects to round up in a dedicated subfolder.
The folderstructure is Inbox>Actueel>P000.0000
The first bit, where incoming messages are checked works fine, but after that I get lost... Where it starts with For Each Folder In olFolderPrjcts
The error is on this line Set olFolder = objNS.GetDefaultFolder(olFolderInbox)
This is what I came up with so far:
Private WithEvents myOlItems As Outlook.Items
Private Sub Application_Startup()
Dim olApp As Outlook.Application
Dim objNS As Outlook.NameSpace
Dim olFolder As Outlook.MAPIFolder
Set olApp = Outlook.Application
Set objNS = olApp.GetNamespace("MAPI")
Set olFolder = objNS.GetDefaultFolder(olFolderInbox)
Set myOlItems = objNS.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub myOlItems_ItemAdd(ByVal item As Object)
Dim Atts As Outlook.Attachments
Dim Props As Outlook.UserProperties
Dim Prop As Outlook.UserProperty
Dim PropName As String
PropName = "NumberAttachments"
Set Atts = item.Attachments
Set Props = item.UserProperties
Set Prop = Props.Find(PropName, True)
If Prop Is Nothing Then
Set Prop = Props.Add(PropName, olText, True)
End If
Dim olFolder As Outlook.MAPIFolder
Set olFolder = objNS.GetDefaultFolder(olFolderInbox)
Dim olFolderPrjcts
Set olFolderPrjcts = olFolder.Folders("actueel")
Prop.Value = Atts.Count
item.Save
Dim Msg As Outlook.MailItem
If TypeName(item) = "MailItem" Then
Set Msg = item
For Each Folder In olFolderPrjcts
If Left(Msg.Subject, 9) = Left(Folder.Name, 9) Then
Msg.Move (Folder)
End If
Next
' DO SOMETHING TO NEWLY ARRIVED MESSAGE
' If Msg.Subject contains like P000.0000 AND
' folder exists that starts with P000.0000
' then move to that folder
End If
End Sub
Without Option Explicit the error is likely Run-time error '424': Object required.
With Option Explicit the error is likely Compile error: Variable not defined.
Option Explicit
' Tools | Options | Editor tab
' Checkbox "Require Variable Declaration"
Private Sub myOlItems_ItemAdd(ByVal Item As Object)
Dim objNS As Namespace ' <--
Dim olFolder As folder
Dim folder As folder
Dim olFolderPrjcts As folder
Dim Msg As MailItem
Set objNS = GetNamespace("MAPI") ' <--
Set olFolder = objNS.GetDefaultFolder(olFolderInbox)
Set olFolderPrjcts = olFolder.Folders("actueel")
If TypeName(Item) = "MailItem" Then
Set Msg = Item
For Each folder In olFolderPrjcts.Folders
If Left(Msg.subject, 9) = Left(folder.name, 9) Then
'Debug.Print Msg.subject
'Debug.Print folder.name
Msg.move folder ' <-- no brackets
Exit For
End If
Next
End If
End Sub

Automate Attachment Save

So, the goal is that when I receive an email from a customer, containing the desired attachment, save the attachment to a location of my choosing.
This is my new code, it compiles but doesn't output the file?
Thanks in advance.
Private WithEvents Items 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")
Set Items = objNS.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub Application_NewMail()
Dim oInbox As MAPIFolder
Dim oItem As MailItem
Set oInbox = Application.Session.GetDefaultFolder(olFolderInbox)
Set oItem = oInbox.Items.GetLast
'Only act if it's a MailItem
Dim Msg As Outlook.MailItem
If TypeName(item) = "MailItem" Then
Set Msg = oItem
'Change variables to match need. Comment or delete any part unnecessary.
If (Msg.SenderName = "Name Of Person") And _
(Msg.Subject = "Subject to Find") And _
(Msg.Attachments.Count >= 1) Then
'Set folder to save in.
Dim olDestFldr As Outlook.MAPIFolder
Dim myAttachments As Outlook.Attachments
Dim Att As String
'location to save in. Can be root drive or mapped network drive.
Const attPath As String = "C:\"
' save attachment
Set myAttachments = item.Attachments
Att = myAttachments.item(1).DisplayName
myAttachments.item(1).SaveAsFile attPath & Att
' mark as read
Msg.UnRead = False
End If
End If
ProgramExit:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ProgramExit
End Sub
When you open the VBA window, you will see the object called "ThisOutlookSession", which is where you place the code.
This event is triggered automatically upon reception of a new email received:
Private Sub Application_NewMail()
Dim oInbox As MAPIFolder
Dim oItem As MailItem
Set oInbox = Application.Session.GetDefaultFolder(olFolderInbox)
Set oItem = oInbox.Items.GetLast
//MsgBox oItem.To
//Etcetera
End Sub
About your edit, I didn't really investigate why it didn't work, but you can use this, which I tested:
Dim atmt As Outlook.Attachment
Dim Att As String
Const attPath As String = "U:\"
For Each atmt In Msg.Attachments
Att = atmt.DisplayName
atmt.SaveAsFile attPath & Att
Next
Note that it may seem as if you didn't save the file, because you cannot use 'Date modified' in WinExplorer to show the latest saved attachment (I noticed just now). But you can look it up alphabetically.