Save email to a folder if subject line matches - vba

I'm trying to save an email, when it arrives, into a folder if the subject line contains the right term.
This code would end up being copied for 75-80 items all with varying subject lines.
Option Explicit
Private Sub InboxItems_ItemAdd(ByVal objItem As Object)
Dim msgNew As MailItem
Dim DateYr As Object
Dim DateMonth As Object
If objItem.Class = olMail Then
Set msgNew = objItem
If (msgNew.Subject Like "Client Media Report*") Then
DateYr = Format(Now(), "yyyy", vbUseSystemDayOfWeek, vbUseSystem)
DateMonth = Format(Now(), "mm. mmmm", vbUseSystemDayOfWeek, vbUseSystem)
On Error Resume Next
MkDir "M:\AutoArchive\Client Media Report\" & DateYr
On Error GoTo 0
msgNew.SaveAs "M:\AutoArchive\Client Media Report\" & DateYr & "\" & DateMonth & ".msg"
End If
End If
End Sub
I'd expect this to save a new email into the correct folder. E.g., the example would save into M:\AutoArchive\Client Media Report\2019\08. August
It doesn't save and doesn't spit an error.
Example subject line: Client Media Report 05 August 2019
Example file location: M:\AutoArchive\Client Media Report\2019\08. August
EDIT: Updated with latest code, event triggers error
Unable to open item
on
Set mai = Application.Session.GetItemFromID(strEntryId)
Private Sub Application_NewMailEx(ByVal EntryIDCollection As String)
MsgBox ("Test1")
Dim mai As Object
Dim msgNew As MailItem
Dim DateYr As Object
Dim DateMonth As Object
Set mai = Application.Session.GetItemFromID(strEntryId)
MsgBox mai.Subject
If mai.Class = olMail Then
Set msgNew = objItem
If (msgNew.Subject Like "DPS Front Pages*") Then
DateYr = Format(Now(), "yyyy", vbUseSystemDayOfWeek, vbUseSystem)
DateMonth = Format(Now(), "mm. mmmm", vbUseSystemDayOfWeek, vbUseSystem)
On Error Resume Next
MkDir "D:\AutoArchive\Full Front Pages\" & DateYr
On Error GoTo 0
msgNew.SaveAs "D:\AutoArchive\Full Front Pages\" & DateYr & "\" & DateMonth & msgNew.Subject & ".msg"
End If
End If
End Sub

You need to handle the NewMailEx event of the Application class which is fired when a new item is received in the Inbox.
The NewMailEx event fires when a new message arrives in the Inbox and before client rule processing occurs. You can use the Entry ID returned in the EntryIDCollection array to call the NameSpace.GetItemFromID method and process the item. Use this method with caution to minimize the impact on Outlook performance. However, depending on the setup on the client computer, after a new message arrives in the Inbox, processes like spam filtering and client rules that move the new message from the Inbox to another folder can occur asynchronously.
Private Sub NewMailEx(ByVal EntryIDCollection As String)
Dim mai As Object
Dim msgNew As MailItem
Dim DateYr As Object
Dim DateMonth As Object
Set mai = Application.Session.GetItemFromID(strEntryId)
MsgBox mai.Subject
If mai.Class = olMail Then
Set msgNew = objItem
If (msgNew.Subject Like "Client Media Report*") Then
DateYr = Format(Now(), "yyyy", vbUseSystemDayOfWeek, vbUseSystem)
DateMonth = Format(Now(), "mm. mmmm", vbUseSystemDayOfWeek, vbUseSystem)
On Error Resume Next
MkDir "M:\AutoArchive\Client Media Report\" & DateYr
On Error GoTo 0
msgNew.SaveAs "M:\AutoArchive\Client Media Report\" & DateYr & "\" & DateMonth & msgNew.Subject & ".msg"
End If
End If
End Sub

Related

Restrict Outlook Items to today's date - VBA

