Setting Send-From Account in VBA

J

Josh

Like many other posters I've seen, I sometimes send mail from the
wrong account in Outlook 2007. I wanted to create a macro that when I
sent a message, would prompt me to verify the sending account, and let
me change if necessary.

I have the following code:
Private Sub Application_ItemSend(ByVal item As Object, Cancel As
Boolean)

If TypeOf item Is Outlook.MailItem Then
'Show form that displays account list and sets
item.SendUsingAccount

'To debug, verify it's using the right account:
msgbox item.SendUsingAccount
End if

End Sub

The routine works in the sense that it displays the list of accounts,
and sets the item.SendUsingAccount value properly (the messagebox
displays the correct value). However, it goes through and sends the
mail from the originally selected account anyways. It seems like once
you get to the ItemSend event, it's too late to change the account for
the current message if it gets sent. However, if something interrupts
the sending process (like another check for having a subject that
could set cancel = TRUE and cancel the sending, or stepping through
the code in debug mode), it will actually update the sending account
(which I can see reflected in the message window, cause it didn't
actually send).

My question is... is there any way to update the SendUsingAccount
property once you get to the ItemSend event? If not, is there an
earlier place to trap this event? Is there a way to trap the event of
clicking the send button and then running this code?

Thanks in advance.
 
J

Jan Hyde (VB MVP)

Josh <[email protected]>'s wild thoughts were released on
Thu, 23 Oct 2008 07:25:02 -0700 (PDT) bearing the following
fruit:
Like many other posters I've seen, I sometimes send mail from the
wrong account in Outlook 2007. I wanted to create a macro that when I
sent a message, would prompt me to verify the sending account, and let
me change if necessary.

I have the following code:
Private Sub Application_ItemSend(ByVal item As Object, Cancel As
Boolean)

If TypeOf item Is Outlook.MailItem Then
'Show form that displays account list and sets
item.SendUsingAccount

'To debug, verify it's using the right account:
msgbox item.SendUsingAccount
End if

End Sub

The routine works in the sense that it displays the list of accounts,
and sets the item.SendUsingAccount value properly (the messagebox
displays the correct value). However, it goes through and sends the
mail from the originally selected account anyways. It seems like once
you get to the ItemSend event, it's too late to change the account for
the current message if it gets sent. However, if something interrupts
the sending process (like another check for having a subject that
could set cancel = TRUE and cancel the sending, or stepping through
the code in debug mode), it will actually update the sending account
(which I can see reflected in the message window, cause it didn't
actually send).

My question is... is there any way to update the SendUsingAccount
property once you get to the ItemSend event? If not, is there an
earlier place to trap this event? Is there a way to trap the event of
clicking the send button and then running this code?

Thanks in advance.

Why not set 'Cancel' yourself, set the properties you want
to change and resend.

You'll need some sort of flag to prevent being prompted on
the resend of course.
 
J

Josh

Josh <[email protected]>'s wild thoughts were released on
Thu, 23 Oct 2008 07:25:02 -0700 (PDT) bearing the following
fruit:











Why not set 'Cancel' yourself, set the properties you want
to change and resend.

You'll need some sort of flag to prevent being prompted on
the resend of course.

Well, that's what I had to settle for. I now just display a message
"Are you sure you want to send from account: ACCOUNT_NAME" OK/Cancel.
However, I was wondering if there was a more elegant solution.

As a follow-up, is there a way to know if a message is a new message
or a reply/forward? I don't really need to perform this check if I'm
simply replying to a message, it's more important for a new message.

Thanks,
Josh
 
J

JP

There are a couple of threads on the issue, and I can't locate them at
the moment, but I believe the consensus was you needed to use
Redemption to do this. I can try to locate them if you really want an
accurate answer.

Regarding your followup question, you would need to check the
ConversationIndex to see if there is an existing message. See
http://www.outlookcode.com/codedetail.aspx?id=1714 for code sample. As
an alternative, you could check if Left$(MailItem.Subject, 3) = "RE:"

HTH,
JP
 
D

Dmitry Streblechenko

Look at the ConversationIndex property - for new messages it will be 44
characters long (22 byte for the raw PR_CONVERSATION_INDEX binary property).

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
There are a couple of threads on the issue, and I can't locate them at
the moment, but I believe the consensus was you needed to use
Redemption to do this. I can try to locate them if you really want an
accurate answer.

Regarding your followup question, you would need to check the
ConversationIndex to see if there is an existing message. See
http://www.outlookcode.com/codedetail.aspx?id=1714 for code sample. As
an alternative, you could check if Left$(MailItem.Subject, 3) = "RE:"

