Automatically save draft email - vba

I'm looking for VBA code for Outlook 2013 that will automatically save a draft either when opening the composition window, when replying or forwarding an email (it's OK if it fires on newly-composed messages also) or just before sending it when hitting the Send button.
Essentially emulating hitting the "Save" icon or Ctrl-S either before composing or before the message gets sent.
Outlook generates a "Could not complete the operation because the mail provider does not support it" error when replying to or forwarding a non-Google Apps account email when Google Apps accounts are combined with other email accounts in Outlook.
I discovered that a work-around is to manually save the email before sending it. I can do that manually but often forget. Can't do it after the error message appears. Trying to save after the "could not complete" error is thrown results in another error.
BTW, I already have a routine running off the Application_ItemSend event; will adding another conflict?
Update: Here is a version of what I tried:
Private Sub Application_ItemSend(ByVal item As Object, Cancel As Boolean)
' Runs when the item is being sent.
Call AutoSaveDraft(item)
Call CheckSubject(item)
End Sub
(CheckSubject fires)
Private Sub AutoSaveDraft(item As Object)
item.Save
SendKeys "+{F12}" ' Save the message. ##
SendKeys "^S"
Sleep 1000 ' Pause execution 1 second. The Windows sleep function is called in the beginning ##
End Sub
(Yes, I have all three potential save methods. Have also tried them individually.

You are free to call the Save method in the ItemSend event handler if it helps to avoid issues.
You may find the Getting Started with VBA in Outlook 2010 article helpful.

Since the original poster doesn't make it clear, this is what actually works to prevent the errors related to non-Google Apps accounts when simply hitting Send:
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
Item.Save
End Sub

Related

Slow opening of any email after set value for an object on Application_ItemLoad

Basically I am using below code to run macro after I manually open a specific email.
The code and macro works ,but I noticed there is a slowness while opening of any email on outlook.
After many tests, I find out this line is the cause of issue:
Set MyItem = Item
And this the full code:
Option Explicit
Option Compare Text
Public WithEvents MyItem As Outlook.MailItem
Private Sub Application_ItemLoad(ByVal Item As Object)
If Item.Class = olMail Then
Set MyItem = Item 'This line cause slow opening of any email
End If
End Sub
Private Sub myItem_Open(Cancel As Boolean)
If MyItem.Subject = "Test Email" Then
'Code
End If
End Sub
Kindly How to fix this issue?
Basically I am using below code to run macro after I manually open a specific email.
You may consider using other event handlers in Outlook - for selecting in the Explorer window you may try to handle the SelectionChange event of the Explorer class which is fired when the user selects a different or additional Microsoft Outlook item programmatically or by interacting with the user interface. For opening in the separate window you can handle the NewInspector event which is fired whenever a new inspector window is opened, either as a result of user action or through program code. The event occurs after the new Inspector object is created but before the inspector window appears. Also you may handle the Inspector.Activate event which is fired when an inspector becomes the active window, either as a result of user action or through program code.
If there is a specific reason to use the ItemLoad event handler in the code you may continue using the late-binding technology and keep the item defined as object.
Also don't forget to release corresponding objects in the Unload event of the Item-level events.

Outlook VBA Type mismatch (error 13) when initializing handler for Sent Mail folder

This is my first thread on the forum so I hope i do everything as is needed.
Since a few years we use a vba outlook macro at our firm to send our sent mails to a folder. The folder is specified when pressing the SEND button. When we created the macro, we used to save the file directly after pressing send, but then only a draft file was saved to the specified folder. Herefore we initiated a handler to check when the mail is added to the Sent Mail folder so we could save this mail to the specified folder. Since yesterday, only some of my colleagues started getting a Type mismatch error while running this macro. Today another couple of colleagues is having this issue as well. Most of us can still use the macro without having any errors.
I narrowed the problem down to the initialize_handler itself by creating a much easier macro. So now when sending any email, I initialize a handler for the items in my Sent Mails folder. When an item is added to the Sent Mails folder, a messagebox should appear telling me an item is added.
The type mismatch error is created on "Set myOlItems = ...."
Public WithEvents myOlItems As Outlook.Items
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
Call Initialize_handler
End Sub
Public Sub Initialize_handler()
Set myOlItems = Application.GetNamespace("MAPI").GetDefaultFolder(olFolderSentMail).Items
End Sub
Private Sub myOlItems_ItemAdd(ByVal ObjectSent As Object)
MsgBox "Item is added to Sent Mails"
End Sub
I hope someone has a solution to this. I wasn't able to find out what could trigger the error?
Thanks!
I'd recommend starting from breaking the chain of property and methods calls by declaring each property or method call on a separate line of code. So, we will be able to find out which property or method calls fails.

WithEvents object in Outlook VBA eventually fails to raise event

Okay, looks like someone has encountered this problem before, but I didn't see any further comments or solutions. See the Edit in the accepted answer to this question.
My situation is like this.
I am running Outlook 2013 under Win10 x64 with an Exchange email account. I sometimes run Outlook for several days to a week or more at a time without closing it.
I want to raise an event when a new item is added to the Sent Mail folder. This needs to occur after the Application ItemSend event because, let's say, I want to delete the message after it is sent, which you cannot do from within the ItemSend event handler.
So I have the following code:
Public WithEvents goSent As Outlook.Items
Private Sub Application_Startup()
'Establish the global object for the folder we want to monitor.
Set goSent = Session.GetDefaultFolder(olFolderSentMail).Items
End Sub
Private Sub goSent_ItemAdd(ByVal Item As Object)
'Do stuff here.
End Sub
Everything works beautifully for a day or longer, but eventually the ItemAdd event handler stops firing. If I enter the VBA editor and manually run Application_Startup, then it starts working again.
[Edit:] One other bit of information: The "built-in" events, like Application ItemSend, always seem to fire reliably no matter how long Outlook has been running.
[Edit 2:] This time, I let things go for a day after the event stopped firing. I opened the VBA editor and put a breakpoint in the Application ItemSend procedure. When it stopped, I queried the goSent object and found that (a) it still existed (rather than being Nothing), but (b) it had only the items in it that were there yesterday, presumably at the time it became "untethered" from the Sent Mail items collection. When I submitted a new Set statement in the Immediate window, it immediately began to work again.
[Edit 3:] I noticed that the MSDN documentation says to put event handlers for custom objects--like my ItemAdd event--in class modules. I have mine in ThisOutlookSession, but it was my understanding that ThisOutlookSession is a class module. Is there a problem with that?
Any idea why this would happen and what to do about it? I considered adding an event handler for Application ItemSend and just reassigning the goSent object every time that's fired, but it doesn't address the underlying problem.
[Edit 4:] For a while now, I've had a Set statement in the Application ItemSend handler, and that seems to have mostly taken care of things, even though it's a workaround, not really a solution. It appears to fail when I have delayed delivery on a sent item for an extended time, and I don't send any further messages in the meantime. Then the goSent object disconnects from the Sent Mail collection, and the message is actually sent from the Outbox after that point and before Application ItemSend fires again.
Thanks!
[Edit 5:] Unrelated to original issue: I discovered that my macros fail to accomplish what I want with an Exchange server that is in online mode (i.e., not cached mode) if I have messages in the Outbox with delayed delivery and Outlook is closed when the delivery time passes. In online mode, Exchange itself sends these messages and adds them to the Sent Mail folder on the server, so when Outlook reopens, the messages are already in the Sent Mail collection and no event fires. Which makes sense. See discussion here. Looks like I would need to add something to my Application_Startup macro to look for messages sent since Outlook last closed.
I had similar issue and never found a proper solution. What I did was I wrote a little batch script that closes and opens outlook app, then I set a task in task scheduler to run it every hour outside of my working hours. You can also do it easily in vbs.

Outlook VBA to Save Attachments from OUTGOING messages to a folder

I would like to create an archive of OUTGOING attachments in a folder (a Windows folder, outside Outlook). I have used scripts to save attachments from INCOMING messages by using some of the solutions provided on this site, but I don't see a way to set this up for outgoing mail. I also tried to set up a rule to apply a script to all outgoing messages, but I don't see an option to "run a script" on messages I send (like I can for incoming messages).
I can probably use a script that parses an outlook folder, but it would be much more effective to have it run in real-time as messages are sent.
Process the Application.ItemSend event - the item will be passed as a parameter to your event handler. You can then process the message attachment the same way your process the incoming messages.
If you really want to use the Outbox instead of the ItemSend event (which is probably a better solution), try this (found here and modified to use Outbox)
Public WithEvents myOlItems As Outlook.Items
Public Sub Initialize_handler()
Set myOlItems = Application.GetNamespace("MAPI").GetDefaultFolder(olFolderOutbox).Items
End Sub
Private Sub myOlItems_ItemAdd(ByVal Item As Object)
'your code to save attachments here
End Sub

Finding Outlook event triggered by third party email send

I have a third party piece of software that sends email through Outlook. It allows us to specify a "reply to" email address, but not a "from" email address. I'm trying to write something in VBA that notices when a message comes from that third party software and uses the "reply to" address as the "from" address before it sends the email. I'm having trouble getting any events to trigger when I send email with the third party software.
If I use
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
MsgBox "Test"
End Sub
it triggers the message box when I send an email through Outlook, but not when the third party software does. Is there another event I should be looking at instead? I'm looking at Application events or MailItem events (http://msdn.microsoft.com/en-us/library/office/dn320237(v=office.15).aspx) and nothing but the Send events seem at all appropriate. I tried the sample code for the item Send event
Public WithEvents myItem As Outlook.MailItem
Sub SendMyMail()
Set myItem = Outlook.CreateItem(olMailItem)
myItem.To = "Dan Wilson"
myItem.Subject = "Data files information"
myItem.Send
End Sub
Private Sub myItem_Send(Cancel As Boolean)
myItem.ExpiryTime = #2/2/2003 4:00:00 PM#
End Sub
but it doesn't trigger even when I send an email through Outlook. I did try restarting Outlook before testing that out.
This question looks promising: How do I trigger a macro to run after a new mail is received in Outlook?
but it involves setting an event listener to the Inbox. I've heard that there's a way to change settings somehow in a way that prevents the third party messages from being automatically sent, and when that happens they get stuck in Outlook's Drafts folder. How would I go about putting an event listener on the Drafts folder instead of the Inbox?
Application.ItemSend event is only fired if a message is sent through the Outlook Object Model. If the other app uses Extended MAPI, no event fires.