I've written some code that scans my default Outlook inbox for emails received today with a specific subject.
I then download the attachment for Outlook items that meet my criteria. I am having trouble designating the Restrict method to pull back items received today.
Here is what I have:
Sub DownloadAttachmentFirstUnreadEmail()
Dim oOlAp As Object, oOlns As Object, oOlInb As Object
Dim oOlItm As Object, oOlAtch As Object
Dim sFilter As String
Dim NewFileName As String
NewFileName = "C:\Temp\" & "CHG_Daily_Extract_" & Format(Date, "MM-DD-YYYY") & ".csv"
'~~> Get Outlook instance
Set oOlAp = GetObject(, "Outlook.application")
Set oOlns = oOlAp.GetNamespace("MAPI")
Set oOlInb = oOlns.GetDefaultFolder(olFolderInbox)
'Declare email item restriction
sFilter = "[ReceivedTime] = '" & Format(Date, "DDDDD HH:NN") & "'"
'Catch
If oOlInb.Items.Restrict(sFilter).Count > 0 Then
'~~> Loop thru today's emails
For Each oOlItm In oOlInb.Items.Restrict(sFilter)
'~> Check if the email subject matches
If oOlItm = "ASG CDAS Daily CHG Report" Then
'~~> Download the attachment
For Each oOlAtch In oOlItm.Attachments
oOlAtch.SaveAsFile NewFileName
Exit For
Next
End If
Exit For
Next
'Display if no emails today
Else: MsgBox "No items"
End If
End Sub
When I run the code, I consistently receive my catch message of "No items".
Please let me know if I am using the Restrict method incorrectly. Thank you so much for the help.
How about the following-
Filter = "#SQL=" & "%today(" & Chr(34) & ("urn:schemas:httpmail:datereceived") & _
Chr(34) & ")%
Or with Attachment
Filter = "#SQL=" & "%today(" & Chr(34) & ("urn:schemas:httpmail:datereceived") & _
Chr(34) & ")% AND " & _
Chr(34) & "urn:schemas:httpmail:hasattachment" & _
Chr(34) & "=1"
Example
Option Explicit
Private Sub Examples()
Dim olNs As Outlook.NameSpace
Dim Inbox As Outlook.MAPIFolder
Dim Items As Outlook.Items
Dim Msg As String
Dim i As Long
Dim Filter As String
Set olNs = Application.GetNamespace("MAPI")
Set Inbox = olNs.GetDefaultFolder(olFolderInbox)
Filter = "#SQL=" & "%today(" & Chr(34) & ("urn:schemas:httpmail:datereceived") & _
Chr(34) & ")%"
Set Items = Inbox.Items.Restrict(Filter)
Msg = Items.Count & " Items in " & Inbox.Name
If MsgBox(Msg, vbYesNo) = vbYes Then
For i = Items.Count To 1 Step -1
Debug.Print Items(i) 'Immediate Window
Next
End If
End Sub
Filtering Items Using a Date-time Comparison MSDN
Outlook Date-time Macros
The date macros listed below return filter strings that compare the value of a given date-time property with a specified date in UTC; SchemaName is any valid date-time property referenced by namespace.
Note Outlook date-time macros can be used only in DASL queries.
Macro Syntax Description
today %today(" SchemaName")% Restricts for items with SchemaName
property value equal to today
More Examples Here

Adding an Appointment sent as an Attachment to a Calendar

