Outlook 2013 using VBA to Send Drafts - vba

Good morning,
Using Outlook 2010 I compiled code to send all emails that were saved in a drafts folder of a given account. Now I've upgraded to Office 2013 I am getting an error... It is the .Send bit where it falls over and presents the error message:
"This method can't be used with an inline response mail item."
I am certain that there is a v simple method for sending drafts, but I have scoured the web and can't figure it as yet.
Public Sub SendDrafts()
Dim lDraftItem As Long
Dim myOutlook As Outlook.Application
Dim myNameSpace As Outlook.NameSpace
Dim myFolders As Outlook.Folders
Dim myDraftsFolder As Outlook.MAPIFolder
'Send all items in the "Drafts" folder that have a "To" address filled
'Setup Outlook
Set myOutlook = Outlook.Application
Set myNameSpace = myOutlook.GetNamespace("MAPI")
Set myFolders = myNameSpace.Folders
'Set Draft Folder. This will need modification based on where it's
Set myDraftsFolder = myFolders("accounts#credec.co.uk").Folders("Drafts")
'Loop through all Draft Items
For lDraftItem = myDraftsFolder.Items.count To 1 Step -1
'Check for "To" address and only send if "To" is filled in.
If Len(Trim(myDraftsFolder.Items.Item(lDraftItem).To)) ] 0 Then
'Send Item
myDraftsFolder.Items.Item(lDraftItem).Send
End If
Next lDraftItem
'Clean-up
Set myDraftsFolder = Nothing
Set myNameSpace = Nothing
Set myOutlook = Nothing
End Sub

I know this is old, but in case someone elses is looking for an answer:
"Active Inline Response" refers to a draft that is open in Outlook. So, when you are debugging, close the draft and flip back to a different message. Then see if your code will run.

I found that if you have clicked on the draft folder so that the Draft folder is active, then you get that error message, usually on the email in the folder that is highlighted.
SOLUTION: Click on any other folder, then run the code, should work, mine did!

Related

How I can run macro automatically with new email arrives in outlook

Am very new to VBScript and macro . I have a vbscript which will create tickets for email's but I need to run this script manually every time .To make it automation I have mapped my macro to the "run a script" script rule in Outlook but when the rule runs it is not fetching the data in the mail which is arrived .It's creating tickets with previous email always .
I have gone through so many VBscripts but none worked to convert the mail that received in to ticket.
If any one faced similar type of issue please let me know the complete solution.
Dim olApp As outlook.Application
Dim objNS As outlook.NameSpace
Dim objSourceFolder As outlook.MAPIFolder
Dim objDestFolder As outlook.MAPIFolder
Dim Msg As outlook.MailItem
Set olApp = outlook.Application
Set objNS = olApp.GetNamespace("MAPI")
Set objSourceFolder = objNS.GetDefaultFolder(olFolderInbox)
Set objDestFolder = objSourceFolder.Folders("Termination")
Set Msg = objDestFolder.Items.GetLast
Set sh = CreateObject("Shell.Application")
Set ie = CreateObject("InternetExplorer.Application")
LocationURL = "Ticket URL” & Msg.EntryID"
ie.Navigate (LocationURL)
ie.Visible = True
With ie.Document
.getElementById("details").Value = Msg.Body
.getElementById("short_description").Value = Msg.Subject
.getElementById("requester_login").Value = "premchand"
End With
When you run a macro from a rule it typically has an argument to which the item triggering the rule gets passed: you do not have to navigate through the Inbox to find the item.
Public Sub DoSomething(Item As Outlook.MailItem)
'code which acts on "Item"
End Sub
There are several ways for handling incoming emails:
The NewMailEx event of the Application class which is fired when a new item is received in the Inbox. This event is not available in Microsoft Visual Basic Scripting Edition (VBScript).
The ItemAdd event of the Items class is fired when one or more items are added to the specified collection. So, you can subscribe to the Inbox folder to see new items. Be aware, this event does not run when a large number of items are added to the folder at once. This event is not available in Microsoft Visual Basic Scripting Edition (VBScript).
Assign a macro VBA sub to the rule in Outlook. In that case the incoming mail item is passed as a parameter to the sub as Tim showed.

Call Outlook procedure using VBScript

