Appening to Subject and Send message Outlook VBA - vba

I'm trying to create a macro that will add some text into the subject of a message and then send the message. I ahve created a button on the ribbon that the user will click to add (Secure) into the subject line and send the message.
I'm using the following which I've put together from several sources I found online.
Sub InsertSubject()
Dim objMsg As Outlook.MailItem
'Get the currently open message'
Set objMsg = Outlook.Application.ActiveInspector.CurrentItem
objMsg.Subject = CurrentItem.Subject & "(Secure) "
'Destroy the object to avoid memory leaks'
objMsg.Send
Set objMsg = Nothing
End Sub
when I run this I get a Run-time error 424 Object Required. It appears to have an issue with the following line
objMsg.Subject = CurrentItem.Subject & "(Secure) "
If I remove the CurrentItem.Subject, the code works but obviously just replaces what ever subject with (Secure).
Any help would be greatly appreciated.

I think you are intending to do objMsg.Subject = objMsg.Subject & "(Secure) ".
Note that you are trying to use CurrentItem which is not necessarily the same as Outlook.Application.ActiveInspector.CurrentItem. I'm not that familiar with Outlook object model but I bet CurrentItem when called on it's own is not valid.

Related

MS Access VBA code to send an Outlook email

I am trying to get Access to send a simple email programatically. I have added the Outlook 16.0 reference. Below is the code. When it gets to the With oMail part, it returns an error: "Application-defined of object-defined error."
It errors on the .ReplyRecipients.Add line. If I comment out that line, then it errors on the .Send line.
Note I am running the TestSend() sub to activate the SendEmailOutlook sub.
Sub TestSend()
Call SendEmailOutlook("myemail#email.com", "Test message", "Test message.")
End Sub
Public Sub SendEmailOutlook(strTo As String, strSubject As String, strBody As String)
On Error GoTo SendEmailOutlookErr
Dim strEmail As String
Dim strMsg As String
Dim oLook As Object
Dim oMail As Object
Set oLook = CreateObject("Outlook.Application")
Set oMail = oLook.createitem(0)
With oMail
.ReplyRecipients.Add "myemail#email.com"
.to = strTo
.htmlbody = strBody
.Subject = strSubject
.Send
End With
Set oMail = Nothing
Set oLook = Nothing
Exit Sub
SendEmailOutlookErrExit:
Exit Sub
SendEmailOutlookErr:
MsgBox Err.Description, vbOKOnly, Err.Source & ":" & Err.Number
Resume SendEmailOutlookErrExit
End Sub
In the code the late binding technology is used, so the COM reference is optional. But if you have already added the Outlook COM refence you may declare all Outlook objects instead of just having the object in the declaration. It can help. Read more about the late and early binding in the Using early binding and late binding in Automation article.
Also the following line of code contains multiple property and method calls:
With oMail
.ReplyRecipients.Add "myemail#email.com"
The code is valid. But it makes sense to declare each property or method on a separate line of code, so you could easily find the faulting one - where exactly the error occurs.
The MailItem.ReplyRecipients property returns a Recipients collection that represents all the reply recipient objects for the Outlook item. Use the Add method to create a new Recipient object and add it to the Recipients object. The Type property of a new Recipient object is set to the default for the associated AppointmentItem, JournalItem, MailItem, or TaskItem object and must be reset to indicate another recipient type.
Set myItem = Application.CreateItem(olMailItem)
Set myRecipient = myItem.Recipients.Add ("Jon Grande")
myRecipient.Type = olCC
Another aspect is how Outlook has been configured to trust applications on a client computer, an application that uses the Outlook object model to access certain data or execute certain actions can invoke security warnings or throw errors when Outlook is automated without any UI. Depending on the type of information or action that the program was attempting to access or execute, there are three different security prompts that applications can invoke through the Object Model Guard: the address book warning, send message warning, and execute action warning. Read more about that in the Outlook Object Model Security Warnings article.

Send an email with a blank subject

