I am sending an email using the QTP outlook object model.
Here is the piece of code.
'Create an object of type Outlook
Set objOutlook = CreateObject("Outlook.Application")
Set myMail = objOutlook.CreateItem(0)
'Set the email properties
myMail.To = "some_mail_id#gmail.com"
myMail.CC = "some_mail_id_2#gmail.com; some_other_mail#yahoo.com" 'Sending mails to multiple ids
myMail.BCC = "" 'If BCC is not required, then this line can be omitted
myMail.Subject = "Sending mail from MS Outlook using QTP"
myMail.Body= "Test Mail Contents"
myMail.Attachments.Add("D:\Attachment.txt") 'Path of the file to be attached
'Send the mail
myMail.Send
Now I needed to retrieve the sender email address & store it in an environment variable. myMail.Sender or myMail.sendermailaddres both of them are not working me.
The following code will give you the first email address the user you're connected to Outlook has access to:
objOutlook.Session.Accounts.Item(0)
I use a loop to find the account I want to send from like this:
iAccount = 0
For iLoop = 1 To oOutlook.Session.Accounts.Count
If UCase(Trim(oOutlook.Session.Accounts.Item(iLoop))) = UCase(Trim(EmailData("SendFrom"))) Then
iAccount = iLoop
Exit For
End If
Next
where EmailData is a Dictionary object containing the items I'm using for the mail item. When creating the mail item I use Set oMailItem.SendUsingAccount = oOutlook.Session.Accounts.Item(iAccount) to specify the account it should be sent from.
Related
In my company we have a number of different email addresses which go to "Shared Inbox" accounts that are managed by a few people.
We want to keep track of how many emails are in each Inbox.
A user might look after several different shared inboxes, and no one user has access to the same set of inboxes.
The VBA code I have loops through all of the logged-in user's shared inboxes and counts how many emails are in each inbox folder which isn't their own "personal" inbox and logs that data to a table using a separate procedure:
Sub WorkPosition()
Dim ThisUser As String
Dim Mailbox As Object
Dim MailBoxName As String
Dim oStore As Outlook.Store
Dim olFolder As Outlook.Folder
ThisUser = UCase(Environ("UserName"))
For x = Application.Session.Stores.Count To 1 Step -1
Set Mailbox = Nothing
On Error Resume Next
Set Mailbox = Application.Session.Stores(x)
On Error GoTo 0
If Mailbox Is Nothing Then GoTo SkipMailbox
MailBoxName = Mailbox
If InStr(UCase(Mailbox), ThisUser) = 0 Then
Set olFolder = Mailbox.GetDefaultFolder(olFolderInbox)
Set objItems = olFolder.Items
MailCount = objItems.Count
LogFolder MailBoxName, MailCount, ThisUser 'Run the "Logfolder" sub which logs the data
End If
SkipMailbox:
Next x
End Sub
This all works, except users don't name their shared inbox accounts very well. Several users have the same name for their shared inbox, but they're associated to different email addresses.
For example:
Charles might have info#mycompany.com as an Outlook store named "Customer Questions"
David might have queries#mycompany.com as an Outlook store also named "Customer Questions"
When Charles and David log their mail counts using my VBA code, they are both being logged with the MailBoxName as "Customer Questions".
I've come to the conclusion that I don't want to log the mailbox name. I want to log the email address instead, which they can't change and will be unique to that inbox.
I am able to do this if there is an email in the inbox, since I can just take the "to" address from the first mail item in the folder, but not if there are 0 emails in the folder.
How can I extract the incoming email address(es) which are associated to a user's Outlook store into a VBA string, so that I can pass it to my "LogFolder" procedure?
Outlook Object Model does not expose anything like that.
If using Redemption is an option (I am its author), it exposes RDOExchangeMailbox.Owner property (returns RDOAddressEntry object):
skPrimaryExchangeMailbox = 3
skDelegateExchangeMailbox = 4
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
for each Store in Session.Stores
If (Store.StoreKind = skPrimaryExchangeMailbox) or (Store.StoreKind = skDelegateExchangeMailbox)Then
Debug.Print Store.Name & " : " & Store.Owner.SMTPAddress
End If
next
I'm trying to use Word VBA to send a document to an email recipient. For the most part, it is not difficult. I have this code so far:
With oItem
'Set the recipient for the new email
.To = "person1#mail.com"
'Set the recipient for a copy
.CC = "ccperson#mail.com"
'Set the subject
.Subject = "Blah blah"
End With
My problem is that I have several sender email addresses configured in Outlook, and Outlook is picking the wrong one by default.
Is there a way to specify a sender email address using the method above? Needless to say, the intuitive code line for specifying a sender address (.From = me#wherever.com) does not work. Thank you.
UPDATE:
I finally got my code to work after modifying it using the suggestions from peakpeak and Dimitry below. My changes were
1) to include a reference to the Microsoft Outlook 16 object library so that I could get access to the Outlook.MailItem datatype. The mail would send fine with the code above (without the reference), but would always send with the wrong From address.
2) Declare the mail item as Outlook.MailItem. This seemed to enable the SentOnBehalfOfName field.
3) Used my desired From: email address in the SentOnBehalfOfName field.
Here is the working code:
Dim MAPIMailItem As Outlook.MailItem
Set MAPIMailItem = olkApp.CreateItem(olMailItem) 'Create a new mail message
With MAPIMailItem
.BodyFormat = olFormatPlain
.to = strTo
' SentOnBehalfOfName sets the From field on my machine,
' AFTER I declared MAPIMailItem as Outlook.MailItem
.SentOnBehalfOfName = "fromAddress#foo.com"
.Subject = strSubject
.body = strBody
.attachments.Add strAtt
'.send
.Display
End With
I use this code:
Dim WantedAccount as String ' Set to preferred account name
Set MAPISession = objOutlook.Application.Session 'Get the MAPI Outlook session
Set MAPIMailItem = objOutlook.CreateItem(olMailItem) 'Create a new mail message
With MAPIMailItem
For Each Account In MAPISession.Accounts
If Account = WantedAccount Then
.SendUsingAccount = Account
Exit For
End If
Next
If you are sending through an Exchange account, set the MailItem.SentOnBehalfOfName property (assuming you have the right to send on behalf of the specified mailbox). If you are sending through a POP3/SMTP account, set the MailItem.SendUsingAccount property.
We currently have an email automatically created by Excel using VBA, with subject, recipient, message body with template text all filled in.
Sub CreateMail(Optional sFile As String = "")
'Create email to send to requestor with attachment sFile
'Declarations
Dim app As Outlook.Application
Dim msg As Outlook.MailItem
Dim send_to As Recipient
Dim send_tos As Recipients
'Initiations
Set app = CreateObject("Outlook.Application")
Set msg = app.CreateItem(olMailItem)
Set send_tos = msg.Recipients
Set send_to = send_tos.Add("receiver#email.com")
send_to.Type = 1
'Create message
With msg
.SentOnBehalfOfName = "sender#email.com"
.Subject = "This is the email subject"
.HTMLBody = "This is the email body" & vbCrLf
'Resolve each Recipient's name.
For Each send_to In msg.Recipients
send_to.Resolve
Next
If Len(sFile) > 0 Then
.Attachments.Add sFile
End If
.Display
End With
End sub
After making some manual changes to the email that is created, we'd like to send it and have a copy saved to a folder on the file system automatically (in addition to the usual sent folder in Outlook). Is there a way to do this all within Excel VBA?
I suspect it might be possible using Outlook VBA, however the folders are defined in Excel and we'd like to keep the code together in the one file.
What is your code for sending email? This works for me in an Excel VBA module:
Dim appOutLook As Outlook.Application
Dim MailOutLook As Outlook.MailItem
Set appOutLook = CreateObject("Outlook.Application")
Set MailOutLook = appOutLook.CreateItem(olMailItem)
With MailOutLook
.BodyFormat = olFormatRichText
.To = "email address"
.Subject = "Test"
.HTMLBody = "Test " & Now
.DeleteAfterSubmit = True 'to not retain in sent folder
.Display
.SaveAs "C:\filepath\Test.txt", 0
' .Send
End With
However, guess the real trick is allowing edit of the email before saving file. So far not seeing solution for that. Unfortunately the code execution does not pause while the message window is open. I was hoping for the pause since Office is supposed to be an integrated suite of apps - like opening a form in Access in dialog mode which does pause execution of code.
With code in Excel only, monitor the SentItems folder.
Utilizing Outlook Events From Excel
Confirm the mail from a unique ID.
The unique ID could be in the subject or body.
You could try saving the unique ID in PR_SEARCH_KEY. It is the same idea How, can get the exact sent Email from Sent Items folder? and How to uniquely identify an Outlook email as MailItem.EntryID changes when email is moved
I have a large number of forwarding email addresses which are all set to forward to the same email account. I find this is useful because if a business is hacked and my email address is stolen then I only have the change the email address for that business. For example, "amazon#mydomain.com", "ebay#mydomain.com" and "facebook#mydomain.com" would all be forwarded to "mailbox#mydomain.com".
When I want to send an email to the business, I have to go into Outlook and change the account set up to have the forwarding email address as the email address. I find this a nuisance. I know I can change who the email is from when I write it, but then the recipient sees "J Smith on behalf of newaddress#mydomain.com". I would rather it just showed the address I am using in the from field, as it does if I go into the account set up and change the email address there.
It would be nice to have a macro set up which asked me which email address I wanted to use and then sent the email for me. I have looked up how to change email account details in VBA, but it looks as if the details are all read-only. Is there a way to change my "from" email address cleanly? Or even setting up a new email account in VBA and deleting it immediately after sending it?
Try creating a userform with a combobox and a button on it. Load all your available accounts into the combobox to be able to select from it:
Private Sub UserForm_Initialize()
Dim acc As Account
For Each acc In ThisOutlookSession.Session.Accounts
Me.ComboBox1.AddItem acc.UserName
Next acc
End Sub
Then add some code to the button that selects the proper account:
Dim objApp As Outlook.Application
Dim objMail As Outlook.MailItem
Set objApp = ThisOutlookSession.Application
Set objMail = objApp.CreateItem(olMailItem)
With objMail
.To = "lala#lala.com"
.CC = ""
.BCC = ""
.Subject = "Test"
.Body = "Test"
Dim i As Integer
For i = 1 To ThisOutlookSession.Session.Accounts.Count Step 1
If ThisOutlookSession.Session.Accounts.Item(i).UserName = Me.ComboBox1.Value Then
.SendUsingAccount = ThisOutlookSession.Session.Accounts.Item(i)
End If
Next i
.Display
End With
Maybe there is an event that is called when you are creating a new email, otherwise you have to add a button or something to bring the form up.
I had this exact same problem and ended up being able to solve it by installing Outlook Redemption and using the following script...
' Redemption code below. Must install Redemption to work.
' http://www.dimastr.com/redemption/faq.htm#14
Dim sItem, Tag
Set sItem = CreateObject("Redemption.SafeMailItem")
sItem.Item = oMailItem
Tag = sItem.GetIDsFromNames("{00020386-0000-0000-C000-000000000046}", "From")
Tag = Tag Or &H1E 'the type is PT_STRING8
sItem.Fields(Tag) = GetHashedReply(oMailItem)
Tag = sItem.GetIDsFromNames("{00020386-0000-0000-C000-000000000046}", "Sender")
Tag = Tag Or &H1E 'the type is PT_STRING8
sItem.Fields(Tag) = GetHashedReply(oMailItem)
sItem.Subject = sItem.Subject 'to trick Outlook into thinking that something has changed
sItem.Save
...where oMailItem is a normal Outlook MailItem that you can get with CreateItem() or get passed to you in the ItemSend() parameters.
When trying to send emails using another inbox, I change .SentOnBehalfOfName to the email I want to send from.
But then the email arrives with "MyRealName on behalf of EmailAddressIWantToSendFrom".
How do I remove MyRealName?
EDIT:
Set outlookApp = CreateObject("Outlook.Application")
Set namespace = outlookApp.GetNamespace("MAPI")
namespace.Logon
Set MyItem = outlookApp.CreateItemFromTemplate(path_to_msg_file)
...
pretend that this comment is a bunch of code that modifies the body of MyItem, mostly doing text replacements in MyItem.HTMLBody
...
Set safeItem = CreateObject("Redemption.SafeMailItem")
Set oItem = MyItem
safeItem.Item = oItem
safeItem.To = "person I want to send to"
safeItem.SentOnBehalfOfName = "desired address I want to sent from"
safeItem.Recipients.ResolveAll
safeItem.Send
To be able to send as that user, you need to have both send-as and receive-as rights. You'd need to connect to that user's mailbox and create the new message in the mailbox of the user you are trying to send as.
EDIT:
Try something like the following:
set rSession = CreateObject("Redemption.RDOSession")
rSession.MAPIOBJECT = Application.Session.MAPIOBJECT
set Store= rSession.GetSharedMailbox("some GAL name")
set Folder = Store.GetDefaultFolder(olFolderOutbox)
set Msg = Folder.Items.Add
Msg.Subejct = "test"
Msg.To = "user#domain.demo"
Msg.Send