Automated emails with .ics attachments are being received in an Outlook Shared mailbox.
I am trying to open that attachment, and save that Meeting/Appointment to the Calendar.
I tried a number of ways. For my latest iteration I am hoping to add this macro directly on the Shared Calendar's mailbox. Let me know if it makes more sense for the emails to be sent to my personal Outlook mailbox, where I then call the macro from a "run a script" Outlook Rule, and route it to the Shared Calendar.
Sub SaveAttatchments()
' This Outlook macro checks at the Outlook Inbox for messages
' with attached files (of *.ics type) and put a entry in the calendar.
On Error GoTo SaveAttachments_err
Dim InboxFolder As Outlook.Folder
Dim myCalendarFolder As Outlook.Folder
Dim myMtgReq As Outlook.MeetingItem
Dim mynamespace As Outlook.NameSpace
Dim Atmt As Attachment
Dim FileName As String
Dim i As Integer
Set mynamespace = Application.GetNamespace("MAPI")
Set InboxFolder = mynamespace.GetDefaultFolder(olFolderInbox)
Set myCalendarFolder = mynamespace.GetDefaultFolder(olFolderCalendar)
FilePath = "C:\temp\"
' Check each message for attachments
For Each Item In InboxFolder.Items
For Each Atmt In Item.Attachments
If Right(Atmt.FileName, 3) = "ics" Then
'Save the attachment in folder
FileName = FilePath & Atmt.FileName
Atmt.SaveAsFile FileName
'Import the ics from the folder and put an entry in Calendar
Set myMtgReq = mynamespace.OpenSharedFolder(FileName)
myMtgReq.GetAssociatedAppointment (True)
i = i + 1
End If
Next Atmt
Next Item
SaveAttachments_exit:
Set Atmt = Nothing
Set Item = Nothing
Set myMtgReq = Nothing
Exit Sub
SaveAttachments_err:
MsgBox "An unexpected error has occurred." _
& vbCrLf & "Please note and report the following information." _
& vbCrLf & "Macro Name: SaveAttachments" _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description: " & Err.Description _
, vbCritical, "Error!"
Resume SaveAttachments_exit
End Sub
I get the following:
"Outlook cannot perform this action on this type of attachment."
Below is the corrected vba. The Attachment saves as a AppointmentItem, not a MeetingItem, which was causing the issues.
Sub SaveAttatchments()
On Error GoTo SaveAttachments_err
Dim myNameSpace As Outlook.NameSpace
Dim InboxFolder As Outlook.Folder
Dim myCalendarFolder As Outlook.Folder
Dim myMtgReq As Outlook.MeetingItem
Dim myAppt As Outlook.AppointmentItem
Dim Atmt As Attachment
Dim FileName As String
Dim i As Integer
Set myNameSpace = Application.GetNamespace("MAPI")
Set InboxFolder = myNameSpace.GetDefaultFolder(olFolderInbox)
Set myCalendarFolder = myNameSpace.GetDefaultFolder(olFolderCalendar)
FilePath = "C:\temp\"
' Check each message for attachments
For Each Item In InboxFolder.Items
If Item.Subject = "Conf Calendar" Then
For Each Atmt In Item.Attachments
'Save the attachment in folder
FileName = FilePath & Atmt.FileName
Atmt.SaveAsFile FileName
'Import the ics from the folder and put an entry in Calendar
Set myAppt = myNameSpace.OpenSharedItem(FileName)
myAppt.Save
i = i + 1
Next Atmt
End If
Next Item
' Clear memory
SaveAttachments_exit:
Set Atmt = Nothing
Set Item= Nothing
Set myMtgReq = Nothing
Exit Sub
SaveAttachments_err:
MsgBox "An unexpected error has occurred." _
& vbCrLf & "Please note and report the following information." _
& vbCrLf & "Macro Name: SaveAttachments" _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description: " & Err.Description _
, vbCritical, "Error!"
Resume SaveAttachments_exit
End Sub

VBA script not saving first mail

