I'm writing some code in VB.net which will zip some files with a password & email them to the recipient(s) & then send a second email to the recipient(s) with the password for the zip file. The email is sent through Outlook.
The people who would be using this also have some VBA code in the Application_ItemSend event procedure in Outlook which checks if there's attachments being sent to external email addresses & if so it gives the user the details & the option to Cancel sending the email - this is done using the Cancel property/argument (sorry I'm not good with the correct terminology for things in VBA/VB.net) of the Application_ItemSend event procedure.
If the user does cancel the first email then I'd like to stop the second email from going out aswell. I've tried checking (directly after invoking MailItem.Send()) MailItem.Sent.ToString but it bugs out on that line & gives this exception - System.Runtime.InteropServices.COMException: 'The item has been moved or deleted.
My first thought was that once MailItem.Send() was invoked that MailItem became nothing, but I've just put a watch for MailItem Is Nothing & it's returning False. I've tried searching but not been able to find anything.
I can work around by displaying the second email & leave it to the user to send or cancel but if possible I'd rather have the code take care of it.
Instead of sending the second email immediately, wait until Items.ItemAdd event fires on the Sent Items folder. Once the first message raises that event, you can create and send the second email.
Related
I have an outlook Macro that collects some information from existing emails and a local database, then serves up a templated email with the information. The user can then review the email, make changes if they want to and then send or not sent (quit/cancel). Is there a way, I can keep the macro running and then execute more code if the user sends the email?
I've created some psuedo code below on how I'm hoping it might work:
Function CreateEmailThenExecuteCode()
Dim newEmail As MailItem
Set newEmail = Application.CreateItem(olMailItem)
newEmail.Display
'Allow user to review and send email
'If they 'send', then execute further code.
If Not Sent Then Exit Function
'Further code
End Function
I know that I can create a new macro that runs every time a user sends an email - but it would be much easier if I can keep the existing macro running, as otherwise I need a way of saving the data from the running macro.
I also know that I can create a custom user form that mimics an email user form - but I would prefer to keep the functionality of the full email user form, especially with access to email address lists etc.
Is it possible?
The Display method doesn't prevent your code from running until you pass true to make the Inspector window modal. The default value is false.
At the same keeping the code running after the Display call doesn't allow users to deal with Outlook UI because the VBA code will be run on the main thread (UI).
You may consider setting up an event handler for the Send event which is fired when the user selects the Send action for an item, or when the Send method is called for the item. So, you will be aware when the item is sent out.
Also you may find the MailItem.Close event helpful. It is fired when the inspector associated with an item is being closed. So, you will also be aware when the item is closed.
I have to send a few hundred mails. The VBA code is working.
Outlook VBA has a .Send method, which sends the mail without pausing. It also has a .display method, which displays a mail item. The displayed mail can then be sent by clicking on the Send button in Outlook.
The requirement is:
In a loop of say, 100 mails, the user should be able to review the first few messages. They should be displayed and then sent by clicking the Send button.
Once the user is ok with a few sample mails, he should be able to send the rest of the messages without reviewing them.
In short, till the user is comfortable the mailitem.display should work and thereafter mailitem.send should work.
Sure, when you loop (from 1 to 100), call MailItem.Display(true) for i <= 10 and MailItem.Send otherwise.
I got an issue with the macro I did in Outlook. To resume, the macro starts every time I receive an email. Then it will run a few others Sub, modify an Excel file and so one. When Outlook is running and I receive a new email, everything works perfectly. The problem occurs when I open Outlook and I receive more than one email at the same time.
I suppose the macro doesn't have enough time to end what it's doing with the first email and already try to start again with the next one.
Is there a way to keep the next emails in suspend in order to run the macro for each email, each one has its turn ? Or maybe you have another solution ?
Thank you.
PS: I can provide the code but it's very long.
The problem occurs when I open Outlook and I receive more than one email at the same time.
The NewMailEx event of the Application class is fired once for every received item that is processed by Microsoft Outlook. The item can be one of several different item types, for example, MailItem, MeetingItem, or SharingItem. The EntryIDsCollection string contains the Entry ID that corresponds to that item.
The NewMailEx event fires when a new message arrives in the Inbox and before client rule processing occurs. You can use the Entry ID returned in the EntryIDCollection array to call the NameSpace.GetItemFromID method and process the item.
Make sure VBA macros are enabled and allowed to run when Outlook is started. Check out the Trust Center settings in Outlook.
I have Outlook VBA code that reads all incoming mails.
This code uses the MailItem to go through each mail looking at sender, to, subject and for attachments.
The heart of the code uses the urn:schemas feature that does a sql query on the inbox.
Thus if a new mail arrives the process that fires looks at the whole inbox every time and not just that mail. (The inbox is kept tidy and items are moved when processed.)
The heart of the query looks like this:
Dim Filter as String
Filter = "urn:schemas:mailheader:subject like '%That report - %'"
Dim iMailMatch As Object
Set iMailMatch = Inbox.items.Find(Filter)
The problem is that (occasionally) when the machine is locked (not logged out), the macro will fire on a new mail event, but it won't find anything even though there are mails which match.
When I unlock the terminal and a new mail arrives - the process fires and it picks up/processes mails successfully that it previously didn't see.
The problem is only apparent when the terminal is locked. Thus I can only think that it has to do with kind of trust privileges.
There are times is does fire successfully when the terminal is locked, but it appears to be only when a mail arrives soon after the terminal is locked.
Do not search. NewMailEx event passes the entry id of the new item to your event handler - open the item using Namespace.GetItemFromID, then read the MailItem.Subject property.
I tried to search across on StackOverflow and Google, but had no success.
Am creating a form application to accept some information for the body of an email, create a HTML email and send via Outlook.
Everywhere I looked and found sending via GMail. But I want to be able to send via outlook without user interruption.
Could someone help me with a code to call outlook, frame the message and send automatically. Also should be able to enter some extra recipients via their username on the domain and it should automatically resolve and pickup the email and send to them when sending via outlook.
The message contents may have fields like Name, Email Address, Phone Number, Address. This should all sit inside a HTML email in a table.
Whilst i am puzzled you cant find what you are looking for i am going to provide an answer as the title is very clear so it could simplify searching for others in the future.
Dim Outlook As New Microsoft.Office.Interop.Outlook.Application
Dim MailItem As Microsoft.Office.Interop.Outlook.MailItem
MailItem = Outlook.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem)
With MailItem
.HTMLBody = "put the body of your email here as a string"
.Subject = "Subject Line Info"
'use the below to change from the default email account
.SentOnBehalfOfName = "YourEmail#yourdomain.you"
'you can add multiple recipients using .Add()
.Recipients.Add("Recipient#theirdomain.them")
'examples of other optional arguments that can be included
.Attachments.Add([file])
.Importance = Microsoft.Office.Interop.Outlook.OlImportance.olImportanceHigh
.Display() 'opens the email for checking prior to sending or use .Send()
End With
As per the comment from Rahul below you will also need to add a Reference to the Microsoft Office 14.0 Object Library.