We currently use the following code to create an email in Outlook so that the user can type what they want in Outlook, then when the email is sent, the system prompts them to see if they would like to save the email.
Dim objOutlook As Object
Dim objMessage As Object
Dim objInspector As Object
If strEMail <> "" Then
objOutlook = CreateObject("Outlook.Application")
objMessage = objOutlook.CreateItem(0)
objMessage.To = strEMail
objInspector = objMessage.GetInspector
objInspector.Display()
While Not objInspector.CurrentItem Is Nothing
End While
frmSaveSentEmail.BringToFront()
frmSaveSentEmail.ShowDialog()
The code works fine on Outlook 2003 as long as they are not using Word as their email editor. However, with Word set up as the email editor, the while loop that tests to see if the email object is closed never ends.
Is there a way to handle this differently so that it will work even with Word as the editor?
I am not terribly experienced with programming Outlook via VB.NET, but that loop certainly looks suspicious. Perhaps you should try taking advantage of the inspector's Close event instead of repeatedly checking its CurrentItem property. If I am not mistaken, you should be able to present your dialog within the event handler.
Ended up changing the loop to:
While Not objOutlook.ActiveInspector Is Nothing
End While
This resolved the issue.
Related
I'm new to creating Add-In's for Outlook, but have managed to crash and bash my way through most of what I'm trying to do. I have been trying in C# as most examples and documentation use C#, however I'm not that comfortable writing in C#. I have used VBA quite a lot in the past so VB.Net is easier for me to use.
So far my Add-In does the following:
Adds a button when reading an email (OfficeID set to TabReadMessage).
When you click the button a form is displayed which asks for some information.
There's a button on the form to continue which validates the form and identifies the current MailItem.
Using the current MailItem, it appends some text and then attempts to Forward the email with the revised text.
Where I'm stuck is with the Forward() function. I can update the To and Subject, but I can't Display() it.
I think I'm ok up to here
' Create an application object which is needed to get to the ActiveInspector
Dim application As Outlook.Application '
application = Globals.ThisAddIn.Application
' Variables to inspector, needed to get the current item, current mail item, the forward email (so we can update the subject)
Dim mailItem As Microsoft.Office.Interop.Outlook.MailItem
Dim forwardMailItem As Microsoft.Office.Interop.Outlook.MailItem
Dim oInspector As Microsoft.Office.Interop.Outlook.Inspector
Dim currentSubject As String
Dim forwardSubject As String
oInspector = application.ActiveInspector
mailItem = oInspector.CurrentItem
' forward email gets created here
forwardMailItem = mailItem.Forward()
currentSubject = mailItem.Subject
forwardSubject = "some other stuff added - " & currentSubject
If I do a MsgBox at this point and reference forwardMailItem.Subject, the new MailItem must be there as it displays the revised subject.
Once I add the following line, it's like the MailItem object has gone - ie if I do MsgBox(forwardMailItem.Subject) nothing happens.
forwardMailItem.Display()
If I remove the above line and just put the following, the email gets sent.
forwardMailItem.Send()
Part 1 - I can't get the forwardMailItem to display and don't understand why?
Part 2 - I don't know how to get the new Ribbon I created to also show when on the Home Ribbon. I found how to change the OfficeID to show it on TabReadMessage instead of the default TabAddIn, but don't know what to search for to find how to add it to the Home Ribbon.
My situation:
I'm trying to send e-mails while Outlook is not open. This code will work if Outlook is running. If Outlook is closed the code will create a non-visible process that you can see running in Task Manager.
The code encounters an error during the .Send. It returns runtime error 287.
From my experience that are certain VBA methods that will only work when the object is either visible or active.
My work around is to use .Display(False) before calling .Send.
After calling .Send it immediately terminates the Outlook process. (Please point me to the right direction why.) Then the e-mail gets stuck in the Outbox.
I have to apply another work around by calling another CreateObject("Outlook.Application") and either looping through the Outbox While Outbox.Items.Count > 0
or
Looping through SyncObjects and manually calling .Start to run Send/Receive on the Outbox.
My question:
Is there a way to directly use the .Send method instead of using work arounds while also not having to open Outlook.
My code:
Sub emailer()
Dim OutApp As Object
Dim OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
With OutMail
.to = "f#r.com"
.CC = ""
.BCC = ""
.Subject = "This is the Subject line"
.Body = "Hi there"
.Send 'or use .Display
End With
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
A workaround for the .send issue with Outlook closing can possibly be resolved by changing the settings for Send/Receive. Go to File -> Options -> Advanced -> find Send/Receive... and press it. Under "Setting for group "All Accounts" is a checkbox for Perform an automatic send/receive when exiting. Check this, and it may resolve the "stuck in the outbox issue you are having".
Here is a screenshot:
Give this a try, hopefully it helps.
Use Namespace.SendAndReceive. Keep in mind that Send/Receive is asynchronous and you need to wait to the sync to finish. You can use Namespace.SyncObjects collection, start a sync using SyncObject.Start, then wait for the SyncObject.SyncEnd event.
To prevent Outlook from closing, you need to keep a live reference to an Outlook Explorer or Inspector object. You can retrieve the Inbox folder using Namespace.GetDefaultFolder, then use MAPIFolder.GetExplorer method to get a pointer to an Explorer object.
UPDATE:
You might also want to make sure that you log to a MAPI profile before you create and send a message. After the CreateObject line, try to add the following
set NS = OutApp.GetNamespace("MAPI")
NS.Logon
I'm attempting to generate an email from MS Access when a particular procedure is run and certain conditions are met, the email will include a hyperlink. I've found the sendobject macro command does not allow for hyperlink, only static text. It seems that the solution is to code the portion of the entire process that generates and sends the email in VBA and call on that code in the appropriate segment of my if function within my macro.
I can't figure out the appropriate code to generate and send and email with a hyperlink to an individual however. It will be very simple, single recepient, unchanging title, and the body will read 'New providers require designation, please access the provider designation dashboard for provider designation' ideally the provider designation dashboard would be the hyperlink and point to a shared network space.
What commands do I need to accomplish this, I'm inexperienced in VBA and this is eating up a fair amount of time I don't have.
Thank you
There are some different approaches for sending e-mail with code. The code bellow uses an Outlook Application COM object to generate the message with a hyperlink - thus, it will only work if MS Outlook is installed in the user's machine.
Sub NewEmail(ByVal mylink As String, ByVal therecipient As String)
Dim Outlook As Object, Email As Object
Set Outlook = CreateObject("Outlook.Application")
Set Email = Outlook.CreateItem(0) 'olMailItem = 0
With Email
.Subject = "My Subject" 'message subject
.HTMLBody = "Greetings, please check this link: <a href='" & mylink & "'>Click me</a>." 'message body, in html. concatenate multiple strings if you need to
.To = therecipient 'recipient
'use this if you want to generate the message and show it to the user
.Display
'use this instead if you want the mail to be sent directly
'.Send
End With
Set Email = Nothing
Set Outlook = Nothing
End Sub
Put the code in a module. Then anywhere in your code you may call the procedure with something like:
NewEmail "www.mysite.com/targetpage.html", "persontomail#domain.com"
Notice that the routine above uses late binding. To use early binding (and get intellisese, but with some drawbacks), you would have to add a reference to Microsoft Outlook XX.X Object Library and dim the "Outlook" and "Email" objects as Outlook.Application and Outlook.MailItem, respectively.
I have a code that checks the recipient of the mail, looks what organization is set in the address book for the recipient and dependent on that sets the "SentOnBehalfOfName"-property of the item. If the recipient is working for client2, he will get the mail from "we_love_to_serve_client2#domain.com".
I call the code either before sending the mail via a button in my ribbon, that calls this Sub:
Sub Signatur()
Dim olApp As Outlook.Application
Dim objMail As Outlook.MailItem
Set olApp = Outlook.Application
Set objMail = Application.ActiveInspector.CurrentItem
Call Signatur_auto(objMail)
End Sub
I do this if I want to know which mail-adress is going to be chosen.
In the itemSend-section of thisOutlookSession I also call the same sub
Call Signatur_auto(Item)
Part of the Signatur_auto (i do not copy that in, the question is too long already...) is dealing with the SentOnBehalfOfName-property, the other part is putting the item into the right folder. The Folder is chosen depending on the SentOnBehalfOfName-property.
Now comes the interesting part: Although the folder-part is always working (which can only be when the SentOnBehalfOfName has worked before), the SentOnBehalfOfName only works "half". In the preview-line the mail sent is shown as from "we_serve_client2#domain.com", but when I open the mail it says it was sent by me. The Client always only sees my address, and also answers to my address - which I do not want....
How cant be, that the same code is having different results dependent on where it is called? Is it a Problem to change the sendonbehalf-field in the item send-section?
Thanks for any Inputs!
Max
Why it does not work?
Try this in ItemSend.
Dim copiedItem As mailItem
Set copiedItem = Item.Copy
copiedItem.SentOnBehalfOfName = "we_love_to_serve_client2#domain.com"
copiedItem.Send
Item.delete
Cancel = True ' In case your setup generates an error message as described in the comments
Why it works? Appears "copiedItem.Send" bypasses ItemSend.
I am completely stuck as to how to retrieve details of an email which is either currently selected or open. In fact, I can't find any details on how to access an email. It seems you can traverse the entire folder structure and get all emails, but that doesn't really help me.
I don't suppose I can get some pointers?
And yes, I hate VBA as much as the next developer, but unfortunately about 0.1% of my work involves integration with Outlook.
Cheers.
To get the currently selected emails by looking at the Selection object of the Explorer.
Dim myOlExp As Outlook.Explorer
Dim myOlSel As Outlook.Selection
Set myOlExp = Application.ActiveExplorer
Set myOlSel = myOlExp.Selection
The selection object can contain many items and also contain Items that are of other types than mail (IPM.Note) i.e calendar apps etc. So if you only want mail items you can take a look at the item MessageClass
As for the current email that is trickier as you can multuiple of these open if you just want the top most you can use the Application.ActiveInspector otherwise you should look at the Inspectors Collection of the Application object. You can then get the "item" from the CurrentItem property off the Inspector(remember these can be non mails as well)
Hope full that will get you going
I ended up here as I was looking for a way to use VBA to modify the email that is currently being composed. While the ActiveInspector solution above works if the new email is in a new window, it does not work if replying 'inline' (in the preview pane). For this, I wrote this function:
Private Function CurrentEmail() As MailItem
Dim thisMail As MailItem
If Application.ActiveInspector Is Nothing Then
'editing in preview pane
Set thisMail = Application.ActiveExplorer.ActiveInlineResponse
Else
'editing in pop out window
Set thisMail = Application.ActiveInspector.CurrentItem
End If
If thisMail Is Nothing Then Exit Function
If thisMail.Sent Then Exit Function 'ignore sent items
Set CurrentEmail = thisMail
End Function