I have a procedure in Outlook that sends all the saved messages in Drafts folder.
Below is the code:
Public Sub SendMail()
Dim olApp As Outlook.Application
Dim olNS As Outlook.NameSpace
Dim olFolder As Outlook.MAPIFolder
Dim olDraft As Outlook.MAPIFolder
Dim strfoldername As String
Dim i As Integer
Set olApp = Outlook.Application
Set olNS = olApp.GetNamespace("MAPI")
Set olFolder = olNS.GetDefaultFolder(olFolderInbox)
strfoldername = olFolder.Parent
Set olDraft = olNS.Folders(strfoldername).Folders("Drafts")
If olDraft.Items.Count <> 0 Then
For i = olDraft.Items.Count To 1 Step -1
olDraft.Items.Item(i).Send
Next
End If
End Sub
Above code works fine.
Question:
I want to use Task Scheduler to fire this procedure as a specified time.
1. Where will I put the procedure in Outlook, Module or ThisOutlookSession?
2. I am not good in vbscript so I also don't know how to code it to call the Outlook Procedure. I've done calling Excel Procedure but Outlook doesn't support .Run property.
So this doesn't work:
Dim olApp
Set olApp = CreateObject("Outlook.Application")
olApp.Run "ProcedureName"
Set olApp = Nothing
I've also read about the Session.Logon like this:
Dim olApp
Set olApp = CreateObject("Outlook.Application")
olApp.Session.Logon
olApp.ProcedureName
Set olApp = Nothing
But it throws up error saying object ProcedureName is not supported.
Hope somebody can shed some light.
SOLUTION:
Ok, I've figured out 2 work around to Avoid or get pass this pop-up.
1st one: is as KazJaw Pointed out.
Assuming you have another program (eg. Excel, VBScript) which includes sending of mail via Outlook in the procedure.
Instead of using .Send, just .Save the mail.
It will be saved in the Outlook's Draft folder.
Then using below code, send the draft which fires using Outlook Task Reminder.
Option Explicit
Private WithEvents my_reminder As Outlook.Reminders
Private Sub Application_Reminder(ByVal Item As Object)
Dim myitem As TaskItem
If Item.Class = olTask Then 'This works the same as the next line but i prefer it since it automatically provides you the different item classes.
'If TypeName(Item) = "TaskItem" Then
Set my_reminder = Outlook.Reminders
Set myitem = Item
If myitem.Subject = "Send Draft" Then
Call SendMail
End If
End If
End Sub
Private Sub my_reminder_BeforeReminderShow(Cancel As Boolean)
Cancel = True
Set my_reminder = Nothing
End Sub
Above code fires when Task Reminder shows with a subject "Send Draft".
But, we don't want it showing since the whole point is just to call the SendMail procedure.
So we added a procedure that Cancels the display of reminder which is of olTask class or TaskItem Type.
This requires that Outlook is running of course.
You can keep it running 24 hours as i did or, create a VBscript that opens it to be scheduled via Task Scheduler.
2nd one: is to use API to programatically click on Allow button when the security pop-up appears.
Credits to SiddarthRout for the help.
Here is the LINK which will help you programmatically click on the Allow button.
Of course you have to tweak it a bit.
Tried & Tested!
Assuming that you have Outlook Application always running (according to comment below your question) you can do what you need in the following steps:
add a new task in Outlook, set subject to: "run macro YourMacroName" and set time (plus cycles) when your macro should start.
go to VBA Editor, open ThisOutlookSession module and add the following code inside (plus see the comments inside the code):
Private Sub Application_Reminder(ByVal Item As Object)
If TypeName(Item) = "TaskItem" Then
Dim myItem As TaskItem
Set myItem = Item
If myItem.Subject = "run macro YourMacroName" Then
Call YourMacroName '...your macro name here
End If
End If
End Sub
Where will I put the procedure in Outlook, Module or ThisOutlookSession?
Neither. Paste the below code in a Text File and save it as a .VBS file. Then call this VBS file from the Task Scheduler as shown HERE
Dim olApp, olNS, olFolder, olDraft, strfoldername, i
Set olApp = GetObject(, "Outlook.Application")
Set olNS = olApp.GetNamespace("MAPI")
Set olFolder = olNS.GetDefaultFolder(6)
strfoldername = olFolder.Parent
Set olDraft = olNS.Folders(strfoldername).Folders("Drafts")
If olDraft.Items.Count <> 0 Then
For i = olDraft.Items.Count To 1 Step -1
olDraft.Items.Item(i).Send
Next
End If
If you are using Outlook 2007 or newer I have found you can easily eliminate the security pop up you mentioned above when running your script by doing the following:
In Outlook 2007 Trust Center, go to Macro Security - Select "No security Check for macros"
In Outlook 2007 Trust Center, go to Programatic Access - Select "Never warn me abous suspicious activity.
Of course that technically leaves you open to the remote possibility for someone to email you some malicious email script or something of that nature I assume. I trust my company has that managed though and this works for me. I can use VBS scripts in Outlook, Access, Excel to send emails with no security pop up.
Another Option:
If you don't want to do that, another option that has worked well for me prior to this is here:
http://www.dimastr.com/redemption/objects.htm
Basically a dll redirect that does not include the popup. It leaves your other default security in place and you write \ call your VBA for it and send mail without the secutity pop-ups.