HTH,
JP
 
J

Josh

Look at the ConversationIndex property - for new messages it will be 44
characters long (22 byte for the raw PR_CONVERSATION_INDEX binary property).

--
Dmitry Streblechenko (MVP)http://www.dimastr.com/
OutlookSpy  - Outlook, CDO
and MAPI Developer Tool

There are a couple of threads on the issue, and I can't locate them at
the moment, but I believe the consensus was you needed to use
Redemption to do this. I can try to locate them if you really want an
accurate answer.

Regarding your followup question, you would need to check the
ConversationIndex to see if there is an existing message. Seehttp://www.outlookcode.com/codedetail.aspx?id=1714for code sample. As
an alternative, you could check if Left$(MailItem.Subject, 3) = "RE:"

HTH,
JP

The length=44 for ConversationIndex worked like a charm. Thanks!

I'm not familiar with redemption and a quick search didn't reveal
anything too helpful. Would you mind posting an example?

Thanks,
Josh
 
D

Dmitry Streblechenko

You don't have to use Redemption for that. MailItem exposes the
ConversationIndex property as well.

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
Look at the ConversationIndex property - for new messages it will be 44
characters long (22 byte for the raw PR_CONVERSATION_INDEX binary
property).

--
Dmitry Streblechenko (MVP)http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool

There are a couple of threads on the issue, and I can't locate them at
the moment, but I believe the consensus was you needed to use
Redemption to do this. I can try to locate them if you really want an
accurate answer.

Regarding your followup question, you would need to check the
ConversationIndex to see if there is an existing message.
Seehttp://www.outlookcode.com/codedetail.aspx?id=1714for code sample. As
an alternative, you could check if Left$(MailItem.Subject, 3) = "RE:"

HTH,
JP

The length=44 for ConversationIndex worked like a charm. Thanks!

I'm not familiar with redemption and a quick search didn't reveal
anything too helpful. Would you mind posting an example?

Thanks,
Josh
 
J

Josh

You don't have to use Redemption for that. MailItem exposes the
ConversationIndex property as well.

--
Dmitry Streblechenko (MVP)http://www.dimastr.com/
OutlookSpy  - Outlook, CDO
and MAPI Developer Tool






The length=44 for ConversationIndex worked like a charm. Thanks!

I'm not familiar with redemption and a quick search didn't reveal
anything too helpful. Would you mind posting an example?

Thanks,
Josh

I'm not sure I understand. I know that I don't need Redemption for
figuring out if it's a new message or reply, I got that by using the
conversationIndex. The open question is still how to set the
item.SendUsingAccount property in the ItemSend event or to figure out
a way to set it earlier in the process.
 
D

Dmitry Streblechenko

You cannot change teh accout in teh ItemSen event.
As was previously suggested, Cancel the event, set the appropriate account,
then call MailItem.Send again.

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-

I'm not sure I understand. I know that I don't need Redemption for
figuring out if it's a new message or reply, I got that by using the
conversationIndex. The open question is still how to set the
item.SendUsingAccount property in the ItemSend event or to figure out
a way to set it earlier in the process.
 
J

Josh

You cannot change teh accout in teh ItemSen event.
As was previously suggested, Cancel the event, set the appropriate account,
then call MailItem.Send again.

--
Dmitry Streblechenko (MVP)http://www.dimastr.com/
OutlookSpy  - Outlook, CDO
and MAPI Developer Tool


I'm not sure I understand. I know that I don't need Redemption for
figuring out if it's a new message or reply, I got that by using the
conversationIndex. The open question is still how to set the
item.SendUsingAccount property in the ItemSend event or to figure out
a way to set it earlier in the process.

I see what you mean now. The only question I have is how/when to
resend the message. In ItemSend, I set a private variable currMailItem
= item (where item is the passed in parameter to ItemSend). However,
if I set cancel = true, and then try to run item.send, it says "You
cannot send an item that is already in the process of being sent. So,
I have a handle to the mailItem, but I don't know how I can call the
Send method. Given that I don't see any timers in the control box, and
any methods I call out to would all be called within ItemSend, I'm
still at a loss of how to accomplish this. The relevant code snippet
is:

If blnAccountChanged = True Then
Cancel = True 'Cancel sending current message
blnResending = True 'Set the resending flag
Set currMailItem = item
currMailItem.Send 'THIS LINE CAUSES AN ERROR FOR TRYING TO RESEND
Exit Sub
Else
'The account didn't change, so just send as normal
Cancel = False
End If

