?
Solved

Persist  all recipients on Item forward event

Posted on 2009-04-24
17
Medium Priority
?
927 Views
Last Modified: 2012-05-06
Hi,

Could any one please let me know if it is possible to persist all recipients
(To, and CC list) while I forward some item(might be mail item).  For example, I received email where To="XXX and YYYY" and CC="AAA and BBB". When I forward this email I want to preserve these To and CC user's list.

Thanks.
0
Comment
Question by:deshaw
  • 10
  • 7
17 Comments
 
LVL 76

Expert Comment

by:David Lee
ID: 24223348
Hi, deshaw.

Outlook does not offer a means of retaining the addresses when forwarding a message.  To accomplish this you'll have to copy the addresses from the original message to the copy being forwarded.  Something like this.
Set olkForward = olkOriginal.Forward
For Each olkRecipient in olkOriginal.Recipients.
    olkForward.Recipients.Add olkRecipient
Next

Open in new window

0
 
LVL 1

Author Comment

by:deshaw
ID: 24223444
Where ( or Which event) I have to put that code? Also give the prototype of event. might be Item Forward event?
Thanks.
0
 
LVL 76

Expert Comment

by:David Lee
ID: 24223553
That's up to you.  I suppose you could do it from the Forward event.  I see problems with that though.  The prototype for the Forward event is

    Item_Forward(ByVal Forward As Object, Cancel As Boolean)

where Item represents the item generating the event.  Notice that the Item being forwarded is passed, but not the new message (i.e. the result of the forward).   That makes it impossible to copy the recipients from the original to the forward.  The solution I see to get around that is to use something like the code in the snippet.  It stops monitoring events on the Item, creates it's own forward message, copies the addresses over, cancels the original forward event, then displays the message.


Private Sub olkMsg_Forward(ByVal Forward As Object, Cancel As Boolean)
    Dim olkNew As Objectm, olkRecipient As Outlook.Recipient
    Set olkMsg = Nothing
    Set olkNew = Forward.Forward
    For Each olkRecipient In Forward.Recipients
        olkNew.Recipients.Add olkRecipient
    Next
    Cancel = True
    olkNew.Display
    Set olkNew = Nothing
    Set olkRecipient = Nothing
End Sub

Open in new window

0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 1

Author Comment

by:deshaw
ID: 24223734
Sorry BluDevilFan but I didn't get where I have to put olkMsg_Forward macro. From where I have to call it? I cannot put it in ThisOutlookSession because there is no event like olkMsg_Forward. I am sure you did not mean to call olkMsg_Forward from Item_Forward. It is also not a module because of the arguments. Let me know what to do?
Thanks.
0
 
LVL 76

Expert Comment

by:David Lee
ID: 24223794
Are you already using a wrapper class to trap items so you can monitor their events?  If not, then you'll have to in order to be able to trap the Forward event of any item.  olkMsg_Forward is just an example of trapping a forward event.  olkMsg represents the item who's events your trapping.  For example, in the prototype I used an object named Item.  olkMsg is just another name.  The code fragment is an example showing how to do something.  You'll have to integrate the concept into your code and change object names to match the objects you're using.
0
 
LVL 1

Author Comment

