Link to home
Start Free TrialLog in
Avatar of AndyAinscow
AndyAinscowFlag for Switzerland

asked on

Automate outlook - modify a 'reply' email from another office app.

Using an instance of the outlook namespace I can use the CreateItem to create and manipulate a new email message, leaving it available for the user to add text or other things at will then send it.

Now there is a requirement that the user selects an email message and hits 'reply' to start editing a new email.  At this point when the email editor window is open
User generated imagethat via VBA I can get the item and manipulate it as if it was a new item generated by my current code.  How?
Avatar of darbid73
darbid73
Flag of Germany image

At least in Outlook 2010 and 2013 but maybe earlier you can use the MailItem.Reply event.

Option Explicit
Private WithEvents oExpl As Explorer
Private WithEvents oItem As MailItem
Private bDiscardEvents As Boolean
'http://slipstick.me/44b0w
 
Private Sub Application_Startup()
   Set oExpl = Application.ActiveExplorer
   bDiscardEvents = False
End Sub
 
Private Sub oExpl_SelectionChange()
   On Error Resume Next
   Set oItem = oExpl.Selection.Item(1)
End Sub
 
' Reply
Private Sub oItem_Reply(ByVal Response As Object, Cancel As Boolean)
       
   Cancel = True
   bDiscardEvents = True
  
   Dim oResponse As MailItem
   Set oResponse = oItem.Reply

' add the fields here
   oResponse.Subject = "keyword " & oResponse.Subject

   oResponse.Display
      
   bDiscardEvents = False
Set oItem = Nothing
End Sub

Open in new window

Source for the code is here. I have just copied fully.

To explain what is happening is that (1) you get the Outlook Explorer.  (2) This Explorer has an item selection event. (3) You get the MailItem from this event. (4) Listen for the Reply on this MailItem.

I think this code might need a little but of adjusting but in general its a good way.
Avatar of AndyAinscow

ASKER

Thanks, I'll give it a try and let you know.
I've given it a try (after qualifying some things - the code is meant to be run inside outlook I think).  It will find the selected email message in the main outlook window.  Unfortunately this is not the window where one is composing the reply which means it could even be another email message.  With dire consequences if it is then modified.  Also that will always find an email even when no reply is being composed - again not what I need.

The critical thing is I need to find the reply to an email in its pop up window - should one be being composed.
Welcome to the complications of Outlook.

1. Outlook can have more than one Explorer window.  For example if you have a Calendar window open and Email window then this will mean you have more than one Explorer.
2. As a consequence of 1 if you have an instance of the Calendar window then you will never get an EmailItem.
3. A SelectionChange event is for ALL selections. This means that if you select a CalendarItem or Note or Task then this event is fired.  But it is my understanding that you MUST select a MailItem before you can reply.
4. As such if you have the correct Explorer then you will get the Selection Events and thus it will on selection of an email set up the Reply event.  Now when you click on reply the event is fired.

Please follow the steps I am explaining and understand them and let me know at the exact point you are having difficulty.
I'm pretty certain I understand what you are saying.

I'm running the code from another office app, not inside outlook.  Because of that I have to cope with the situation that the user has started a reply before running the code.  In this case hooking into an event isn't going to work - because the event has been fired before I even get an instance of outlook in my code.
So I need to find the 'reply' window if it exists and is open.  Put another way, from an instance of outlook I need to be able to iterate through all child windows and reliably identify a 'reply' window which I can then use to modify the email being generated.  This should also be done from VBA.  

(In theory I could code a dll which iterates through existing child windows and looks for a specific class type of window - Spy++ can help me find the correct type that outlook will use - but then I end up with a window handle which I would have to somehow get back to the VBA code and 'convert' to an existing window.  That 'window' would then allow me to edit the email programatically - add specific attachments, check all necessary recipients will be sent the mail.)
ASKER CERTIFIED SOLUTION
Avatar of darbid73
darbid73
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I think it is good enough to close this thread off at this point.  Thanks.
oppps sorry.

But you do not want this
If mailItem Is Nothing Then
        Set mailItem = objOutlook.CreateItem(olMailItem)
    End If

Open in new window

Yes I do.  It could be the user has NOT click reply to anything so there is no message waiting to be manipulated.
The original situation was just simply create a new mail message.  Now there has been the requirement that ** if ** they were in the process of replying then they could go back to the other office app and hit a button to add things to the reply.  (No flipping back and forth, copy and pasting).

OK.  It is not bullet proof and the user can always do something silly but it should work in the vast majority of instances.