Получение адреса электронной почты из недоставленной электронной почты Outlook с помощью VBA

У меня есть цепочка макросов для достижения желаемой задачи, которая включает в себя отправку электронной почты из одной конкретной учетной записи в Outlook каждому отдельному сотруднику по продажам. Адрес электронной почты извлекается из имени Sales Associates в Excel, например, Col B. (FirstName LastName) Я разделил имя и прикрепил домен. В редких случаях адрес электронной почты Sales Associates - это не просто FirstName LastName, поэтому мне нужно обнаружить возвращенное письмо.

Если адрес электронной почты неверен, Outlook отправляет сообщение «Не доставлено» (отчет о недоставке). Я пытаюсь получить адрес электронной почты из этого недоставленного сообщения. Иногда эти недоставленные электронные письма заменяются «китайскими» символами.

Я не специалист по VBA. Я пробовал несколько решений из Интернета, но, похоже, ни одно из них не работает.

https://answers.microsoft.com/en-us/office/forum/office_2013_release-customize/problem-in-vba-reading-text-from-body-of-out-of/1d8ca369-a4c0-41da-9d28-3f490de3ed8c

Извлечь текстовую строку из недоставленного тела письма для Excel

Отчет о недоставке в Outlook - проблемы с поиском элементов, VBA


person Cody    schedule 09.06.2020    source источник
comment
Ответ для stackoverflow.com/questions/43161382/ по-прежнему применяется - единственные варианты: расширенный MAPI (C ++ или Delphi) или Redemption (любой язык).   -  person Dmitry Streblechenko    schedule 09.06.2020
comment
Мне такой подход не кажется разумным. Сообщение электронной почты, которое невозможно доставить, может прийти спустя много времени после того, как оно было отправлено. Эти письма настолько незначительны, что задержка не имеет значения? Я бы сгенерировал столбец адресов электронной почты, используя ваш текущий подход, а затем исправил бы несколько неправильных адресов. Я бы использовал этот столбец при отправке будущих писем, чтобы все они сразу шли по правильному адресу.   -  person Tony Dallimore    schedule 10.06.2020
comment
Подход @TonyDallimore - это то, что я использовал.   -  person Cody    schedule 17.06.2020


Ответы (2)


Вы можете попробовать использовать свойство ReportItem.Body для получения адресов электронной почты. Если он по-прежнему не работает, как указано на страницах, упомянутых в вашем сообщении, вы можете:

  1. Используйте низкоуровневый API, на котором основан Outlook - Extended MAPI или любые сторонние оболочки для этого API, такие как Redemption.
  2. Сохраните элемент на диск, затем проанализируйте его и получите отсюда необходимую информацию.
person Eugene Astafiev    schedule 09.06.2020
comment
ReportItem объект не предоставляет свойство Recipients. - person Dmitry Streblechenko; 09.06.2020
comment
Вы правы, изначально я хотел вместо этого написать Body :) - person Eugene Astafiev; 09.06.2020

Немного проработав этот вопрос, по существу потому, что элемент в Outlook на самом деле является объектом ReportItem класса REPORT.IPM.Note.NDR, а не объектом MailItem, вы не можете извлечь из него информацию так, как вы обычно это делаете с MailItem Body, используя VBA.

Для фона причина искажения `` тела '' - это просто известная ошибка с объектами Outlook ReportItem при доступе с помощью VBA - содержимое фактически визуализируется Outlook на лету из различных скрытых значений свойств MAPI, поэтому на самом деле они не существуют как вы их видите, поэтому ценность «тела» бессмысленна.

Вчера я обновил свой ответ на странице Извлечь текстовую строку из недоставленное тело письма, чтобы преуспеть вопрос, который вы сказали, что уже рассматривали после того, как столкнулись с той же самой проблемой, много копались и собирали решение из разных источников.

Предполагая, что все элементы относятся к классу REPORT.IPM.Note.NDR (которым они обычно являются при использовании Exchange), вы можете использовать метод ReportItem.PropertyAccessor.GetProperty для ReportItem объект для доступа ко многим значениям свойств MAPI, которые обычно не предоставляются VBA / OLE.

Кредит Sidupac в этот пост для перечисления некоторых из наиболее распространенных, которые могут вам понадобиться, с их соответствующим шестнадцатеричным идентификатором и URL-адресами схемы Microsoft, как показано ниже:

Sub PAValues(olReportItem As Outlook.ReportItem)

Dim PA As Outlook.propertyAccessor
Set PA = olReportItem.propertyAccessor