first of all i'll say that i'm not an expert in coding but i do have a basic understanding.
i have a script that saves all unread mails as txt and marks them as read.
It works fine, but when i set up a rule with it to run every time i get a mail from a specific person it doesn't effect the first mail.
Example: i get a mail, the script runs but doesn't save anything (as long as there is no other mail from the same person and isn't Unread).
then i get a second mail from the same person, the script will run and save the previous mail but not the latest one.
Here a sample of the code:
Public Sub TestEnvMacro()
Set objOutlook = CreateObject("Outlook.Application")
Set objNamespace = objOutlook.GetNamespace("MAPI")
Set objMailbox = objNamespace.Folders("your email goes here")
Set objFolder = objMailbox.Folders("Inbox")
Set colItems = objFolder.Items
Dim NewMsg
Dim dtDate As Date
Dim sName As String
Const OLTXT = 0
Pause (5)
For Each objMessage In colItems.Restrict("[Unread] = True")
If objMessage.UnRead = True Then
Pause (5)
Set NewMsg = objMessage
sName = NewMsg
dtDate = NewMsg.ReceivedTime
sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
vbUseSystem) & Format(dtDate, "-hhnnss", _
vbUseSystemDayOfWeek, vbUseSystem) & "-" & sName & ".txt"
NewMsg.SaveAs "G:\" & sName, OLTXT
NewMsg.UnRead = False
End If
Next
End Sub
I didn't include the pause Sub since it's pretty self explanatory what it does, also i've had a problem with getting the script to show up in the "Rules" so I added this Sub:
Public Sub SaveAsTextMod(msg As MailItem)
Dim strID As String
Dim olNS As NameSpace
Dim olMail As MailItem
strID = msg.EntryID
Set olNS = Application.GetNamespace("MAPI")
Set olMail = olNS.GetItemFromID(strID)
Call TestEnvMacro
Set olMail = Nothing
Set olNS = Nothing
End Sub
When you create a rule to apply for incoming emails, the mail item is passed as a parameter to the macro sub. There is no need to search for unread emails in Outlook. You just need to define the function with a MailItem parameter do the required actions against that objects.
Public Sub SaveAsTextMod(msg As MailItem)
Dim dtDate As Date
Dim sName As String
dtDate = msg.ReceivedTime
sName = Format(dtDate, "yyyymmdd", vbUseSystemDayOfWeek, _
vbUseSystem) & Format(dtDate, "-hhnnss", _
vbUseSystemDayOfWeek, vbUseSystem) & "-" & msg.Subject & ".txt"
msg.SaveAs "G:\" & sName, OLTXT
msg.UnRead = False
End Sub
You may find the Getting Started with VBA in Outlook 2010 article helpful.

VBA Outlook rule to Run Script is not completing

I'm have trouble with this macro/script that doesn't completely run via email rule
I have an outlook rule that looks for an email with a subject then move the email to a subfolder then runs a script that move the email attachment to a folder on the C drive and then deletes the original email from the subfolder
Everything seem to be setup correctly, security is ok, and the macro runs as a macro outside the rule It's just the rule doesn't run the script, here is the script I'm using
Sub Get_SOH_All(MyMail As MailItem)
On Error GoTo SaveAttachmentsToFolder_err
Dim ns As NameSpace
Dim Inbox As MAPIFolder
Dim SubFolder As MAPIFolder
Dim item As Object
Dim Atmt As Attachment
Dim FileName As String
Dim i As Integer
Dim varResponse As VbMsgBoxResult
Set ns = GetNamespace("MAPI")
Set Inbox = ns.GetDefaultFolder(olFolderInbox)
Set SubFolder = Inbox.Folders("DATA DUMP") ' Enter correct subfolder name.
i = 0
If Len(Dir("c:\DATA DUMP\Stock On Hand", vbDirectory)) = 0 Then
MkDir "c:\DATA DUMP\Stock On Hand"
End If
For Each item In SubFolder.Items
For Each Atmt In item.Attachments
If Right(Atmt.FileName, 3) = "csv" Then
FileName = "C:\DATA DUMP\Stock On Hand\"
Atmt.SaveAsFile FileName & "Stock_On_Hand_All.csv"
item.Delete
i = i + 1
End If
Next Atmt
Next item
SaveAttachmentsToFolder_exit:
Set Atmt = Nothing
Set item = Nothing
Set ns = Nothing
Exit Sub
SaveAttachmentsToFolder_err:
MsgBox "An unexpected error has occurred." _
& vbCrLf & "Please note and report the following information to Jarrod Hall." _
& vbCrLf & "Macro Name: GetAttachmentsSOH" _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description: " & Err.Description _
, vbCritical, "Error!"
Resume SaveAttachmentsToFolder_exit
End Sub
The code in a script is normally used on one item not multiple.
The mail is to be deleted so you can drop the part of the rule that moves the mail and try this.
Sub Get_SOH_All(MyMail As MailItem)
On Error GoTo SaveAttachmentsToFolder_err
Dim Atmt As Attachment
Dim FileName As String
If Len(Dir("c:\DATA DUMP\Stock On Hand", vbDirectory)) = 0 Then
MkDir "c:\DATA DUMP\Stock On Hand"
End If
For Each Atmt In MyMail.Attachments
If Right(Atmt.FileName, 3) = "csv" Then
FileName = "C:\DATA DUMP\Stock On Hand\"
Atmt.SaveAsFile FileName & "Stock_On_Hand_All.csv"
MyMail.Delete
End If
Next Atmt
SaveAttachmentsToFolder_exit:
Set MyMail = Nothing
Exit Sub
SaveAttachmentsToFolder_err:
MsgBox "An unexpected error has occurred." _
& vbCrLf & "Please note and report the following information to Jarrod Hall." _
& vbCrLf & "Macro Name: GetAttachmentsSOH" _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description: " & Err.Description _
, vbCritical, "Error!"
Resume SaveAttachmentsToFolder_exit
End Sub

