I have following vba code which reads a mailbox and sends reply to any users who send a invalid code as a reply to the mailbox, but sometimes the run time error (Outlook does not recognize one or more names) is received. My questions are,
Will creation of new MAPI profile resolve the issue or do i need to add a code that resolves the address and ignores if the email id no longer exist. if yes how do i do that?
Also in general whats the parameter to not send emails for specific condition?
Below is the code that we currently have:
Sub ResponseCodeError(Item As Outlook.MailItem)
'If not a valid code then send email to the User
If (Left(Item.Subject, 2) <> "S;" And Left(Item.Subject, 2) <> "N;") Then
Dim outobj, mailobj
Set outobj = CreateObject("Outlook.Application")
Set mailobj = outobj.CreateItem(0)
With mailobj
.To = Item.SenderEmailAddress
.Subject = "Invalid Code"
.Body = "Please use a valid CODE"
.Send
End With
'Move Email to Error Folder
mailboxNameString = "mailboxname"
FolderName = "Error"
Dim olApp As New Outlook.Application
Dim olNameSpace As Outlook.NameSpace
Dim olCurrExplorer As Outlook.Explorer
Dim olCurrSelection As Outlook.Selection
Dim olDestFolder As Outlook.MAPIFolder
Set olNameSpace = olApp.GetNamespace("MAPI")
Set olCurrExplorer = olApp.ActiveExplorer
Set olCurrSelection = olCurrExplorer.Selection
Set olDestFolder = olNameSpace.Folders(mailboxNameString).Folders(FolderName)
Item.Move olDestFolder
End If
Set outobj = Nothing
Set mailobj = Nothing
End Sub
I had once the same error, and I resolved it after 5 hours searching like crazy in the code. But it was much simpler: 1 email address had an error missing the .(dot) in the domain name.
Instead of setting the To property, call MailItem.Recipients.Add (returns Recipient object). Call Recipient.Resolve - it will return false if the name cannot be resolved.
The issue might be due to incorrect names, extra characters or spaces in some property of Item.(especially To, BCC, CC or collective property Recipients)
It might also be due to names not resolved yet before sending the mail. I am not sure but would assume that the error was due to trying to resolve names while sending the mail and probably being unable to resolve them due to some issue. Explicitly resolving names like the code below before the mail is sent should solve the issue.
Item.Recipient.ResolveAll can be used to resolve the names before sending the mail. It returns true if all names were successfully resolved.
Code: (Reference)
If Not myRecipients.ResolveAll Then
For Each myRecipient In myRecipients
If Not myRecipient.Resolved Then
MsgBox myRecipient.Name
End If
Next
End If
I have tested the code without adding and resolving recipients 1 by 1.(suggested by Dmitry)
I used Item.To, Item.BCC properties. Then used ResolveAll and send the mail only if all names are resolved.
I just ran into this error; code that had been working for years suddenly triggered the "Outlook does not recognize one or more names" error.
I discovered that the recipient was an Outlook shared folder name, ie. "My Shared Folder" and whether it is an Access 2016 or Outlook issue, the name could no longer resolve to its associated email address. Changing the recipient to "mysharedfolder#blahblah.com" resolved the issue for me.
SOLVED In my case in Outlook I had several contacts with the same e-mail (two companies that are run by one contact/e-mail) and that created the problem. I deleted one of the contacts so no e-mail is repeated in the contact list in Outlook and now it works. Note that my batch still sends an e-mail twice to that contact which info for each company which is what I wanted it.
Related
I create an email draft using the following VBA Code in Excel (2014):
Sub Send_email()
Dim OutApp As Object
Set OutApp = CreateObject("Outlook.Application")
Dim OutMail As Object
Set OutMail = OutApp.CreateItem(0)
With OutMail
.To = "myself#hotmail.com"
.Subject = "test email"
.HTMLBody = "Sample test body"
.Save
End With
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
If I open the saved email and send it manually, I receive an Undeliverable error message from System Administrator:
"Your message did not reach some or all of the intended recipients."
If I use:
.Send
instead of
.Save
The email is sent (with no Undeliverable error).
Hopefully this will help. I was able to resolve the issue for myself by adding a call to OutMail.Recipients.ResolveAll().
VB.NET
Call OutMail.Recipients.ResolveAll
This solved the issue for me. However, if you have a version of Outlook that does not support antivirus detection, you may get a message box prompting you that an external app is trying to access email addresses or something similar to this:
a program is trying to access e-mail address information ...
If you get this, Google the phrase above to find many articles on how to resolve. It has to do with trust settings in Outlook.
i run you code AS IS from within excel, and it's working well.
When i open outlook i found the draft , flagged "the message has not been sent".
The email is saved in Drafts Folder of my Outlook, and i can view it in outlook.
I opened the draft email and sent it by pressing the sent button , and it is sent successfully.
i can't guess the problem , for i didn't find it :).
Review the setting of your email in outlook, you may find something.
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.
Running it from MS Access (2007) via the Outlook Interop library. I get the error -2147221219 (8004011d) from the starred line on one user account, but not on another. Error appears to be related to permissions, and both accounts have Full Access permissions to the account who's calendar I'm trying to open and can open and create appointments to it via Outlook. Sample code
Public Function NewApt(MtgDate As Date, Cat As String)
Dim objOLApp As Outlook.Application
Dim objNS As Outlook.Namespace
Dim objCalendar As Outlook.Folder
Dim NewMtg As Outlook.AppointmentItem
Dim Org As Outlook.Recipient
Set objOLApp = New Outlook.Application
Set objNS = objOLApp.GetNamespace("MAPI")
Set Org = objNS.CreateRecipient("tuser#somewhere.com")
Org.Resolve
If Org.Resolved Then
** Set objCalendar = objNS.GetSharedDefaultFolder(Org, olFolderCalendar)
Else
MsgBox "Scheduling User failed to resolve, see Crimius."
Exit Function
End If
...
Any ideas why?
I know one reason why this error may appear.
Whe you use the GetSharedDefaultFolder method and the recipient in parameter 1 (Recipient) is hidden from the global address list such an error can occur:
COMException (0x8004011D):
The operation failed because of a registry or installation problem. Restart Outlook and try again. If the problem persists, reinstall.
Maybe, the Outlook-Datafile is protected by password.
Switch to Outlook, enter the Password for the Outlook-Container, and then try again.
I had exactly the same issue. A VBA module that ran during years suddenly refused to. After verification it turned out that the internal e-mail addresses changed to previous runs of the macro...
Changing to email addresses solved the problem.
I get thousands of Nagios alerts in my inbox daily, but many of them are actually trivial (even though Nagios reports them as critical). I want to check whether the text of these alerts contains numbers above a certain threshold; if the numbers are lower than that threshold, move the message to a junk folder. I should really work with my sysadmin to decrease the number of useless alerts Nagios sends in the first place, but humor me in my attempt at a creative workaround.
I'm using Outlook 2007 and have found several tutorials on writing Outlook macros in VB, including this one about programmatically creating a rule to move messages to different folders. That example uses a TextRuleCondition to check whether the subject contains any of the keywords in an array.
But I don't want to check for keywords, I want to check if a number in the message text is greater or less than a threshold value. For example, if the text of a message contains the following, it could be moved to a junk folder:
Nagios bad condition: foo = 3
But if a message contained this, I would want to keep it:
Nagios bad condition: foo = 157
This example seems a little more like what I want in terms of searching the content of the message for arbitrary text. But it requires the message to be open, so I'm not quite sure how to translate it into a rule. Any help would be appreciated.
The second example you link to will put you on the right track to write code that discriminates between good and junk e-mails.
Then you will want to put that code in the _ItemAdd event for the Inbox items, such that it runs every time something new pops up in your Inbox. Here's an example of what should go in your Outlook VBA module:
Public WithEvents myOlItems As Outlook.Items
Public Sub Application_Startup()
' Upon starting Outlook, set reference to the items in the Inbox.
Set myOlItems = Application.GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Items
End Sub
Private Sub myOlItems_ItemAdd(ByVal Item As Object)
' Because myOlItems is declared "WithEvents",
' the ItemAdd event will fire anytime something new pops up in the Inbox.
If TypeName(Item) = "MailItem" Then
' It's an e-mail.
' Here goes the code to test whether it should go to the junk folder.
Else
' It's something else than an e-mail.
' Do nothing.
End If
End Sub
JFC has already given you one way. Here is another using RULES to check messages as they arrive. Do this.
Open VBA Editor and paste this code in ThisOutlookSession
UNTESTED
Option Explicit
Sub Sample(MyMail As MailItem)
Dim strID As String, olNS As Outlook.NameSpace
Dim objInboxFolder As Outlook.MAPIFolder
Dim objDestinationFolder As Outlook.MAPIFolder
Dim olMail As Outlook.MailItem
Dim strFileName As String, strSubj As String
Dim Myarray() As String
Dim ThrsdVal As Long
strID = MyMail.EntryID
Set olNS = Application.GetNamespace("MAPI")
Set olMail = olNS.GetItemFromID(strID)
'~~> Email Subject
strSubj = olMail.Subject
'~~> Threshold value
ThrsdVal = 100
'Nagios bad condition: foo = 3
Myarray = Split(strSubj, "=")
Set objInboxFolder = olNS.GetDefaultFolder(olFolderInbox)
'~~> Destination folder
Set objDestinationFolder = objInboxFolder.Folders("Temp")
'~~> Check if less than threshold value
If Val(Trim(Myarray(1))) < ThrsdVal Then
olMail.Move objDestinationFolder
End If
Set olMail = Nothing
Set olNS = Nothing
End Sub
Now
1) Create a new Rule (Select "Check Messages When they Arrive")
2) In (Condition) select "From people or Distribution List"
3) Select the relevant email address from which you are getting the emails
4) In Actions, select "run a script" and then choose the above script.
5) Finally click on Finish and you are done :)
The best part about this is that you can run this rule for existing emails in your inbox folder as well :)
NOTE: Like I mentioned above, I have not tested the code so do let me know if you get any errors and I will rectify it. Also I am assuming that the message will have a subject with the format as "Nagios bad condition: foo = X". I have not included any error handling. I am sure you can take care of that :)
HTH
Sid
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.