by:deshaw
ID: 24223884
:-( I don't have any wrapper class. Could you tell me If just want to consider only mail item then how to trap the forward event? I am not sure but if I write like below it is not getting invoke while I click forward button:

Private Sub MailItem_Forward(ByVal Forward As Object, Cancel As Boolean)
    MsgBox "Forwarding mail item"
    Dim olkNew As Objectm, olkRecipient As Outlook.Recipient
    Set olkMsg = Nothing
    Set olkNew = Forward.Forward
    For Each olkRecipient In Forward.Recipients
        olkNew.Recipients.Add olkRecipient
    Next
    Cancel = True
    olkNew.Display
    Set olkNew = Nothing
    Set olkRecipient = Nothing
End Sub

Thanks.
0
 
LVL 76

Expert Comment

by:David Lee
ID: 24224119
"it is not getting invoke while I click forward button:"

Of course it isn't.  To trap events for an item you have to declare an object with the "WithEvents" clause and then instantiate the object.  So, using your variable name "MailItem", you have to add

    Dim WithEvents MailItem as Outlook.MailItem

in the ThisOutlookSession module.  That creates the basis for trapping events for that object.  The next step is to instantiate the object.  Instantiation occurs when you assign something to the variable.  That's where the wrapper class comes into play.  To instantiate the object you need something like

    Set MailItem = Outlook.ActiveInspector.CurrentItem

You can run this line manually, but you really want it to be automatic.  You want that line of code to execute every time you open an item so Outlook can watch for a Forward event.  Otherwise, at some point after opening an item you must run the code so Outlook can monitor the message for events.  For Outlook to automatically monitor messages for events requires monitoring other objects in the system.  That's where the wrapper class comes in at.  

Are you looking to add this to the add-in you were working on before?  If so, then it has a wrapper class in it.
0
 
LVL 1

Author Comment

by:deshaw
ID: 24224284
>>That creates the basis for trapping events for that object.
Ohhh OK thanks. Now I got the trapping concepts.

>>Are you looking to add this to the add-in you were working on before?  If so, then it has a wrapper class in it.
If I could make it simpler using Add-in instead of macro then I will go for it. OK I have Outlook COM Add-in template and I have kept your code in

Private Sub objMailItem_Forward(ByVal Forward As Object, Cancel As Boolean)
   MsgBox "Forwarding mail item"
   Dim olkNew As Objectm, olkRecipient As Outlook.Recipient
   Set olkMsg = Nothing
   Set olkNew = Forward.Forward
   For Each olkRecipient In Forward.Recipients
       olkNew.Recipients.Add olkRecipient
   Next
   Cancel = True
   olkNew.Display
   Set olkNew = Nothing
   Set olkRecipient = Nothing
End Sub

I have set the objMailItem in colInsp_NewInspector event. Please let me know now what should I do?

Thanks.
0
 
LVL 1

Author Comment

by:deshaw
ID: 24224347
Still I didn't understand wrapper class concept. :-) I know once we done I would understand it.

Thanks for being there.
0
 
LVL 76

Expert Comment

by:David Lee
ID: 24228823
re: Post 24224284

The NewInspector event was what I was talking about.  Setting objMailItem to the currently open message in the NewInspector event was exactly what you needed.  Now when you open a message the NewInspector event fires which sets objMailItem so it can watch for its events and trap the Forward action.  Everything should work now.

re: Post 24224347

Consider this code fragment.  

    Dim WithEvents objInspectors as Outlook.Inspectors
    Dim WithEvents objMailItem as Outlook.MailItem

    Private Sub objInspectors_NewInspector(ByVal Inspector As Inspector)
        Set objMailItem = Inspector.CurrentItem
    End Sub

This is how we'd handle this process without a wrapper class.  This works fine so long as we never open more than one item at a time.  If we open one item and then open a second the reference to the first item is lost.  That occurs because we have a single mail item object.  To handle the possibility of multiple items being opened at once and reacting to their events we need an array or collection to store all of the open mail items.  You could arbitrarily assume that you'd never have more than five items open and use something like this

    Dim WithEvents objInspectors as Outlook.Inspectors
    Dim WithEvents objMailItem1 as Outlook.MailItem
    Dim WithEvents objMailItem2 as Outlook.MailItem
    Dim WithEvents objMailItem3 as Outlook.MailItem
    Dim WithEvents objMailItem4 as Outlook.MailItem
    Dim WithEvents objMailItem5 as Outlook.MailItem

    Private Sub objInspectors_NewInspector(ByVal Inspector As Inspector)
        'Code to determine which objMailItem is not being used and assign Inspector.CurrentItem to it'
    End Sub

That's very inefficient and writing code to figure out which objMailItem is firing would be complicated.  And the whole process would fail if you ever opened a sixth item.  

Microsoft did not provide anything in Outlook's object model for handling this, so it's up to the developer to design a way to handle it.  The solution is a wrapper class.  A wrapper class wraps (hence the name wrapper) the process of managing multiple copies of an object into an object class.  That sample add-in template has both an inspector wrapper and an explorer wrapper class in it.  The inspector wrapper is designed to handle multiple inspector items (an inspector is the window an Outlook item is displayed in).  The explorer wrapper does the same thing for explorers (the windows that folders are displayed in).

Does that help?
0
 
LVL 1

Author Comment

by:deshaw
ID: 24231463
Your posts always help BluDavilFan. I have a problem here. I have invokded forward event like below from inspector otherwise it is not getting invoked. I have two questions:
1. How to identify that user clicked forward button for current inspector item because NewInspector gets invoked for every events like Reply, Reply All etc. If I not invoke  objMailItem_Forward from NewInspector event then it never gets invoked at all.
2. Though, original email contains some users id in to and cc list, Forward.Recipients returns always null. Moreover, two email items to forward getting poped up. One for user clicked on forward button and other  because of   olkNew.Display in objMailItem_Forward. I think we have to get rid of this.
Thanks.

Private Sub colInsp_NewInspector(ByVal Inspector As Inspector)
    Dim objItem As Object
    On Error Resume Next
    Set objInsp = Inspector
    Set objItem = objInsp.CurrentItem
    Select Case objItem.Class
            Case olMail
                Set objMailItem = objItem
                objMailItem_Forward objMailItem, False 
    End Select
End Sub
 
Private Sub objMailItem_Forward(ByVal Forward As Object, Cancel As Boolean)
   Dim olkNew As Object, olkRecipient As Outlook.Recipient
   Set olkNew = Forward.Forward
   For Each olkRecipient In Forward.Recipients
       MsgBox olkRecipient 'Never comes here
       olkNew.Recipients.Add olkRecipient
   Next
   Cancel = True
   olkNew.Display
   Set olkNew = Nothing
   Set olkRecipient = Nothing
End Sub 

Open in new window

0
 
LVL 1

Author Comment

by:deshaw
ID: 24239312
BlueDevilFan, I have written macro that meets my requirements. It taks the selected email item, forward the item and copies all recipients. Could you tell me if it is possible to add To and CC list recipients from selected email to email being sent? I could see that while using safe mail item, objSafeMailItem.To and objSafeMailItem.CC are read only properties. but I am not sure if we set anything else like objSafeMailItem.Recipient.Class so that it put recipient in particular To or CC list.
Thanks.

Sub ReplyWithAttachments()
    Dim itm As Object
    Dim objApp As Outlook.Application
    Dim objSafeMailItem As Redemption.SafeMailItem
    Dim rpl As Redemption.SafeMailItem
    
    Set objApp = Application
    Select Case TypeName(objApp.ActiveWindow)
        Case "Explorer"
            Set itm = objApp.ActiveExplorer.Selection.Item(1)
        Case "Inspector"
            Set itm = objApp.ActiveInspector.CurrentItem
    End Select
    
    If Not itm Is Nothing Then
        If itm.Class = olMail Then
            itm.Save
            Set objSafeMailItem = CreateObject("Redemption.SafeMailItem")
            Set rpl = CreateObject("Redemption.SafeMailItem")
            objSafeMailItem.Item = itm
            rpl.Item = itm.Forward
            rpl.Subject = Replace(rpl.Subject, "FW:", "RE:")
            rpl.Recipients.Add (objSafeMailItem.Sender.Name)
            
            For Each olkRecipient In objSafeMailItem.Recipients
                rpl.Recipients.Add (olkRecipient.Name)
            Next
            
            rpl.Recipients.ResolveAll
            rpl.Display
        Else
            MsgBox "Please select any email item, then click this button."
        End If
    End If
    
    Set rpl = Nothing
    Set itm = Nothing
    Set objApp = Nothing
    Set objSafeMailItem = Nothing
    
End Sub

Open in new window

0
 
LVL 1

Author Comment

by:deshaw
ID: 24247740
BlueDevilFan, Any update for my last two posts?
Thanks.
0
 
LVL 76

Accepted Solution

by:
David Lee earned 2000 total points
ID: 24255179
"How to identify that user clicked forward button for current inspector item because NewInspector gets invoked for every events like Reply, Reply All etc."
The NewInspector event doesn't determine if an item is a forward or reply.  The NewInspector event is used to set a watch on the item that's been opened in the new inspector.  It's the job of THAT object to catch the forward event.  Here's the sequence the actions have to occur in along with the code required for that steo.

1.  Begin monitoring the inspectors collection for new inspectors.

    Dim WithEvents olkInspectors As Outlook.Inspectors

    Private Sub Application_Startup()
        Set olkInspectors = Outlook.Inspectors
    End Sub

2.  The NewInspector event fires.  Begin monitoring the item opened in the new insepector.

    Dim WithEvents olkMsg As Outlook.MailItem

    Private Sub olkInspectors_NewInspector(ByVal Inspector As Inspector)
        Set olkMsg = Inspector.CurrentItem
    End Sub

3.  The user forwards the currently open message.

    Private Sub olkMsg_Forward(ByVal Forward As Object, Cancel As Boolean)
        'Code for taking action on the item being forwarded goes here.'
    End Sub


"If I not invoke  objMailItem_Forward from NewInspector event then it never gets invoked at all."
You do not want to invoke the forward command from the NewInspector.  If you did, then you'd forward every message you opened.  Clearly not what you want.

"Could you tell me if it is possible to add To and CC list recipients from selected email to email being sent?"
Sorry, I don't understand.  Are you asking if it's possible to only copy over some of the recipients instead of all of them?  If that's not the question, then I've no idea what you're asking.  

"I am not sure if we set anything else like objSafeMailItem.Recipient.Class so that it put recipient in particular To or CC list."
If you're copying the recipient from the original message, then there's no need to change the class.  It'll be copied over too.
0
 
LVL 1

Author Closing Comment

by:deshaw
ID: 31574143
Thanks BlueDevilFan
0
 
LVL 76

Expert Comment

by:David Lee
ID: 24268104
You're welcome.
0
 
LVL 1

Author Comment

by:deshaw
ID: 24268120

Could you please help me on http://www.experts-exchange.com/Software/Office_Productivity/Groupware/Outlook/Q_24354609.html
I think you are the only person helping me in all Outlook problems. :-)
Thanks for being there.
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article lists the top 5 trialware OST to PST Converter Tools. These tools save a lot of time for users when they want to convert OST to PST after their Exchange server is no longer available or other critical issues with Exchange server or impo…
By default Outlook 2016 displays only one time zone in the Calendar. The following article explains how to display two time zones in one calendar view.
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
As many of you are aware about Scanpst.exe utility which is owned by Microsoft itself to repair inaccessible or damaged PST files, but the question is do you really think Scanpst.exe is capable to repair all sorts of PST related corruption issues?
Suggested Courses

862 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question