Thanks for your help.

-Josh
 
J

Josh

I see what you mean now. The only question I have is how/when to
resend the message. In ItemSend, I set a private variable currMailItem
= item (where item is the passed in parameter to ItemSend). However,
if I set cancel = true, and then try to run item.send, it says "You
cannot send an item that is already in the process of being sent. So,
I have a handle to the mailItem, but I don't know how I can call the
Send method. Given that I don't see any timers in the control box, and
any methods I call out to would all be called within ItemSend, I'm
still at a loss of how to accomplish this. The relevant code snippet
is:

If blnAccountChanged = True Then
  Cancel = True 'Cancel sending current message
  blnResending = True 'Set the resending flag
  Set currMailItem = item
  currMailItem.Send 'THIS LINE CAUSES AN ERROR FOR TRYING TO RESEND
  Exit Sub
Else
  'The account didn't change, so just send as normal
  Cancel = False
End If

Thanks for your help.

-Josh

Sorry, one more thing I just noticed. Setting item.SendUsingAccount
doesn't update the signature. So even if I could get it to update to
the new account and resend, it would still have the signature from the
old account. Any way around this?
 
D

Dmitry Streblechenko

No, a signature is set only when a brand new unsent message is displayed for
the very first time.
You really do not want Outlook to silently change anything in the messge
body...

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
I see what you mean now. The only question I have is how/when to
resend the message. In ItemSend, I set a private variable currMailItem
= item (where item is the passed in parameter to ItemSend). However,
if I set cancel = true, and then try to run item.send, it says "You
cannot send an item that is already in the process of being sent. So,
I have a handle to the mailItem, but I don't know how I can call the
Send method. Given that I don't see any timers in the control box, and
any methods I call out to would all be called within ItemSend, I'm
still at a loss of how to accomplish this. The relevant code snippet
is:

If blnAccountChanged = True Then
Cancel = True 'Cancel sending current message
blnResending = True 'Set the resending flag
Set currMailItem = item
currMailItem.Send 'THIS LINE CAUSES AN ERROR FOR TRYING TO RESEND
Exit Sub
Else
'The account didn't change, so just send as normal
Cancel = False
End If

Thanks for your help.

-Josh

Sorry, one more thing I just noticed. Setting item.SendUsingAccount
doesn't update the signature. So even if I could get it to update to
the new account and resend, it would still have the signature from the
old account. Any way around this?
 
J

Josh

No, a signature is set only when a brand new unsent message is displayed for
the very first time.
You really do not want Outlook to silently change anything in the messge
body...

--
Dmitry Streblechenko (MVP)http://www.dimastr.com/
OutlookSpy  - Outlook, CDO
and MAPI Developer Tool







Sorry, one more thing I just noticed. Setting item.SendUsingAccount
doesn't update the signature. So even if I could get it to update to
the new account and resend, it would still have the signature from the
old account. Any way around this?

Well, when you change the account manually on a message, it updates
the signature. So, I assumed there was a way that you could do it
programatically as well.

Any thoughts on the other question about how to resend the message
after the account has been manually changed?

Thanks,
Josh
 
D

Dmitry Streblechenko

Outlook changes the signature when the user sees the message and can correct
any problem.
AS for sending, it looks like Outlook prevents you from recursively calling
Send: you will need to cancel the ItemSend event, store the message entry id
i n a variable, reopen the message using Namespace.GetItemFromID at a later
point (timer event handler?) and call Send again.

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-

Well, when you change the account manually on a message, it updates
the signature. So, I assumed there was a way that you could do it
programatically as well.

Any thoughts on the other question about how to resend the message
after the account has been manually changed?

Thanks,
Josh
 
J

Josh

Outlook changes the signature when the user sees the message and can correct
any problem.
AS for sending, it looks like Outlook prevents you from recursively calling
Send: you will need to cancel the ItemSend event, store the message entryid
i n a variable, reopen the message using Namespace.GetItemFromID at a later
point (timer event handler?) and call Send again.

--
Dmitry Streblechenko (MVP)http://www.dimastr.com/
OutlookSpy  - Outlook, CDO
and MAPI Developer Tool


Well, when you change the account manually on a message, it updates
the signature. So, I assumed there was a way that you could do it
programatically as well.

Any thoughts on the other question about how to resend the message
after the account has been manually changed?

Thanks,
Josh

