Когда MailItem не является MailItem?

Я написал функцию обработки сообщений в Visual Basic для Outlook (мы используем Outlook 2003 и Exchange Server), чтобы помочь мне сортировать входящую электронную почту.

У меня это работает, за исключением того, что иногда правило не работает, и Outlook деактивирует его.

Затем я снова включаю правило и вручную запускаю его в папке «Входящие», чтобы наверстать упущенное. Правило самопроизвольно дает сбой и деактивируется несколько раз в день.

Я хотел бы исправить это раз и навсегда.


person Community    schedule 17.09.2008    source источник
comment
stackoverflow.com/a/42547062/4539709   -  person 0m3r    schedule 14.03.2020


Ответы (7)


Этот код показал мне разные имена типов, которые были в папке «Входящие»:

Public Sub GetTypeNamesInbox()
Dim myOlItems As Outlook.Items
Set myOlItems = application.GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Items
Dim msg As Object

For Each msg In myOlItems
    Debug.Print TypeName(msg)
    'emails are typename MailItem
    'Meeting responses are typename MeetingItem
    'Delivery receipts are typename ReportItem
Next msg

End Sub

ХТН

person Killian Tyler    schedule 29.12.2011

Я использую следующий фрагмент кода VBA в других приложениях Office, где прямо упоминается библиотека Outlook.

' Outlook Variables

  Dim objOutlook As Outlook.Application: Set objOutlook = New Outlook.Application
  Dim objNameSpace As Outlook.NameSpace: Set objNameSpace = objOutlook.GetNamespace("MAPI")
  Dim objFolder As MAPIFolder: Set objFolder = objNameSpace.PickFolder()
  Dim objMailItem As Outlook.MailItem

  Dim iCounter As Integer:  iCounter = objFolder.Items.Count
  Dim i As Integer

  For i = iCounter To 1 Step -1
    If TypeOf objFolder.Items(i) Is MailItem Then
      Set objMailItem = objFolder.Items(i)
      With objMailItem

и т. д.

person Bruce E. Leandro    schedule 29.08.2012
comment
Мне нравится TypeOf больше, чем жестко запрограммированный MailItem в виде строки. - person Rob I; 24.06.2014
comment
Хороший ответ, но в моем случае мне пришлось также проверить MessageClass, чтобы исключить случай IPM.Outlook.Recall, который в основном не имеет определенных свойств, кроме Subject - person Giulio; 02.12.2020
comment
На основе ms doc, для сообщений электронной почты необходимо проверить условие If TypeOf objFolder.Items(i) Is MailItem And objFolder.Items(i).MessageClass = "IPM.Note" Then - person Giulio; 02.12.2020

написали функцию обработки сообщений в Visual Basic для Outlook (мы используем Outlook 2003 и Exchange Server), чтобы помочь мне разобраться с входящей электронной почтой. У меня это работает, за исключением того, что иногда правило не работает, и Outlook деактивирует его. Затем я снова включаю правило и вручную запускаю его в папке «Входящие», чтобы наверстать упущенное. Правило самопроизвольно дает сбой и деактивируется несколько раз в день. Я хотел бы исправить это раз и навсегда.

Вот код, лишенный функциональности, но дающий вам представление о том, как он выглядит:

   Public WithEvents myOlItems As Outlook.Items

   Public Sub Application_Startup()
       ' Reference the items in the Inbox. Because myOlItems is declared
       ' "WithEvents" the ItemAdd event will fire below.
       ' Set myOlItems = Outlook.Session.GetDefaultFolder(olFolderInbox).Items
       Set myOlItems = Application.GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Items
   End Sub

   Private Sub myOlItems_ItemAdd(ByVal Item As Object)
       On Error Resume Next
       If TypeName(Item) = "MailItem" Then
           MyMessageHandler Item
       End If
   End Sub

   Public Sub MyMessageHandler(ByRef Item As MailItem)
       Dim strSender As String
       Dim strSubject As String

       If TypeName(Item) <> "MailItem" Then
           Exit Sub
       End If

       strSender = LCase(Item.SenderEmailAddress)
       strSubject = Item.Subject

       rem do stuff
       rem do stuff
       rem do stuff
   End Sub

Одна ошибка, которую я получаю, - это «Несоответствие типов», вызывающее MyMessageHandler, где VB жалуется, что Item не является MailItem. Хорошо, но TypeName(Item) возвращает «MailItem», так почему Item не является MailItem?

Еще один, который я получаю, это когда приходит электронное письмо с пустой темой. Линия

strSubject = Item.Subject

дает мне ошибку. Я знаю, что Item.Subject должен быть пустым, но почему это ошибка?

Спасибо.

person Community    schedule 17.09.2008
comment
TypeName запрашивает у типа удобочитаемую версию. Поскольку может быть два разных типа с одним и тем же именем, использование TypeName для проверки типов приведет к ложным срабатываниям/отрицательным результатам. Попробуйте TypeOf Item вместо MailItem - person rpetrich; 29.11.2008
comment
Если TypeName(Item) = "MailItem", то вызвать процедуру... которая не только принимает только MailItems, но еще раз проверяет, является ли элемент MailItem? - person JimmyPena; 21.06.2012

Моя память об этом несколько туманна, но я считаю, что MailItem не является MailItem, когда это что-то вроде уведомления о прочтении. (К сожалению, код VBA, демонстрирующий это, был написан на другой работе, и сейчас его нет.)

У меня также был написан код для обработки входящих сообщений, вероятно, по той же причине, что и вы (слишком много правил для Exchange или правила слишком сложны для Мастера правил), и, кажется, я столкнулся с той же проблемой, что и у вас, что некоторые элементы казались быть из другого типа, хотя я ловил их чем-то вроде того, что вы написали.

Я посмотрю, смогу ли я привести конкретный пример, если это поможет.

person Dave DuPlantis    schedule 29.09.2008

Существует множество типов элементов, которые можно увидеть в папке «Входящие» по умолчанию.

В вызываемой процедуре присвойте входящий элемент переменной типа Object. Затем используйте TypeOf или TypeName, чтобы определить, является ли это MailItem. Только тогда ваш код должен выполнять действия, применимые к электронным письмам.

i.e.

Dim obj As Object

If TypeName(obj) = "MailItem" Then
  ' your code for mail items here
End If
person JimmyPena    schedule 21.06.2012

почему бы не использовать простой обработчик ошибок для кода? Шутки в сторону. Вы можете написать ошибку для каждого чтения свойства или объекта, которое кажется неудачным. Тогда пусть это Резюме, несмотря ни на что. Нет необходимости в сложной обработке ошибок. Подумайте о тесте, который показывает пустой предмет. Поскольку вы не знаете, какое значение он вернет, если оно вообще есть, и, похоже, он выдает ошибку на пустом или пустом объекте, вам нужно представить его как простой тест с возможной ошибкой. Запустите тест как оператор if (в котором вы все равно получите сообщение об ошибке) и возобновите работу программы при ошибке.

On Error Resume Next
If object.subject = Null 'produces an error when subject is null, otherwise allows a good read
  strSubject = ""   'sets the subject grab string to a null or empty string as a string
Else
 strSubject = object.subject 'Sets the subject grab string to the subject of the message\item
End If
person htd    schedule 27.04.2013

person    schedule
comment
Пожалуйста, добавьте объяснение к вашему коду. - person nalply; 11.10.2012