send all "visible" drafts with VBA in Outlook 2007

How do I automatically send out multiple (currently visible) draft items with VBA?
Please help, thank you.
Edit: It's a tough case, none of the items are in the drafts folder yet. These are generated emails that are on your screen, waiting to be sent.
Edit2: nvm, it's not going to help anyway. My script creates approximately 500 emails, and displaying the first 100 causes out of memory error. I opted to auto send them without displaying (it breaks the layout this way, but it's my only option for now.)
It just so happens that I ran into the same issue before and have code handy. If you're not already in Outlook, you will need to add a reference in the VBA IDE, Tools ---> References... and check the box next to "Microsoft Outlook 14.0 Object Library".
Dim oFolder As Folder
Dim oNS As NameSpace
Dim olMail As MailItem
If (MsgBox("Are you sure you want to send ALL EMAILS IN YOUR DRAFTS FOLDER?", vbYesNo + vbCritical, "WARNING: THIS WILL SEND ALL DRAFTS")) = vbYes Then
Set oNS = Outlook.Application.GetNamespace("MAPI")
Set oFolder = oNS.GetDefaultFolder(olFolderDrafts)
For i = 1 To oFolder.Items.Count
oFolder.Items(1).Send
Next
End If
Set oNS = Nothing
Here's some code. Replace Your Name in myFolders("Mailbox - Your Name") with your actual name as it appears in the mailbox.
Public Sub EmailOutlookDraftsMessages()
Dim lDraftItem As Long
Dim myOutlook As Outlook.Application
Dim myNameSpace As Outlook.NameSpace
Dim myFolders As Outlook.Folders
Dim myDraftsFolder As Outlook.MAPIFolder
'Send all items in the "Drafts" folder that have a "To" address filled in.
'Setup Outlook
Set myOutlook = Outlook.Application
Set myNameSpace = myOutlook.GetNamespace("MAPI")
Set myFolders = myNameSpace.Folders
'Set Draft Folder.
Set myDraftsFolder = myFolders("Mailbox - Your Name").Folders("Drafts")
'Loop through all Draft Items
For lDraftItem = myDraftsFolder.Items.Count To 1 Step -1
'Check for "To" address and only send if "To" is filled in.
If Len(Trim(myDraftsFolder.Items.Item(lDraftItem).To)) > 0 Then
'Send Item
myDraftsFolder.Items.Item(lDraftItem).Send
End If
Next lDraftItem
'Clean-up
Set myDraftsFolder = Nothing
Set myNameSpace = Nothing
Set myOutlook = Nothing
End Sub
Source Code adapted from this Question's answer.

VBA in Outlook: "microsoft outlook has stopped working" message