I am a professor interacting with students who do not respond to emails, but who do respond to text messages. So, I am writing an Outlook userform to generate text messages that are sent by Outlook to students' cell phones, e.g., by using email addresses that target the student's cell phone text message service like this: 5405551212#mms.att.net
The problem I am running into is that I don't want to have a Subject for these text messages because that Subject is added as the first line of each text sent to the student and is confusing and looks weird, but, the VBA code olMail.Send will throw this error when the Subject is blank: "Run-time error '-2147467259 (80004005)': Outlook does not recognize one or more names." The names for olMail.To and olMail.CC are fine and the error goes away when I add a non-blank Subject.
Is there a way to programmatically force Outlook to send the email with a blank subject? I have not been able to find a solution searching online other than to make the subject " " (a space)--but that is not an ideal solution because it still adds a "blank" line at the top of each text message because of the space.
I could probably use olMail.Display and then use SendKeys to send the email and answer "Yes" when I am asked if I want to send the email without a subject, but that is clunky.
How can I skip the error and send the email without a subject using VBA?
EDIT:
Here's the code that I was using to add recipients to the mailitem:
Dim olApp As Outlook.Application
Dim olMail As MailItem
olMail.To = Me.tbxEmailAddress 'this would be something like 5405551212#mms.att.net
olMail.CC = "someemail#notmail.com" 'this would be my own email address
olMail.Subject = "" 'blank subject
olMail.Body = Replace(Me.tbxTexts, vbCrLf, "") 'remove extra hard returns
olMail.Send 'this would throw the error mentioned above,
'but if I changed olMail.Subject = "" to
'olMail.Subject = "This is the subject" then no error would occur
Using #Eugene Astafiev's information below, I cobbled together a working solution like this:
Dim myRecipients As Outlook.Recipients
Dim myRecipient As Outlook.Recipient
Dim olApp As Outlook.Application
Dim olMail As MailItem
Set olApp = Outlook.Application
olMail.Subject = "" 'blank subject
olMail.Body = Replace(Me.tbxTexts, vbCrLf, "") 'remove extra hard returns
Set myRecipient = olMail.Recipients.Add(tbxEmailAddress)
myRecipient.Type = olTo 'Type is: olBCC, olCC, olOriginator, or olTo
Set myRecipient = olMail.Recipients.Add("someemail#notmail.com")
myRecipient.Type = olBCC
Set myRecipients = olMail.Recipients
If Not myRecipients.ResolveAll Then
For Each myRecipient In myRecipients
If Not myRecipient.Resolved Then
MsgBox "Could not resolve: " & myRecipient.Name
End If
Next
End If
olMail.Send 'no error now!
Interestingly, no email address using the myRecipients collection ever reported being unable to be resolved. However, when I tried to resolve the individual myRecipient object/item using myRecipient.Resolve then the text message email address (e.g., 5405551212#mms.att.net) would fail to resolve but my own email address would resolve fine.
Maybe this has something to do with 5405551212#mms.att.net not being an address in my Address Book or Contacts?
At any rate, it does send now. (Note: prior to using the myRecipients.ResolveAll, I did succeed in getting the code I originally had to work by using olMail.Display and then olMail.Send and then using SendKeys "%s" twice--the first time to "click" the Send button and the second time to "click" the "Send Anyway" button when Outlook complained there was no subject. But, clearly the VBA code approach is far superior.)
Thanks to everyone for you help!
Outlook doesn't require setting up the Subject line before submitting items. Use the Recipients.ResolveAll method which attempts to resolve all the Recipient objects in the Recipients collection against the Address Book.
Sub CheckRecipients()
Dim MyItem As Outlook.MailItem
Dim myRecipients As Outlook.Recipients
Dim myRecipient As Outlook.Recipient
Set myItem = Application.CreateItem(olMailItem)
Set myRecipients = myItem.Recipients
myRecipients.Add("Eugene Astafiev")
myRecipients.Add("Nate Sun")
myRecipients.Add("Dan Wilson")
If Not myRecipients.ResolveAll Then
For Each myRecipient In myRecipients
If Not myRecipient.Resolved Then
MsgBox myRecipient.Name
End If
Next
End If
End Sub
You may find the following articles helpful:
How To: Fill TO,CC and BCC fields in Outlook programmatically
How To: Create and send an Outlook message programmatically

Can I check if a recipient has an automatic reply before I send an email?

I have a macro set up that will automatically send out emails to dozens of managers. Sometimes they're away and I have to check the away message and manually forward it to the person covering for them.
I try to find a solution before I seek help so have mercy on me! I found a similar question but it wasn't a lot of help, I couldn't find a lot of info on extracting an auto response from a recipient in a draft.
So far this is what I've got:
Sub CheckAutoReply()
Dim OL As Outlook.Application
Dim EM As Outlook.MailItem
Dim R As Outlook.Recipient
Set OL = New Outlook.Application
Set EM = CreateItem(olMailItem)
With EM
.display
.To = "John.Doe#Stackoverflow.com" 'This is a recipient I know has an autoresponse. Fictitious of course.
End With
Set R = EM.Recipients(1) 'on hover it pops up with "EM.Recipients(1) = "John.Doe#Stackoverflow.com""
Debug.Print R.Name 'this returns "John.Doe#Stackoverflow.com"
Debug.Print R.AutoResponse 'this returns nothing
Set OL = Nothing
Set EM = Nothing
End Sub
This is not a proper answer but an attempt to get you started.
Your code suggests your knowledge of Outlook VBA is limited. If this is true, I doubt that any of the approaches in “a similar question” will be appropriate. Are you familiar with Visual Studio, C++, Delphi or Redemption? Even if you managed to access PR_OOF_STATE, you would not have the alternative email address.
I would start by attempting to extract the email address from the out-of-office reply. Looking for “#” and extracting the text back to and forward to the next space might be enough.
Copy the code below to an Outlook VBA module. Select one of the out-of-office replies and run macro DemoExplorer. The objective of this macro is to show you what the text and Html bodies of the email look like. Try this macro on other replies. Are the bodies consistent? Can you see how to extract the alternative email address?
Public Sub DemoExplorer()
Dim Exp As Outlook.Explorer
Dim ItemCrnt As MailItem
Dim NumSelected As Long
Set Exp = Outlook.Application.ActiveExplorer
NumSelected = Exp.Selection.Count
If NumSelected = 0 Then
Debug.Print "No emails selected"
Else
For Each ItemCrnt In Exp.Selection
With ItemCrnt
Debug.Print "From " & .SenderName & " Subject " & .Subject
Debug.Print "Text " & Replace(Replace(Replace(.Body, vbLf, "{lf}"), vbCr, "{cr}"), vbTab, "{tb}")
Debug.Print "Html " & Replace(Replace(Replace(.HTMLBody, vbLf, "{lf}"), vbCr, "{cr}"), vbTab, "{tb}")
End With
Next
End If
End Sub
The answer to the similar question you found (Remove recipients from Outlook email if automatic reply is activated) still stands. What were you having problem with?
The only additional possibility (and this is what Outlook uses when it displays an OOF banner for a recipient you are about to send to) is to use EWS and the GetMailTips operation (see https://msdn.microsoft.com/en-us/library/office/dd877060(v=exchg.150).aspx).

Using Outlook.Application.ActiveInspector.CurrentItem in VSTO

I have an Outlook macro and I'm working to convert it to a com add in to make deployment easier. This is my first attempt at doing this and I am using VSTO 2013. When I copy over the code I'm using in my macro, it doesn't like the "Outlook.Application.ActiveInspector.CurrentItem" as I get an error: "Reference to a non-shared member requires an object reference."
The code I am using is listed below.
Sub InsertSubject()
Dim objMsg As Outlook.MailItem
'Get the currently open message'
Set objMsg = Outlook.Application.ActiveInspector.CurrentItem
objMsg.Subject = objMsg.Subject & "(Secure) "
'Destroy the object to avoid memory leaks'
objMsg.Send
Set objMsg = Nothing
End Sub
Can anyone give me some tips on how to use the currently selected item item in VB? Sorry if this comes aross as a "teach me how to code" question. I am new to this and just learn better when I have a real world problem to work through.
I was actaully able to piece the following together and get this to work.
Dim _item As Outlook.MailItem = Globals.ThisAddIn.Application.ActiveInspector().CurrentItem
Dim objMsg As Outlook.MailItem
'Get the currently open message'
objMsg = Globals.ThisAddIn.Application.ActiveInspector().CurrentItem
objMsg.Subject = objMsg.Subject & "(Secure) "
'Destroy the object to avoid memory leaks'
objMsg.Send()
objMsg = Nothing

Suppress dialog warning that a program is trying to access my mails

I am following the code from this page: How to create a script for the Rules Wizard in Outlook
This is what I have:
Public Sub GetMails(Item As Outlook.MailItem)
MsgBox "Mail message arrived: " & Item.SenderEmailAddress
MsgBox "Mail message arrived: " & Item.Subject
MsgBox "Mail message arrived: " & Item.Body
End Sub
I set a rule to run this macro. Every time this script runs there is a dialog about how a program is trying to access my mails.
How can I get rid of this using VBA or is there any configuration option in Outlook so that this does not appear?
I have googled for this and found some sites giving code for C# and VB.net but none for VBA.
This was added to prevent malicious scripts from turning Outlook into a mass mailer or other bad things.
You can turn this off on your workstation, but if you want to distribute your application to other users, you can get rid of this only by creating your own Outlook Addin or use a 3rd-party tool like Redemption.
Try this
Tools-->Macro-->Security-->macro security-->No security
Tools-->Macro-->Security-->Programmatic Access
Then choose Never warn me about suspicious activity.
I found this somewhere and it works:
Sub SaveAttachment(myItem As Outlook.MailItem)
' Remove ay attachments for the email and save them in a
' local folder. If there are any erros on the saveing then
' attachments are left in place.
Dim myAttachments As Object
Dim myOrt As String
Dim strID As String
Dim olNS As Outlook.NameSpace
Dim oMail As Outlook.MailItem
Dim fs As Object
' We need to get the mail item object from the application
' object to avoid warning messages
strID = myItem.EntryID
Set olNS = Application.GetNamespace("MAPI")
Set oMail = olNS.GetItemFromID(strID)