Run Script to Append Subject and Body of Email - vba

I am [attempting to] learn how to write a script in Outlook that when a certain category is set on an email:
Append the Subject with " PROJ=5"
Append the Body with about 10 lines of text
Send email.
My goal is to mark an email with a category and forward the email to our ticketing system.
I'm not really having any luck with the samples I have found.
Samples (URL) I have tried (Copied code and updated relevant fields):
slipstick.com
social.technet.microsoft.com

Append the Subject with " PROJ=5"
MailItem.Subject Property Returns a String indicating Outlook item. Read/write.
Example
Item.Subject = "PROJ=5" & Item.Subject
Append the Body with about 10 lines of text
Example
Dim olBody As String
olBody = "<HTML><BODY><P>Append the Body with about 10 lines of text</P>" & vbNewLine & vbNewLine & _
"<P>Append the Body with about 10 lines of text</P></HTML></BODY>" & vbNewLine
olForward.HTMLBody = olBody & vbCrLf & olForward.HTMLBody
Send / Forward Email
Example
'//
Set olForward = Item.Forward
'// add Recipent
olForward.Recipients.Add "email#domain.com"
'// Send or your use .Dispaly
olForward.Send
Run a Script Rule
To use Rule Wizard, your macro has to have the expected parameter:
Example
Public Sub ItemForward(Item As Outlook.MailItem)
End Sub
Helpful article in MSDN Outlook 2010 VBA
Complete Code Test on Outlook 2010 VBA
Please make sure your References are set to run action script (Tools > References)
Option Explicit
'// Run Action Script
Public Sub ItemForward(Item As Outlook.MailItem)
Dim olApp As Outlook.Application
Dim olForward As MailItem
Dim olBody As String
Set olApp = CreateObject("Outlook.Application")
'// Append the Subject
Item.Subject = "PROJ=5 " & Item.Subject
Item.Save
Set olForward = Item.Forward
'// add Recipent
olForward.Recipients.Add "Test#mail.com"
olBody = "<HTML><BODY><P>Append the Body with about 10 lines of text</P>" & vbNewLine & vbNewLine & _
"<P>Append the Body with about 10 lines of text</P>" & vbNewLine & _
"<P>Append the Body with about 10 lines of text</P>" & vbNewLine & _
"<P>Append the Body with about 10 lines of text</P>" & vbNewLine & _
"<P>Append the Body with about 10 lines of text</P>" & vbNewLine & _
"<P>Append the Body with about 10 lines of text</P>" & vbNewLine & _
"<P>Append the Body with about 10 lines of text</P>" & vbNewLine & _
"<P>Append the Body with about 10 lines of text</P>" & vbNewLine & _
"<P>Append the Body with about 10 lines of text</P>" & vbNewLine & _
"<P>Append the Body with about 10 lines of text</P></HTML></BODY>" & vbNewLine
'// Forward Email
olForward.HTMLBody = olBody & vbCrLf & olForward.HTMLBody
'// Send or your use .Dispaly
olForward.Send
Set olApp = Nothing
Set olForward = Nothing
End Sub

Related

Email address in vba not displaying correctly

I have everything working to send an email via an Access command button. However, the displayed email address is incorrect.
Private Sub cmdSendEmail_Click()
Dim EmailApp, NameSpace, EmailSend As Object
Set EmailApp = CreateObject("Outlook.Application")
Set NameSpace = EmailApp.GetNamespace("MAPI")
Set EmailSend = EmailApp.CreateItem(0)
EmailSend.To = [emailadd] '[emailadd] is the field on the form where the button is located
EmailSend.Subject = [Forms]![WorkordersVR]![Project] & " - " & [Forms]![WorkordersVR]![JobNumber]
EmailSend.Body = "Hello," & vbCrLf & vbCrLf & _
"The project" & " " & [Forms]![WorkordersVR]![Project] & " " & "is ready for pickup." & vbCrLf & vbCrLf & _
"Thank you!" & vbCrLf & vbCrLf & _
"Person sending email here" & vbCrLf & _
EmailSend.Display
Set EmailApp = Nothing
Set NameSpace = Nothing
Set EmailSend = Nothing
End Sub
What ends up in the displayed email To is:
"fred#aplace.com#fred#aplace.com#"
How do I get fred#aplace.com?
You can use string functions available in VBA to get a substring until the # symbol in the string. For example, the InStr function returns a number specifying the position of the first occurrence of one string within another.
Also I'd suggest using the Recipients property of the MailItem class which returns a Recipients collection that represents all the recipients for the Outlook item. Then I'd suggest using the Recipient.Resolve method which attempts to resolve a Recipient object against the Address Book.
For example:
Sub CreateStatusReportToBoss()
Dim myItem As Outlook.MailItem
Dim myRecipient As Outlook.Recipient
Set myItem = Application.CreateItem(olMailItem)
Set myRecipient = myItem.Recipients.Add("email")
myRecipient.Resolve
If(myRecipient.Resolved) Then
myItem.Subject = "Status Report"
myItem.Display
End If
End Sub