I try to write a VBA script which replys automatically on mails which are in the inbox of a shared mailbox. At the moment it's just a test, later on I want to reply on new incoming mails.
However, so far if I try to run the code, Outlook crashes with the error "microsoft outlook has stopped working" and I have to restart Outlook.
fyi: I'm using a German Outlook Version 2007.
Sub ReplyMail()
Dim myOutApp As Object
Dim myNameSpace As Object
Dim myMailFolder As Object
Dim myRecipient As Outlook.Recipient
boxName = "sharedmailbox#host.de" 'configure mailbox address here
'Get Mailbox folder
Set myOutApp = CreateObject("Outlook.application")
Set myNameSpace = myOutApp.GetNamespace("MAPI")
Set myRecipient = myNameSpace.CreateRecipient(boxName)
myRecipient.Resolve 'convert mail address into mailbox name
Set myMailFolder = myNameSpace.GetSharedDefaultFolder(myRecipient, olFolderInbox)
Dim Item As Object
Set Item = myMailFolder.Items(1)
Dim oMail As Outlook.MailItem
Set oMail = Item.Reply
With oMail
.BodyFormat = olFormatHTML
.HTMLBody = "<HTML>This is a test mail.</HTML>"
.Send
End With
End Sub
If use ".display" instead of ".send" the mail pops up correctly and I'm able to send the mail manually.
I really don't know how to solve this error, pls help!
Thank you!
Michael
Very strange!
Unless it's an exceptional bug, I don't see it.
Small remark: Declare your objects as Outlook objects:
Dim myOutapp as outlook.application
Dim myNameSpace as outlook.namespace
Dim myMailFolder as Mapifolder
This for general performance (Object is the general type) but it will almost certainly not solve your problem.
If I were in your situation, I'd try to entirely quit Outlook from memory, repair or reinstall Outlook/Office. I don't think that something is terribly wrong with your code; Since the .display works, I'm very surprised.
There might be an issue with access rights to
C:\Users\
I had a similar issue with opening certain e-mails starting from a certain point of time. Somehow access rights to that folder had been deconfigured.
So I followed this procedure and everything was fine again:
http://www.addictivetips.com/windows-tips/windows-7-access-denied-permission-ownership/

How to send multiple drafts from Outlook 2003

Outlook wont let me send multiple drafts at the same time. Is there an easy way to send multiple drafts at once in outlook? without having to open each one individually?
From what i've read, seen and tried; this is not possible from within outlook itself, and thus a programming solution would be required, probably some VB script
ok, i found a bit of VB that does it:
`Public Sub SendDrafts()
Dim lDraftItem As Long
Dim myOutlook As Outlook.Application
Dim myNameSpace As Outlook.NameSpace
Dim myFolders As Outlook.Folders
Dim myDraftsFolder As Outlook.MAPIFolder
'Send all items in the "Drafts" folder that have a "To" address filled
'in.
'Setup Outlook
Set myOutlook = Outlook.Application
Set myNameSpace = myOutlook.GetNamespace("MAPI")
Set myFolders = myNameSpace.Folders
'Set Draft Folder. This will need modification based on where it's
'being run.
Set myDraftsFolder = myFolders("$MAILBOX").Folders("$DRAFTS")
'Loop through all Draft Items
For lDraftItem = myDraftsFolder.Items.Count To 1 Step -1
'Check for "To" address and only send if "To" is filled in.
If Len(Trim(myDraftsFolder.Items.Item(lDraftItem).To)) > 0 Then
'Send Item
myDraftsFolder.Items.Item(lDraftItem).Send
End If
Next lDraftItem
'Clean-up
Set myDraftsFolder = Nothing
Set myNameSpace = Nothing
Set myOutlook = Nothing
End Sub
just replace $MAILBOX with your mailbox name and $DRAFTS with the name of your drafts folder.
This has been personnaly tested and seems to work fine.
Not very different from author's answer, but still:
Sub SendDrafts()
Dim ns As NameSpace
Dim drafts As MAPIFolder
Dim Item As MailItem
Set ns = Application.GetNamespace("MAPI")
Set drafts = ns.GetDefaultFolder(olFolderDrafts) ' 16
For Each Item In drafts.Items
'Item.Send
Next
End Sub
Please be careful as it really sends all emails in your default draft folder. After uncommenting the send line. Dim lines to allow for autocompletion when inside Outlook macro editor.
A useful version, which I just tested in Outlook 2000:
Drag the emails you wish to send to the Outbox. They won't be sent automatically, but using this version of the prior posting sends them:
Sub SendOutbox()
Dim ns As NameSpace
Dim outbox As MAPIFolder
Dim Item As MailItem
Set ns = Application.GetNamespace("MAPI")
Set outbox = ns.GetDefaultFolder(olFolderOutbox) ' 16
For Each Item In outbox.Items
Item.Send
Next
End Sub
That way, you can be selective.
Yes, you can write a macro or add-in to do that.