In the code below I don’t understand how the subroutine checks if the emails coming through are a reply of an email previously sent.
The first subroutine seems to check if the subject line of an incoming email matches this condition: "re: " & strSubject Or InStr(LCase(Item.Subject), strSubject)
After that I am confused. The only way the code works for me is by using categories. It does not work as shown below.
Public WithEvents objInboxItems As Outlook.Items
Private Sub Application_Startup()
Set objInboxItems = Application.Session.GetDefaultFolder(olFolderInbox).Items
End Sub
'If receive the reply, clear the flag and remove the reminder
Private Sub objInboxItems_ItemAdd(ByVal Item As Object)
Dim objSentItems As Outlook.Items
Dim objVariant As Variant
Dim i As Long
Dim strSubject As String
Dim dSendTime As String
Set objSentItems = Outlook.Application.Session.GetDefaultFolder(olFolderSentMail).Items
If Item.Class = olMail Then
For i = 1 To objSentItems.Count
If objSentItems.Item(i).Class = olMail And **objSentItems.Item(i).categories = "Not Completed"** Then
Set objVariant = objSentItems.Item(i)
strSubject = LCase(objVariant.Subject)
dSendTime = objVariant.SentOn
If LCase(Item.Subject) = "re: " & strSubject Or InStr(LCase(Item.Subject), strSubject) > 0 Then
If Item.SentOn > dSendTime Then
With objVariant
.ClearTaskFlag
.ReminderSet = False
.Save
End With
End If
End If
End If
Next i
End If
End Sub
'Get a prompt asking if to send a notification email
Private Sub Application_Reminder(ByVal Item As Object)
Dim strPrompt As String
Dim nResponse As Integer
Dim objFollowUpMail As Outlook.MailItem
'You can change the subject as per your real case
If (Item.Class = olMail) And (LCase(Item.Subject) = "datanumen outlook repair") Then
strPrompt = "You haven't yet recieved the reply of " & Chr(34) & Item.Subject & Chr(34) & " within your expected time. Do you want to send a follow-up notification email?"
nResponse = MsgBox(strPrompt, vbYesNo + vbQuestion, "Confirm to Send a Follow-Up Notification Email")
If nResponse = vbYes Then
Set objFollowUpMail = Application.CreateItem(olMailItem)
With objFollowUpMail
.To = Item.Recipients.Item(1).Address
.Subject = "Follow Up: " & Chr(34) & Item.Subject & Chr(34)
.Body = "Please respond to my email " & Chr(34) & Item.Subject & Chr(34) & "as soon as possible"
.attachments.Add Item
.Display
End With
End If
End If
End Sub
The code just needs better commenting. The basic logic is: When a new email comes in, check if it's a reply to any email in the sent box. If so, remove the task and reminder flags from the sent email.
Public WithEvents objInboxItems As Outlook.Items
Private Sub Application_Startup()
Set objInboxItems = Application.Session.GetDefaultFolder(olFolderInbox).Items
End Sub
'If receive the reply, clear the flag and remove the reminder
Private Sub objInboxItems_ItemAdd(ByVal Item As Object) 'New item received in inbox
Dim objSentItems As Outlook.Items
Dim objVariant As Variant
Dim i As Long
Dim strSubject As String
Dim dSendTime As String
' get all emails in sent box
Set objSentItems = Outlook.Application.Session.GetDefaultFolder(olFolderSentMail).Items
If Item.Class = olMail Then 'if new inbox item is email
For i = 1 To objSentItems.Count 'for each item in sent box
If objSentItems.Item(i).Class = olMail Then ' if sent item is email
Set objVariant = objSentItems.Item(i) 'sent email
strSubject = LCase(objVariant.Subject) 'sent email subject
dSendTime = objVariant.SentOn 'sent email send date
'Check subject, if new email is reply to sent email, or new email subject contains sent email subject
If LCase(Item.Subject) = "re: " & strSubject Or InStr(LCase(Item.Subject), strSubject) > 0 Then
If Item.SentOn > dSendTime Then ' if new email has later send date then sent email (else can't be reply)
With objVariant 'with sent email
.ClearTaskFlag ' clear flag
.ReminderSet = False 'remove reminder
.Save
End With
End If
End If
End If
Next i
End If
End Sub
The code listed above is badly written and wrong in general. The ItemAdd event is fired when an item is added to the folder, not received. For example, a user may move some items from one folder to another triggering this event. If you want to handle all incoming emails you need to handle the NewMailEx event of the Application class which is fired 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. This event fires once for every received item that is processed by Microsoft Outlook. The item can be one of several different item types, for example, MailItem, MeetingItem, or SharingItem. The EntryIDsCollection string contains the Entry ID that corresponds to that item.
For i = 1 To objSentItems.Count 'for each item in sent box
If objSentItems.Item(i).Class = olMail Then ' if sent item is email
Instead of interating over all items in the folder and finding items that correspond to your conditions I'd recommend using the Find/FindNext or Restrict methods of the Items class. Read more about these methods in the following articles:
How To: Use Find and FindNext methods to retrieve Outlook mail items from a folder (C#, VB.NET)
How To: Use Restrict method to retrieve Outlook mail items from a folder
I tried to recreate the situation, given flags are not reliable in my setup.
It may be possible to remove reminders by reinitializing ReminderTime.
Code for ThisOutlookSession
Option Explicit
Public WithEvents objInboxItems As Items
Private Sub Application_Startup()
Set objInboxItems = Session.GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub test_objInboxItems_ItemAdd()
' For testing select a reply to the flagged sent item
objInboxItems_ItemAdd ActiveExplorer.Selection(1)
End Sub
Private Sub objInboxItems_ItemAdd(ByVal Item As Object)
' If reply received,
' clear the flag and remove the reminder from the corresponding sent item
' No attempt to make the logic efficient
' - Find / Restrict in the sent items folder
' In my setup
' - TaskDueDate is always 4501-01-01 (no date)
' - Reminders on mailitems are not functional
Dim objSentItems As Items
Dim objVariant As Variant
Dim i As Long
Dim strSubject As String
Set objSentItems = Session.GetDefaultFolder(olFolderSentMail).Items
If Item.Class = olmail Then
Debug.Print
Debug.Print "Item.Subject ...........: " & Item.Subject
For i = 1 To objSentItems.Count
If objSentItems.Item(i).Class = olmail Then
Set objVariant = objSentItems.Item(i)
strSubject = LCase(objVariant.Subject)
If objVariant.ReminderTime <> "4501-01-01" Then
Debug.Print " strSubject ............: " & strSubject
Debug.Print " objVariant.SentOn .....: " & objVariant.SentOn
Debug.Print " objVariant.ReminderTime: " & objVariant.ReminderTime
If LCase(Item.Subject) = "re: " & strSubject Or InStr(LCase(Item.Subject), strSubject) > 0 Then
'Debug.Print " Item.SentOn .....: " & Item.SentOn
'Debug.Print " objVariant.SentOn: " & objVariant.SentOn
If Item.SentOn > objVariant.SentOn Then
Debug.Print " * strSubject ......: " & strSubject
Debug.Print " * Item.SentOn .....: " & Item.SentOn
Debug.Print " * objVariant.SentOn: " & objVariant.SentOn
If Now > objVariant.ReminderTime Then
With objVariant
' remove flag
.ClearTaskFlag
' attempt to remove reminder
.ReminderSet = False
' reinitializing ReminderTime may have an impact
.ReminderTime = "4501-01-01"
.Save
Debug.Print " ** Flag removed."
Debug.Print " ** Reminder removal attempted."
End With
End If
End If
Else
Debug.Print " *** subject does not match"
End If
End If
End If
Next i
End If
Debug.Print "done"
End Sub
Private Sub test_ToggleMarkAsTaskFlagAndSetReminder()
' for testing
' select a mailitem in the sent items folder to add a flag and a reminder
ToggleMarkAsTaskFlagAndSetReminder ActiveExplorer.Selection(1)
End Sub
Private Sub ToggleMarkAsTaskFlagAndSetReminder(ByVal objItem As Object)
' In my setup
' - TaskDueDate is always 4501-01-01 (no date)
' - Reminders on mailitems are not functional
If TypeOf objItem Is MailItem Then
Debug.Print
Debug.Print "objItem.Subject .............: " & objItem.Subject
Debug.Print " objItem.TaskDueDate Current: " & objItem.TaskDueDate
Debug.Print " objItem.ReminderTime Current: " & objItem.ReminderTime
' https://learn.microsoft.com/en-us/office/vba/api/outlook.olmarkinterval
If objItem.IsMarkedAsTask = False Then
objItem.MarkAsTask (olMarkThisWeek)
Debug.Print " * Marked as task"
' In my setup - TaskDueDate is always 4501-01-01
Debug.Print " objItem.TaskDueDate Updated?: " & objItem.TaskDueDate
Debug.Print " objItem.ReminderTime Updated?: " & objItem.ReminderTime
' In my setup - Reminders on mailitems are not functional
Debug.Print " objItem.ReminderSet Current: " & objItem.ReminderSet
objItem.ReminderSet = True
Debug.Print " objItem.ReminderSet Updated: " & objItem.ReminderSet
objItem.ReminderTime = DateAdd("d", -7, Now) ' testing
Debug.Print " objItem.ReminderTime Updated: " & objItem.ReminderTime
Else 'Reinitialize item
objItem.ClearTaskFlag
Debug.Print " * Task cleared"
' TaskDueDate not functional in my setup, remains 4501-01-01
Debug.Print " objItem.TaskDueDate Updated?: " & objItem.TaskDueDate
objItem.ReminderSet = False
Debug.Print " objItem.ReminderSet = False"
objItem.ReminderTime = "4501-01-01"
Debug.Print " objItem.ReminderTime Updated: " & objItem.ReminderTime
End If
'objItem.Display
objItem.Save
Else
Debug.Print "not a mailitem"
End If
End Sub
Related
I made the following script to rename incoming mails as a rule in Outlook:
Sub RenameMails(MyMail As MailItem)
Dim strID As String
Dim objMail As Outlook.MailItem
strID = MyMail.EntryID
Set objMail = Application.Session.GetItemFromID(strID)
If Left(objMail.Subject, 4) = "FW: " Then
objMail.Subject = Right(objMail.Subject, Len(objMail.Subject) - 4)
objMail.Subject = "Test: " & objMail.Subject
objMail.Save
End If
Set objMail = Nothing
End Sub
This works for regular incoming mails, but if the mail is an invite to a Teams Meeting, it doesn't change the subject. I suspect it is because it's also not possible to rename the mail itself in outlook, but it is possible to rename the appointment in the calendar.
How do I go from here to renaming the appointment that is associated to this mail?
An invite is not a mailitem.
Option Explicit
Sub RenameIncomingItems(myObj As Object)
Debug.Print
Debug.Print TypeName(myObj)
If Left(myObj.subject, 4) = "FW: " Then
myObj.subject = Right(myObj.subject, Len(myObj.subject) - 4)
myObj.subject = "Test: " & myObj.subject
myObj.Save
Debug.Print " Subject saved: " & myObj.subject
Else
Debug.Print " FW: not found"
End If
End Sub
Private Sub test()
RenameIncomingItems ActiveInspector.CurrentItem
End Sub
I made it work like this:
Sub RenameMails(objMail As Object)
Dim myAppt As Outlook.AppointmentItem
If (Left(objMail.Subject, 4) = "FW: ") Then
objMail.Subject = Right(objMail.Subject, Len(objMail.Subject) - 4)
objMail.Subject = "Test: " & objMail.Subject
objMail.Save
End If
If (objMail.Class = olMeetingRequest) Then
Set myAppt = objMail.GetAssociatedAppointment(True)
If (Left(myAppt.Subject, 4) = "FW: ") Then
myAppt.Subject = Right(myAppt.Subject, Len(myAppt.Subject) - 4)
myAppt.Subject = "Test: " & myAppt.Subject
myAppt.Save
End If
End If
End Sub
I have the below code which counts the number of attachments in an email, but the problem is it also counts embedded images. Is there a way to exclude embedded images, so they do not get counted?
Sub CountAttachmentsinSelectedEmails()
Dim olSel As Selection
Dim oMail As Object
Dim AttCount As Long
Dim strMsg As String
Set olSel = Outlook.Application.ActiveExplorer.Selection
For Each oMail In olSel
'To confirm if the selected items are all emails
If oMail.Class <> olMail Then
strMsg = "Please select mail items only!"
nRes = MsgBox(strMsg, vbOKOnly + vbExclamation)
Exit Sub
End If
'Get the total number of the attachments in selected emails
AttCount = oMail.Attachments.Count + AttCount
Next
strMsg = "There are " & AttCount & " attachments in the " & olSel.Count & " selected emails."
nRes = MsgBox(strMsg, vbOKOnly + vbInformation, "Count Attachments")
End Sub
Try the next adapted code, please:
Sub CountAttachmentsinSelectedEmails()
Dim olSel As Selection, nRes As VbMsgBoxResult
Dim oMail As Object, AttCount As Long, strMsg As String
Set olSel = Outlook.Application.ActiveExplorer.Selection
For Each oMail In olSel
'To confirm if the selected items are all emails
If oMail.Class <> olMail Then
strMsg = "Please select mail items only!"
nRes = MsgBox(strMsg, vbOKOnly + vbExclamation)
Exit Sub
End If
'Get the total number of NOT embeded attachments in selected emails
Dim objAtt As Outlook.Attachment
For Each objAtt In oMail.Attachments
If Not IsEmbedded(objAtt) Then
AttCount = AttCount + 1
Debug.Print "Not embedded attachment name: " & objAtt.DisplayName & vbCrLf & _
" from email " & oMail.Subject & vbCrLf & _
" received on: " & oMail.ReceivedTime
End If
Next
Next
strMsg = "There are " & AttCount & " attachments in the " & olSel.count & " selected emails."
nRes = MsgBox(strMsg, vbOKOnly + vbInformation, "Count Attachments")
End Sub
Function IsEmbedded(Att As Attachment) As Boolean
Dim PropAccessor As PropertyAccessor
Set PropAccessor = Att.PropertyAccessor
IsEmbedded = (PropAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001F") <> "")
End Function
You would need to actually look at the HTML body and check if any image referes to the attachment, either through the cid attribute (<img src="cid:xyz">) or through the file name or url. You'd also need to look at the PR_ATTACH_HIDDEN MAPI property.
If using Redemption (I am its author) is an option, it exposes RDOAttachment.Hidden property:
Set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
for each msg in Application.ActiveExplorer.Selection
set rMsg = Session.GetRDOObjectFromOutlookObject(msg)
Debug.Print "-------- " & msg.Subject
for each attach in rMsg.Attachments
Debug.Print attach.Hidden & " - " & attach.FileName
next
next
I need a macro which can match domain name of the email ids in TO and CC from a list of emails(preferably from excel) and if any of the email address does not match, it should throw a pop-up asking if the user wants to continue and if yes then the mail should be sent as it is and a email id should be added in BCC.
Please find the sample code, it works but I also want to compare the domain name as a sub-string in the subject.
Ex: The if the subject line is "ABC Report- Company1- Jan-2 and it is sent to a1#company1.com, a2#compay2.com then it should prompt that the a2#company2.com is an unauthorized email and ask if still the user want to proceed, if Yes it should copy admin#mycompany.com in BCC and delay the mail by 5mins.
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
Dim recips As Outlook.Recipients
Dim recip As Outlook.Recipient
Dim pa As Outlook.PropertyAccessor
Dim prompt As String
Dim strMsg As String
Dim Address As String
Dim lLen
Dim strSubject As String
Const PR_SMTP_ADDRESS As String = "http://schemas.microsoft.com/mapi/proptag/0x39FE001E"
strSubject = Item.Subject
If strSubject Like "*ACB Report*" Or strSubject Like "*XYZ Report*" Then
Set recips = Item.Recipients
For Each recip In recips
Set pa = recip.PropertyAccessor
Address = LCase(pa.GetProperty(PR_SMTP_ADDRESS))
lLen = Len(Address) - InStrRev(Address, "#")
Select Case Right(Address, lLen)
Case "cdolive.com", "gmail.com", "slipstick.com", "outlookmvp.com"
Case Else ' remove case else line to be warned when sending to the addresses
strMsg = strMsg & " " & Address & vbNewLine
End Select
Next
If strMsg <> "" Then
prompt = "This email will be sent outside of the company to:" & vbNewLine & strMsg & vbNewLine & "Please check recipient address." & vbNewLine & vbNewLine & "Do you still wish to send?"
If MsgBox(prompt, vbYesNo + vbExclamation + vbMsgBoxSetForeground, "Check Address") = vbNo Then
Cancel = True
End If
End If
End If
End Sub
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
Dim recips As Outlook.Recipients
Dim recip As Outlook.Recipient
Dim pa As Outlook.PropertyAccessor
Dim prompt As String
Dim strMsg As String
Dim Address As String
Dim lLen
Dim strSubject As String
Const PR_SMTP_ADDRESS As String = "http://schemas.microsoft.com/mapi/proptag/0x39FE001E"
strSubject = Item.subject
If strSubject Like "*ABC Report*" Or strSubject Like "*XYZ Report*" Then
Set recips = Item.Recipients
For Each recip In recips
If recip.Type <> olBCC Then
Set pa = recip.PropertyAccessor
Address = LCase(pa.GetProperty(PR_SMTP_ADDRESS))
'rlen = Len(Address) - InStrRev(Address, "#")
'If strSubject Like "*rlen*" Then
lLen = Len(Address) - InStrRev(Address, "#")
'Select Case Left(Address, rlen)
'Case "acceture", "slipstick"
'Case Else
'strMsg = strMsg & " " & Address & vbNewLine
'End Select
'Next
Dim SendMail As Boolean
Select Case Right(Address, lLen)
Case "cdolive.com", "slipstick.com", "outlookmvp.com", "accenture.com"
' "select case" is doing nothing in this case
SendMail = True
Case Else ' remove case else line to be warned when sending to the addresses
strMsg = strMsg & " " & Address & vbNewLine
End Select
If strMsg <> "" And Not SubjectContainsEmailDomain(strSubject, Address) Then
prompt = "The system has detected that you are sending this email to some unauthorized user:" & vbNewLine & strMsg & vbNewLine & "Please check recipient address." & vbNewLine & vbNewLine & "Do you still wish to send?"
If MsgBox(prompt, vbYesNo + vbExclamation + vbMsgBoxSetForeground, "Check Address") = vbNo Then
Cancel = True
Else
' add BCC
Dim objRecip As Recipient
Set objRecip = Item.Recipients.Add("myid#gmail.com")
objRecip.Type = olBCC
objRecip.Resolve
'MailItem.DeferredDeliveryTime = DateAdd("n", 90, Now)
End If
End If
' Cancel if not in "cdolive.com", "slipstick.com", "outlookmvp.com"
If Not SendMail Then Cancel = True
MsgBox "The entered email address(s) are not aliged to you" & vbNewLine & "Please add the domain name in the code"
'End If
'End If
End If
Next
Last:
End If
End If
End If
End Sub
Function GetDomain(emailAddress As String) As String
Dim arr As Variant
arr = Split(emailAddress, "#")
GetDomain = Left(arr(1), InStrRev(arr(1), ".") - 1)
End Function
Function SubjectContainsEmailDomain(subject As String, email As String) As Boolean
Dim domain As String
domain = GetDomain(email)
Dim index As Integer
SubjectContainsEmailDomain = InStr(LCase(subject), LCase(domain))
End Function
The next to last part of an email address is the Second Level Domain (2LD).
This seems to be finding Recipient2LD that is different from the Subject Company.
The Subject seems to be free form typing by users, and I have no idea how to parse the SubjectCompany out of the Subject line, but if you could then this could be added after EndSelect and before Next.
Dim RecipDomainParts() As String
RecipDomainParts = Split(Right(Address, lLen), ".")
Dim Recip2LD As String ' Recipient Second Level Domain
Recip2LD = DomainParts(UBound(DomainParts) - 1)
' I have no idea how to parse the SubjectCompany out of the Subject line
If Recip2LD <> SubjectCompany Then
strMsg = strMsg & " " & Address & vbNewLine
End If
->>added 9/2/18
you need to decide yourself the general outline of your process: whether to possibly have an error message for each Recipient for each problem (List or Subject) or to combine into one message for a Recipient, while doing each Recipient, or append each msg into one message at the end of all Recipients... Then follow your outline. Work at refining the outline first, then write the code to match.
It may be good to make sub for "Recip_in_List" and make a sub for "RecipDomain_in_Subject" after you revise the outline.
BCC probably should not be skipped, as user might try to put an email there.
Your xyz#qwerty.com should be in the List.
variable SendMail cannot be set to True because it would wipe out False that had been set on prior Recipient. By doing Exit Sub when vbNo you eliminate this boolean.
Set Delay = 0min
For each Recip
If Recip not in List
Popup to user
If vbNo then Cancel=True and exit without send
Else add BCC of xyz#qwerty.com if not there
endif
endif
If RecipDomain not in Subject
Popup to user
If vbNo then Cancel=True and exit without send
Else add BCC of admin#qwerty.com if not there
set Delay = 5min
endif
endif
Next Recip
SEND with Delay
I need to move the incoming message to the related folder depending on a key in the subject of the message.
I developed a script for getting the key in the subject of new message. How can I search rest of messages by a key and retrieve related folder?
Sub CustomMailMessageRule(Item As Outlook.MailItem)
Dim strTicket, strSubject As String
Dim strFolder As String
strTicket = "None"
strSubject = Item.Subject
If InStr(1, strSubject, "#-") > 0 Then
strSubject = Mid(strSubject, InStr(strSubject, "#-") + 2)
If InStr(strSubject, " ") > 0 Then
strTicket = Left(strSubject, InStr(strSubject, " ") - 1)
End If
End If
the unknown part, search all folders by key and retrieve the related folder
strFolder = "???"
and finally, move the incoming message to the related folder by below code
If InStr(strFolder) > 0 Then
Item.Move Session.GetDefaultFolder(olFolderInbox).folders(strFolder)
MsgBox "Your New Message has been moved to related folder "
End Sub
I'm new in VBA.
This searches folders recursively for an item by subject.
Option Explicit
Sub CustomMailMessageRule(Item As mailItem)
Dim strSubject As String
Dim strDynamic As String
Dim strFilter As String
Dim originFolder As Folder
Dim startFolder As Folder
Dim uPrompt As String
strSubject = Item.subject
Set startFolder = Session.GetDefaultFolder(olFolderInbox)
' To reference any inbox not specifically the default inbox
'Set startFolder = Session.folders("email address").folders("Inbox")
Set originFolder = startFolder
' For testing the mail subject is "This is a test"
If InStr(1, strSubject, "This is") > 0 Then
' For testing the dynamically determined key is "a test"
strDynamic = "a test"
strFilter = "#SQL=" & Chr(34) & "urn:schemas:httpmail:subject" & Chr(34) & " LIKE '%" & strDynamic & "%'"
Debug.Print strFilter
' Advanced search requires "Scope" to be specified so it appears
' not easy/possible to process every subfolder in the way described here
' https://stackoverflow.com/questions/43638711/outlook-macro-advanced-search
' This recursively processes every subfolder
processFolder originFolder, startFolder, strFilter, Item
uPrompt = "Mail with " & strDynamic & " in subject not found in subfolders of " & startFolder.Name
Debug.Print uPrompt
MsgBox uPrompt
End If
ExitRoutine:
Set startFolder = Nothing
End Sub
Private Sub processFolder(ByVal originFolder As Folder, ByVal oParent As Folder, strFilter As String, oIncomingMail As mailItem)
Dim oFolder As Folder
Dim oObj As Object
Dim filteredItems As items
Dim uResp As VbMsgBoxResult
Debug.Print oParent
If originFolder.EntryID <> oParent.EntryID Then
' This narrows the search.
' https://stackoverflow.com/questions/21549938/vba-search-in-outlook
Set filteredItems = oParent.items.Restrict(strFilter)
If filteredItems.count > 0 Then
Debug.Print oParent
Debug.Print "Mail found in " & oParent.Name
uResp = MsgBox(Prompt:="Move Message to folder: " & oParent.Name & "?", _
Buttons:=vbYesNoCancel)
If uResp = vbYes Then
oIncomingMail.move oParent
End
End If
If uResp = vbCancel Then End
End If
End If
If (oParent.folders.count > 0) Then
For Each oFolder In oParent.folders
processFolder originFolder, oFolder, strFilter, oIncomingMail
Next
End If
End Sub
I have created a macro in Outlook VBA below that replies with the sender first name added to the greeting, adds some text for the body, and adds a signature in the fonts I want.
What I need help with is getting the macro to pull ALL of the names of the senders, assigning a value to them that I can then place elsewhere in the body of the email. If that cannot be done, I would settle for just getting all of the names into the greeting, though it is much preferred to be able to move the names around.
Example: sender was Name1;Name2
Currently, this macro will pull only Name1 (giving "Dear Name1,"), but
I would like to get to "Dear Name1 and Name2," at the very least.
Best would be able to have Name1 be in the greeting, then Name2 is placed in the body of the text.
I believe I have taken this as far as I can on my own and now turn to you experts for assistance! Thank you!!
Sub AutoAddGreetingtoReply()
Dim oMail As MailItem
Dim oReply As MailItem
Dim GreetTime As String
Dim strbody As String
Dim SigString As String
Dim Signature As String
Dim R As Outlook.Recipient
Dim strGreetName As String
Select Case Application.ActiveWindow.Class
Case olInspector
Set oMail = ActiveInspector.CurrentItem
Case olExplorer
Set oMail = ActiveExplorer.Selection.Item(1)
End Select
strbody = "<H3><B></B></H3>" & _
"<br><br><B></B>" & _
"Please visit this website to view your transactions.<br>" & _
"Let me know if you have problems.<br>" & _
"Questions" & _
"<br><br>Thank you"
SigString = Environ("appdata") & _
"\Microsoft\Signatures\90 Days.htm"
On Error Resume Next
If Dir(SigString) <> "" Then
strGreetName = Left$(oMail.SenderName, InStr(1, oMail.SenderName, " ") - 1)
End If
If Dir(SigString) <> "" Then
Signature = GetBoiler(SigString)
Else
Signature = ""
End If
Set oReply = oMail.ReplyAll
With oReply
.CC = ""
.HTMLBody = "<Font Face=calibri>Dear " & strGreetName & "," & R1 & strbody & "<br>" & Signature
.Display
End With
End Sub
Given a string "First Last" then get the right side of the string like this
sndrName = oMail.SenderName
lastName = right(sndrName, len(sndrName) - InStr(1, sndrName, " "))
Using the format in your code:
strGreetName = Left$(oMail.SenderName, InStr(1, oMail.SenderName, " ") - 1)
lastName = right(oMail.SenderName, len(oMail.SenderName) - InStr(1, oMail.SenderName, " "))
If there is a space in the text InStr returns the position. https://msdn.microsoft.com/en-us/vba/language-reference-vba/articles/instr-function
Original mail has one sender. A ReplyAll has recipients, including the original mail sender.
Option Explicit
Private Sub ReplyFirstNames()
Dim oMail As mailitem
Dim oReply As mailitem
Dim strGreetName As String
Dim strGreetNameAll As String
Dim i As Long
Select Case Application.ActiveWindow.Class
Case olInspector
Set oMail = ActiveInspector.currentItem
Case olExplorer
Set oMail = ActiveExplorer.Selection.Item(1)
End Select
Set oReply = oMail.ReplyAll
With oReply
Debug.Print "The reply all recipients are:"
For i = 1 To .Recipients.count
Debug.Print .Recipients(i)
' Given the format First Last
strGreetName = Left(.Recipients(i), InStr(1, .Recipients(i), " ") - 1)
strGreetNameAll = strGreetNameAll & strGreetName & ", "
Next i
Debug.Print strGreetNameAll
' remove extra comma and space from end
strGreetNameAll = Left(strGreetNameAll, Len(strGreetNameAll) - 2)
Debug.Print strGreetNameAll
.htmlbody = "<Font Face=calibri>" & strGreetNameAll & .htmlbody
.Display
End With
End Sub