Extracting Data Relating To Reminders Snoozed

I have no VBA knowledge but am on a passage of learning. I have obtained the following coding from a public source (Diane Peremsky) of outlook forums. It has a bug I am working on to resolve and strangely returns different data on successive iterations.
Could somebody try provide (or guide me) to add the first 3 lines of the message body to which it refers?
Sub SnoozedReminders()
Dim oReminder As Reminder
Dim oReminders As Outlook.Reminders
Dim RemItems As String
Set oReminders = Outlook.Reminders
For Each oReminder In oReminders
If (oReminder.OriginalReminderDate <> oReminder.NextReminderDate) Then
RemItems = RemItems & oReminder.Caption & vbCrLf & _
"Original Reminder time: " & oReminder.OriginalReminderDate & vbCrLf & _
"Snoozed to: " & oReminder.NextReminderDate & vbCrLf _
& vbCrLf
End If
Next oReminder
Set oMail = Application.CreateItem(olMailItem)
oMail.Subject = "Generated on " & Now
oMail.Body = RemItems
oMail.Display
End Sub
The Reminder.Item property returns a corresponding Outlook item. So, you may get the message body from there.
Sub SnoozedReminders()
Dim oReminder As Reminder
Dim oReminders As Outlook.Reminders
Dim RemItems As String
Set oReminders = Outlook.Reminders
For Each oReminder In oReminders
If (oReminder.OriginalReminderDate <> oReminder.NextReminderDate) Then
RemItems = RemItems & oReminder.Caption & vbCrLf & "Original Reminder time: " &
oReminder.OriginalReminderDate & vbCrLf & "Snoozed to: " & oReminder.NextReminderDate & vbCrLf
& vbCrLf
End If
MsgBox oReminder.Item.Body
Next oReminder
...
End Sub
The Outlook object model provides three main ways for working with item bodies:
Body.
HTMLBody.
The Word editor. The WordEditor property of the Inspector class returns an instance of the Word Document which represents the message body.
See Chapter 17: Working with Item Bodies for more information.

Sending meeting requests using ical through outlook