On Error Resume Next
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x001A001E"), , "PR_MESSAGE_CLASS"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0037001E"), , "PR_SUBJECT"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x00390040"), , "PR_CLIENT_SUBMIT_TIME"
MsgBox PA.BinaryToString(PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x003B0102")), , "PR_SENT_REPRESENTING_SEARCH_KEY"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x003D001E"), , "PR_SUBJECT_PREFIX PT_STRING8"
MsgBox PA.BinaryToString(PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x003F0102")), , "PR_RECEIVED_BY_ENTRYID"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0040001E"), , "PR_RECEIVED_BY_NAME"
MsgBox PA.BinaryToString(PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x00410102")), , "PR_SENT_REPRESENTING_ENTRYID"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0042001E"), , "PR_SENT_REPRESENTING_NAME"
MsgBox PA.BinaryToString(PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x004F0102")), , "PR_REPLY_RECIPIENT_ENTRIES"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0050001E"), , "PR_REPLY_RECIPIENT_NAMES"
MsgBox PA.BinaryToString(PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x00510102")), , "PR_RECEIVED_BY_SEARCH_KEY"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0064001E"), , "PR_SENT_REPRESENTING_ADDRTYPE"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0065001E"), , "PR_SENT_REPRESENTING_EMAIL_ADDRESS"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0070001E"), , "PR_CONVERSATION_TOPIC"
MsgBox PA.BinaryToString(PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x00710102")), , "PR_CONVERSATION_INDEX"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0075001E"), , "PR_RECEIVED_BY_ADDRTYPE"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0076001E"), , "PR_RECEIVED_BY_EMAIL_ADDRESS"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x007D001E"), , "PR_TRANSPORT_MESSAGE_HEADERS"
MsgBox PA.BinaryToString(PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0C190102")), , "PR_SENDER_ENTRYID"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0C1A001E"), , "PR_SENDER_NAME"
MsgBox PA.BinaryToString(PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0C1D0102")), , "PR_SENDER_SEARCH_KEY"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0C1E001E"), , "PR_SENDER_ADDRTYPE"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0C1F001E"), , "PR_SENDER_EMAIL_ADDRESS"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0E02001E"), , "PR_DISPLAY_BCC"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0E03001E"), , "PR_DISPLAY_CC"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0E04001E"), , "PR_DISPLAY_TO"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0E060040"), , "PR_MESSAGE_DELIVERY_TIME"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0E070003"), , "PR_MESSAGE_FLAGS"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0E080003"), , "PR_MESSAGE_SIZE"
MsgBox PA.BinaryToString(PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0E090102")), , "PR_PARENT_ENTRYID"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0E12000D"), , "PR_MESSAGE_RECIPIENTS"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0E13000D"), , "PR_MESSAGE_ATTACHMENTS"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0E1B000B"), , "PR_HASATTACH"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0E1D001E"), , "PR_NORMALIZED_SUBJECT"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0E1F000B"), , "PR_RTF_IN_SYNC"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0E28001E"), , "PR_PRIMARY_SEND_ACCT"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0E29001E"), , "PR_NEXT_SEND_ACCT"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0FF40003"), , "PR_ACCESS"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0FF70003"), , "PR_ACCESS_LEVEL"
MsgBox PA.BinaryToString(PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0FF80102")), , "PR_MAPPING_SIGNATURE"
MsgBox PA.BinaryToString(PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0FF90102")), , "PR_RECORD_KEY"
MsgBox PA.BinaryToString(PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0FFA0102")), , "PR_STORE_RECORD_KEY"
MsgBox PA.BinaryToString(PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0FFB0102")), , "PR_STORE_ENTRYID"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0FFE0003"), , "PR_OBJECT_TYPE"
MsgBox PA.BinaryToString(PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0FFF0102")), , "PR_ENTRYID"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x1000001E"), , "PR_BODY"
MsgBox PA.BinaryToString(PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x10090102")), , "PR_RTF_COMPRESSED"
MsgBox PA.BinaryToString(PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x10130102")), , "PR_HTML"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x1035001E"), , "PR_INTERNET_MESSAGE_ID"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x1045001E"), , "PR_LIST_UNSUBSCRIBE"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x1046001E"), , "N/A"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x30070040"), , "PR_CREATION_TIME"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x30080040"), , "PR_LAST_MODIFICATION_TIME"
MsgBox PA.BinaryToString(PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x300B0102")), , "PR_SEARCH_KEY"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x340D0003"), , "PR_STORE_SUPPORT_MASK"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x340F0003"), , "N/A"
MsgBox PA.BinaryToString(PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x34140102")), , "PR_MDB_PROVIDER"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x3FDE0003"), , "PR_INTERNET_CPID"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x80050003"), , "SideEffects"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x802A001E"), , "InetAcctID"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x804F001E"), , "InetAcctName"
MsgBox PA.BinaryToString(PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x80660102")), , "RemoteEID"
MsgBox PA.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x80AD001E"), , "x-rcpt-to"

End Sub

Синтаксис - это просто метод GetProperty объекта ReportItem.propertyAccessor с соответствующим URL-адресом схемы в качестве аргумента (немного отличается для двоичных значений).

ReportItem.propertyAccessor.GetProperty("SCHEMA-URL")

or

ReportItem.propertyAccessor.BinaryToString(ReportItem.propertyAccessor.GetProperty("SCHEMA-URL")

для стандартных и двоичных свойств соответственно, поэтому вы можете обрабатывать возвращаемые значения по своему усмотрению в переменных или в соответствии с вашим существующим кодом, что бы он ни делал.

В частности, для исходного адреса (а) электронной почты получателя из отчета о недоставке вам нужна запись схемы http://schemas.microsoft.com/mapi/proptag/0x0E04001E, что дает вам PR_DISPLAY_TO < / strong> значение свойства (исходный адрес (а) исходящего сообщения, к которому относится отчет о недоставке).

Это может вернуть только адрес электронной почты, список, разделенный точкой с запятой, если поле «Кому» содержит более одного получателя, у которого произошел сбой, или DisplayName.

Если получатель находится в ваших контактах, метод GetProperty возвращает их DisplayName, а не фактический адрес, что может быть недостатком, если все ваши получатели являются контактами. Кроме того, если получателей было несколько, вам нужно было бы использовать что-то вроде функции Split, чтобы разбить их на массив, чтобы перебирать их и обрабатывать их по отдельности.

Полное перечисление всех свойств можно найти на этом ресурсе Microsoft, но имейте в виду, что не все свойства MAPI доступны для метода GetProperty, а только те, которые имеют шестнадцатеричное значение до 0x8000, что я понял из моего чтения по этой проблеме.

person Matt B    schedule 28.07.2020