OK, this is almost there! I used your suggestion and have a timer that
gets activated and resends the message with the updated account a
second later. The only open issue is the signature. Technically the
original message does remain open on the screen for the second between
attempting to send the first time and actually sending the second
time. Do you have any suggestions for how to best update the signature
to match the new sending account during that time? I've seen some
samples using Word bookmarks or accessing the registry, but I wasn't
sure if there was a method you recommended.

Thanks again.

-Josh
 
J

Josh

Outlook changes the signature when the user sees the message and can correct
any problem.
AS for sending, it looks like Outlook prevents you from recursively calling
Send: you will need to cancel the ItemSend event, store the message entryid
i n a variable, reopen the message using Namespace.GetItemFromID at a later
point (timer event handler?) and call Send again.

--
Dmitry Streblechenko (MVP)http://www.dimastr.com/
OutlookSpy  - Outlook, CDO
and MAPI Developer Tool


Well, when you change the account manually on a message, it updates
the signature. So, I assumed there was a way that you could do it
programatically as well.

Any thoughts on the other question about how to resend the message
after the account has been manually changed?

Thanks,
Josh

Sorry if this is double-posting, I don't see my recent reply. I got
the sending portion working using a timer. This is almost complete,
but the signature issue remains. Now the original message gets
canceled, the account gets changed, and then a second later it resends
with the new account. What's the best way to change the signature at
this point? Technically the email is still being displayed on screen
so the user can see the changes. I've seen some suggestions of using
word bookmarks or reading the signature directly from the registry,
but I was wondering if you had a suggestion for the best way to do
that.

Thanks,
Josh
 
D

Dmitry Streblechenko

Unless you explicly remove the old signature and insert teh new onee, I
don't think there is a way to force Outlook to do that for you.

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
Outlook changes the signature when the user sees the message and can
correct
any problem.
AS for sending, it looks like Outlook prevents you from recursively
calling
Send: you will need to cancel the ItemSend event, store the message entry
id
i n a variable, reopen the message using Namespace.GetItemFromID at a
later
point (timer event handler?) and call Send again.

--
Dmitry Streblechenko (MVP)http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool


Well, when you change the account manually on a message, it updates
the signature. So, I assumed there was a way that you could do it
programatically as well.

Any thoughts on the other question about how to resend the message
after the account has been manually changed?

Thanks,
Josh

Sorry if this is double-posting, I don't see my recent reply. I got
the sending portion working using a timer. This is almost complete,
but the signature issue remains. Now the original message gets
canceled, the account gets changed, and then a second later it resends
with the new account. What's the best way to change the signature at
this point? Technically the email is still being displayed on screen
so the user can see the changes. I've seen some suggestions of using
word bookmarks or reading the signature directly from the registry,
but I was wondering if you had a suggestion for the best way to do
that.

Thanks,
Josh
 
J

Josh

Unless you explicly remove the old signature and insert teh new onee, I
don't think there is a way to force Outlook to do that for you.

--
Dmitry Streblechenko (MVP)http://www.dimastr.com/
OutlookSpy  - Outlook, CDO
and MAPI Developer Tool






Sorry if this is double-posting, I don't see my recent reply. I got
the sending portion working using a timer. This is almost complete,
but the signature issue remains. Now the original message gets
canceled, the account gets changed, and then a second later it resends
with the new account. What's the best way to change the signature at
this point? Technically the email is still being displayed on screen
so the user can see the changes. I've seen some suggestions of using
word bookmarks or reading the signature directly from the registry,
but I was wondering if you had a suggestion for the best way to do
that.

Thanks,
Josh

OK, explicitly removing and inserting is fine. However, I'm not sure
how to get started in terms of:
1) Locating the existing signature in the message and removing it
(given that I will have to determine where the signature block is,
since the text could be anything).
2) Determining which signature goes with the newly selected account
3) Inserting the new signature at the correct location.

Any ideas to get me started?

Thanks,
Josh
 
D

Dmitry Streblechenko

Are you sure you really, really want to do that?
Just to give you an example, if you start typing and then select a different
account, chances are you typed in an area that Outlook considers to be the
signature and wipes out your text. Happens to me about 50% of the time.
Luckily, Edit | Undo works fine.
If you do something like that after the user clicked Send and has no chance
to undo the changes or even be aware that something happened, you'll have a
large crowd of very, very unhappy customers.
In other words, don't do that.

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-

OK, explicitly removing and inserting is fine. However, I'm not sure
how to get started in terms of:
1) Locating the existing signature in the message and removing it
(given that I will have to determine where the signature block is,
since the text could be anything).
2) Determining which signature goes with the newly selected account
3) Inserting the new signature at the correct location.

Any ideas to get me started?

Thanks,
Josh
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top