Here is my dilemma. I have a vb.net application for requesting time using an asset. The user submits a request (can contain required and optional users), then an approver has to approve it. When it is approved, I want to send a meeting request. I can't do it using outlook code since it won't let me change the organizer. If I try to send it using outlook.application > outlook.olitemtype.olappointmentitem or whatever it is, it will default the organizer to the person sending the meeting request, which in this case is the approver, which I don't want. So I think I am left with trying to send an ical. This is where I am having issues. I can't use smtpclient to create the email and send it using the proper content-type, etc. I have to send it using outlook. So I create an ics file and add it as an attachment. I am not sure the difference between METHOD:PUBLISH and METHOD:REQUEST. All the searches I've have done say I should use method:request, but when i open the ICS file, it doesn't give me the options to accept, etc. It doesn't add to my calendar. I want the ability to be able to update and cancel the meeting as well, which I think I know how to do with uid, sequence, etc. I've done searches and just can't get to where I need to be. It looks like the best option is to use smtpclient to create the mail message where you add the headers and ical stuff, but I can't do that, is there a way to it using outlook?
If someone can help point me in the right direction, I would greatly appreciate it.
Here is my current code:
Dim msg As MailMessage = New MailMessage
msg.From = New MailAddress(br.requesting_user_email)
msg.To.Add(New MailAddress(br.requesting_user_email))
msg.Subject = variables.UserInfo.last_name & ", " + variables.UserInfo.first_name & " has approved your request through the Bench Scheduler."
Dim bodytxt As String = "User: " & variables.UserInfo.last_name & ", " + variables.UserInfo.first_name & vbLf & "5+2: " + variables.UserInfo.username & vbLf & vbLf
bodytxt += "Has approved your bench request for " & br.program_name & " - " & br.project_name & "." & vbLf & vbLf
bodytxt += "Start: " & br.start_time & vbLf & "End: " & br.end_time & vbLf
bodytxt += "Bench: " & br.bench_name & vbLf & "Priority: " & br.priority & vbLf & "Purpose: " & br.objective & vbLf & vbLf
bodytxt += "Request Notes: " & br.notes & vbLf & vbLf
bodytxt += vbLf & vbLf & vbLf & "This email was automatically generated by Bench Scheduler. You may respond to this email."
msg.Body = bodytxt
Dim str As StringBuilder = New StringBuilder
str.AppendLine("BEGIN:VCALENDAR")
str.AppendLine("PRODID:-//Microsoft Corporation//Outlook 15.0 MIMEDIR//EN")
str.AppendLine("VERSION:2.0")
If cancel Then
str.AppendLine("METHOD:CANCEL")
Else
str.AppendLine("METHOD:REQUEST")
End If
str.AppendLine("BEGIN:VEVENT")
str.AppendLine("X-MS-OLK-FORCEINSPECTOROPEN:TRUE")
str.AppendLine("BEGIN:VTIMEZONE")
str.AppendLine("TZID:Eastern Standard Time")
str.AppendLine("BEGIN:STANDARD")
str.AppendLine("DTSTART:16011104T020000")
str.AppendLine("RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11")
str.AppendLine("TZOFFSETFROM:-0400")
str.AppendLine("TZOFFSETTO:-0500")
str.AppendLine("END:STANDARD")
str.AppendLine("BEGIN:DAYLIGHT")
str.AppendLine("DTSTART:16010311T020000")
str.AppendLine("RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3")
str.AppendLine("TZOFFSETFROM:-0500")
str.AppendLine("TZOFFSETTO:-0400")
str.AppendLine("END:DAYLIGHT")
str.AppendLine("END:VTIMEZONE")
Dim dt As New DataTable
Dim ta As New BSDataSetTableAdapters.getUserRequestTableAdapter
dt = ta.GetData(br.request_id, "T")
For Each row As DataRow In dt.Rows
If row("type") = "Required" Then
str.AppendLine(String.Format("ATTENDEE;CN='{0}';RSVP=TRUE:mailto:{1}", row("username"), row("email")))
ElseIf row("type") = "Optional" Then
str.AppendLine(String.Format("ATTENDEE;CN='{0}';ROLE=OPT-PARTICIPANT;RSVP=TRUE:mailto:{1}", row("username"), row("email")))
End If
Next
str.AppendLine("CLASS:PUBLIC")
str.AppendLine("CREATED:" & Format(Date.Now, "yyyyMMddTHHmmssZ"))
str.AppendLine(String.Format("DESCRIPTION:{0}", br.objective))
str.AppendLine("DTEND;TZID=" & """" & "Eastern Standard Time" & """" & ":" & Format(CDate(br.end_time), "yyyyMMddTHHmmss"))
str.AppendLine("DTSTAMP:" & Format(Date.Now, "yyyyMMddTHHmmssZ"))
str.AppendLine("DTSTART;TZID=" & """" & "Eastern Standard Time" & """" & ":" & Format(CDate(br.start_time), "yyyyMMddTHHmmss"))
str.AppendLine(String.Format("LOCATION:{0}", br.bench_name))
str.AppendLine(String.Format("ORGANIZER;CN='" & br.requesting_username & "':mailto:" & br.requesting_user_email))
str.AppendLine("PRIORITY:5")
str.AppendLine("SEQUENCE:0")
str.AppendLine(String.Format("SUMMARY;LANGUAGE=en-us:{0}", "Approved Bench Request (ID-" & br.request_id & "): " & br.program_name & "-" & br.project_name & "-" & br.activity))
str.AppendLine("TRANSP:OPAQUE")
str.AppendLine(String.Format("UID:{0}", br.uid))
str.AppendLine(String.Format("X-ALT-DESC;FMTTYPE=text/html:{0}", br.objective))
str.AppendLine("X-MICROSOFT-CDO-BUSYSTATUS:BUSY")
str.AppendLine("X-MICROSOFT-CDO-IMPORTANCE:1")
str.AppendLine("X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY")
str.AppendLine("X-MICROSOFT-DISALLOW-COUNTER:FALSE")
str.AppendLine("X-MS-OLK-AUTOFILLLOCATION:FALSE")
str.AppendLine("X-MS-OLK-CONFTYPE:0")
str.AppendLine("BEGIN:VALARM")
str.AppendLine("TRIGGER:-PT30M")
str.AppendLine("ACTION:DISPLAY")
str.AppendLine("DESCRIPTION:Reminder")
str.AppendLine("END:VALARM")
str.AppendLine("END:VEVENT")
str.AppendLine("END:VCALENDAR")
Dim smtpclient As SmtpClient = New SmtpClient
smtpclient.Host = "replaced for privacy"
smtpclient.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials
Dim contype As System.Net.Mime.ContentType = New System.Net.Mime.ContentType("text/calendar")
contype.Parameters.Add("method", "REQUEST")
contype.Parameters.Add("name", "Meeting.ics")
Dim avcal As AlternateView = AlternateView.CreateAlternateViewFromString(str.ToString, contype)
msg.AlternateViews.Add(avcal)
smtpclient.Send(msg)

How can I automatically send email from Thunderbird with Excel VBA?

What I want to do is send an email from a Thunderbird account automatically. The user shouldn't even have to hit the Send button of the email.
I've tried using CDO, but the problem with it is that you have to input the username and password of the account you are sending from. This macro will be used from several different accounts, so inputting each username and password isn't feasible. I could use CDO if there was someway of retrieving the username, password, and smtp server from Thunderbird, but I feel like the code I already have should be able to accomplish this without CDO (hopefully).
Here is really the only code I see (and it's everywhere) in regards to accomplishing this.
Sub Thunderbird()
Dim thund As String
Dim email As String
Dim cc As String
Dim bcc As String
Dim subj As String
Dim body As String
email = "email#test.com"
cc = "cc#test.com"
bcc = "bcc#test.com"
subj = "Subject"
body = "body text"
thund = "C:\Program Files (x86)\Mozilla Thunderbird\thunderbird.exe"
thund = thund & " -compose " & Chr$(34) & "mailto:" & email & "?"
thund = thund & "cc=" & Chr$(34) & cc & "?"
thund = thund & "bcc=" & Chr$(34) & bcc & "?"
thund = thund & "subject=" & Chr$(34) & subj & Chr$(34)
thund = thund & "body=" & Chr$(34) & body
Call Shell(thund, vbNormalFocus)
SendKeys "^+{ENTER}", True
End Sub
As of right now, the fields cc, bcc, subj, and body are all recognized correctly. The problem is they all get added to the end of the first field. For instance, with the way the code is right now, cc will get put in the cc field, but bcc, subj, and body all get appended to cc in the cc field of Thunderbird.
If I comment cc out, then bcc is put in the correct field, but subj and body get appended to bcc in the bcc field of Thunderbird.
If I comment cc and bcc out, then subj gets put in the correct field, but body gets appended to subj in the subject field of Thunderbird.
So basically I need to add the correct code at the end of each of these lines. I've tried both "?" and Chr$(34) to no avail.
Lastly, SendKeys "^+{ENTER}", True isn't working at all. This might be because of all the parameters not being put in the correct field of Thunderbird, but not sure since I can't get that working. Email from Thunderbird displays, but this code isn't sending the email like it's supposed to.
SOLUTION (as provided by #zedfoxus)
Sub Thunderbird()
Dim thund As String
Dim email As String
Dim cc As String
Dim bcc As String
Dim subj As String
Dim body As String
email = "email#test.com"
cc = "cc#test.com"
bcc = "bcc#test.com"
subj = "Subject"
body = "body text"
thund = "C:\Program Files (x86)\Mozilla Thunderbird\thunderbird.exe" & _
" -compose " & """" & _
"to='" & email & "'," & _
"cc='" & cc & "'," & _
"bcc='" & bcc & "'," & _
"subject='" & subj & "'," & _
"body='" & body & "'" & """"
Call Shell(thund, vbNormalFocus)
Application.Wait (Now + TimeValue("0:00:03"))
SendKeys "^{ENTER}", True
End Sub
You were pretty close. Try this:
Public Sub SendEmail()
Dim thund As String
Dim email As String
Dim cc As String
Dim bcc As String
Dim subj As String
Dim body As String
email = "test#test.com"
cc = "test#test.com"
bcc = "test#test.com"
subj = "Testing"
body = "Testing"
thund = "C:\Program Files (x86)\Mozilla Thunderbird\thunderbird.exe " & _
"-compose " & """" & _
"to='" & email & "'," & _
"cc='" & cc & "'," & _
"bcc='" & bcc & "'," & _
"subject='" & subj & "'," & _
"body='" & body & "'" & """"
Call Shell(thund, vbNormalFocus)
SendKeys "^+{ENTER}", True
End Sub
Notice the example from http://kb.mozillazine.org/Command_line_arguments_(Thunderbird).
thunderbird -compose "to='john#example.com,kathy#example.com',cc='britney#example.com',subject='dinner',body='How about dinner tonight?',attachment='C:\temp\info.doc,C:\temp\food.doc'"
The example indicates that after -compose we should use type our information in double-quotes. Each parameter is separated by comma. Nomenclature is parameter='value[,value]' [,parameter='value[,value]]....

vba + Selection.Paste into outlook + control poition

What I am trying to do is copy a chart from excel into an outlook email, but after numerous searching I am struggling.
i am having trouble positioning where the chart is pasted. I want it to paste after the last line "this is another line again " in the body of the email. It currently pastes at the start of the email before the line "test ... body"
Sub CopyAndPasteToMailBody3() ' this works but how do i control where it puts the chart?
Set mailApp = CreateObject("Outlook.Application")
Set mail = mailApp.CreateItem(olMailItem)
mail.Display
mail.To = "A#a.com"
mail.subject = "subject" & Now
mail.body = "test ... body" & vbNewLine & vbNewLine _
& "this is another line " & vbCrLf _
& "this is another line again "
Set wEditor = mailApp.ActiveInspector.wordEditor
ActiveChart.ChartArea.Copy ' chart needs to be active
wEditor.Application.Selection.Paste
' mail.send
End Sub
Note: using excel 10 on windows 7
I have found that
Set wEditor = mailapp.ActiveInspector.WordEditor
needs to be followed by
wEditor.Range(0, 0).Select
to avoid an error sometimes when you go to paste it.
You can modify the code put the Body on the Clipboard and Paste it:
Set mailApp = CreateObject("Outlook.Application")
Set mail = mailApp.CreateItem(olMailItem)
mail.Display
mail.To = "A#a.com"
mail.Subject = "subject" & Now
Dim Clip As MSForms.DataObject
Set Clip = New MSForms.DataObject
Clip.SetText ("test ... body" & vbNewLine & vbNewLine _
& "this is another line " & vbCrLf _
& "this is another line again " & vbNewLine & " ")
Clip.PutInClipboard
Set wEditor = mailApp.ActiveInspector.wordEditor
wEditor.Application.Selection.Paste
ActiveChart.ChartArea.Copy ' chart needs to be active
wEditor.Application.Selection.Paste
' mail.send
In this case you can assembly the mail as you want.
MSForms.DataObject need to have the Reference: Microsoft Form 2.0 Object Library (FM20.DLL)
You can try also with another code (in this case the image are temporary saved on disk):
Sub CopyAndPasteToMailBody4() ' this works but how do i control where it puts the chart?
Set mailApp = CreateObject("Outlook.Application")
Set mail = mailApp.CreateItem(0)
mail.Display
mail.To = "A#a.com"
mail.Subject = "subject" & Now
Dim Stri As String
Stri = "test ... body" & vbNewLine & vbNewLine _
& "this is another line " & vbCrLf _
& "this is another line again " & vbNewLine & " "
ActiveChart.Export "e:\0\C1.png"
Stri = Stri & "<img src='e:\0\C1.png'>"
mail.HTMLBody = Stri
' mail.send
End Sub
On my PC the first code ask me some permission, with the second code no...