Rule does not run when a new email comes in

I worked out the code below to save an attachment to an email, to a mapped network drive, based on the subject line. However the rule in Outlook 2010 (xp OS) doesn't work when a new email comes in. It doesn't save it to the specified location. When I run the rule manually it works great.
I have enabled all macros. restarted Outlook no change. I have made macros prompt when running. It prompts when a new email comes in. I hit enable no save, no error that it didn't save.
Public Sub SaveAttachments2(mail As Outlook.MailItem)
On Error GoTo GetAttachments_err
Dim ns As NameSpace
Dim Inbox As MAPIFolder
Dim Item As Object
Dim Atmt As Attachment
Dim FileName As String
Dim i As Integer
Dim f As String
Dim strSubject As String
Dim w As Integer
Set ns = GetNamespace("MAPI")
Set Inbox = ns.GetDefaultFolder(olFolderInbox)
For Each Item In Inbox.Items
strSubject = Item.Subject
f = strSubject
Rem MkDir ("Z:\OPERATIO\AS400_Report\" & f)
For Each Atmt In Item.Attachments
FileName = "Z:\OPERATIO\AS400_Reports\" & f & "\" & Atmt.FileName
Atmt.SaveAsFile FileName
i = i + 1
'commented out and added rule option to delete the item
Next Atmt
'Item.Delete
GetAttachments_exit:
Set Atmt = Nothing
Set Item = Nothing
Set ns = Nothing
Exit Sub
GetAttachments_err:
MsgBox "An unexpected error has occurred." _
& vbCrLf & "Please note and report the following information." _
& vbCrLf & "Macro Name: SaveAttachments2" _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description: " & Err.Description _
, vbCritical, "Error!"
Resume GetAttachments_exit
'added next because of compile error
Next
End Sub
You cannot change standalone VBA by simply adding (mail As Outlook.MailItem).
Public Sub SaveAttachments2(mail As Outlook.mailItem)
Dim Atmt As attachment
Dim FileName As String
Dim f As String
f = Trim(mail.Subject) ' Removes spaces at ends. This is a big problem.
On Error Resume Next
MkDir ("Z:\OPERATIO\AS400_Report\" & f) ' Creates a folder if it does not exist
On Error GoTo GetAttachments_err
For Each Atmt In mail.Attachments
FileName = "Z:\OPERATIO\AS400_Reports\" & f & "\" & Atmt.FileName
Atmt.SaveAsFile FileName
' Fails on subjects with illegal characters.
' For example when RE: and FW: in the subject the folder cannot be created.
Next Atmt
GetAttachments_exit:
Exit Sub
GetAttachments_err:
MsgBox "An unexpected error has occurred." _
& vbCrLf & "Please note and report the following information." _
& vbCrLf & "Macro Name: SaveAttachments2" _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description: " & Err.Description _
, vbCritical, "Error!"
Resume GetAttachments_exit
End Sub
See here if illegal characters cause problems creating folders. Save mail with subject as filename