Я дал вам много читать и делать.Пройдите все это медленно и при необходимости вернитесь с вопросами.
Ваши комментарии говорят о том, что у вас очень ограниченные знания Outlook VBA, поэтому я собираюсь начать с краткого введения.Я прошу прощения, если ваши знания лучше, чем я подозреваю, но я бы скорее оскорбил ваши знания, которые оставят вас в замешательстве из-за моего кода.
Краткое введение в Outlook VBA
NativeVBA - довольно ограниченный язык.Он поставляется с рядом операторов и некоторыми стандартными функциями, но большая часть его возможностей исходит от библиотек.Откройте редактор VBA, нажмите Инструменты, а затем Ссылки, и вам будет показан длинный список библиотек.Некоторые в верхней части списка уже будут отмечены.Вы можете прокрутить список вниз и отметить других, если вам нужна функциональность, которую они предоставляют.Это «Библиотека объектов Microsoft Outlook nn.n», которая сообщает компилятору о папках, почтовых элементах и задачах.Это «Библиотека объектов Microsoft Excel nn.n», которая сообщает компилятору о рабочих книгах, рабочих листах и диапазонах.(Обратите внимание, что nn.n зависит от используемой версии Office.) Поэтому для программирования в Outlook VBA необходимо знать VBA (то же самое для Excel, Word и PowerPoint) и объектную модель Outlook.
Outlook хранит все ваши электронные письма, элементы календаря, задачи и т. Д. В файлах, которые он называет , сохраняет .Вы можете увидеть эти файлы, называемые «PST-файлами», потому что большинство из них имеют расширение «PST».Тем не менее, файл Outlook с расширением «OST» также является хранилищем.Вы можете увидеть их как «Учетные записи», потому что по умолчанию в Outlook есть один магазин на одну учетную запись электронной почты.Тем не менее, вы можете иметь магазины, которые не связаны с учетной записью;например, в моей установке есть хранилище с именем «Архив» и другое с именем «Файл данных Outlook», ни одно из которых не является учетной записью.
Если вы посмотрите на панель папок, которая, вероятно, находится в левой части Outlook.В этом окне вы можете увидеть что-то вроде:
DoeJA@Gmail.com
: : : :
Inbox
: : : :
Sent Items
: : : :
JohnDoe@HotMail.com
: : : :
Inbox
: : : :
Sent Items
: : : :
Outlook Data File
: : : :
Inbox
: : : :
Sent Items
: : : :
«DoeJA@Gmail.com», «JohnDoe@HotMail.com» и «Файл данных Outlook» - это названия магазинов.Имена файлов, вероятно, «DoeJA@Gmail.com.OST», «JohnDoe@HotMail.com.PST» и «Файл данных Outlook.PST».Тем не менее, программист VBA не интересуется именами файлов;имена, которые отображаются на панели папок, - это имена, которые имеют значение.
Раздражающая особенность VBA состоит в том, что обычно существует несколько способов достижения одного и того же эффекта.Рассмотрим:
Option Explicit
Sub DsplSingleEmail1()
Dim NS As NameSpace
Dim FldrSrc As Folder
Set NS = Application.GetNamespace("MAPI")
Set FldrSrc = NS.Folders("DoeJA@Gmail.com").Folders("Inbox")
With FldrSrc.Items(1)
Debug.Print .ReceivedTime & " " & .Subject
End With
End Sub
Sub DsplSingleEmail 2()
Dim FldrSrc As Folder
Set FldrSrc = Session.Folders("DoeJA@Gmail.com").Folders("Inbox")
With FldrSrc.Items(1)
Debug.Print .ReceivedTime & " " & .Subject
End With
End Sub
Sub DsplSingleEmail 3()
Dim FldrSrc As Folder
Set FldrSrc = CreateObject("Outlook.Application"). _
GetNamespace("MAPI").GetDefaultFolder(olFolderInbox)
With FldrSrc.Items(1)
Debug.Print .ReceivedTime & " " & .Subject
End With
End Sub
Все три макроса: вывод даты и времени получения, а также тема самого старого письма в папке «Входящие».Если вы хотите попробовать их в своей системе, вам придется заменить «DoeJA@Gmail.com» на имя магазина в вашей системе, в котором есть активный почтовый ящик.
В макросе DsplSingleEmail1
, яиспользовали метод GetNamespace
.В макросе DsplSingleEmail2
я использовал метод Session
.В документации говорится, что эти два подхода эквивалентны, но я не нашел объяснения, почему существуют два эквивалентных метода.Это не имеет значения, если вы пишете свой собственный код;выбрать тот подход, который вы предпочитаете.Но если вы намерены искать фрагменты кода в сети, вы должны быть готовы к программисту A, использующему один подход, и программисту B, использующему другой.Когда вы объединяете фрагменты, которые используют разные подходы, вам нужно будет понять все подходы достаточно хорошо, чтобы настроить код для использования вашего любимого.
Оба GetNamespace
и Session
являются методами Application
.В одном макросе я сказал компилятору об этом, а в другом я оставил компилятор, чтобы решить это для себя.
В макросе DsplSingleEmail3
я использовал метод Namespace
, но у меня есть stобъяснил мое заявление с CreateObject("Outlook.Application")
.Это было бы необходимо, если бы я запускал этот код из Excel, но в этом нет необходимости, потому что я уже в Outlook.Я также использовал метод GetDefaultFolder
с параметром olFolderInbox
.Outlook по умолчанию имеет все свои стандартные папки в хранилище «Файл данных Outlook».Но в моей системе мастер установки организовал импорт моих писем в два других магазина.Без сомнения, где-то есть функциональность для изменения значений по умолчанию, но я никогда не удосужился посмотреть, потому что я не знаю, какой почтовый ящик магазина я бы сделал по умолчанию.Единственная причина, по которой DsplSingleEmail3
работает в моей системе, заключается в том, что я скопировал несколько нежелательных писем в папку «Входящие» в «Outlook Data File».Я включаю Debug.Print FldrSrc.Parent.Name
, потому что он выводит имя хранилища, содержащего папку «Входящие» по умолчанию.
Цель вышеизложенного состоит в том, чтобы продемонстрировать некоторые проблемы с поиском фрагментов кода, не имеющих фона для понимания контекста.Похоже, автор найденного вами фрагмента предполагает, что читатели поймут, как его использовать.Я изучил Excel VBA из книги.Я посетил большую библиотеку и позаимствовал все свои учебники по Excel VBA.Дома я попробовал их все, а затем купил тот, который соответствовал моему стилю обучения.Я изучил Outlook VBA экспериментально, так как не смог найти хороший учебник для Outlook VBA.Я сомневаюсь, что возможно изучить или Excel или Outlook VBA, ища полезные части кода онлайн.Если вы хотите написать макросы, чтобы помочь вашему работодателю, вы должны немного облегчить свою обычную рабочую нагрузку, чтобы у вас было время для изучения VBA и объектной модели Outlook.Это облегчение быстро возместит ваш работодатель, потому что вы сможете писать макросы, которые экономят часы ваших коллег и вас самих.
Решение ваших требований
Я считаю, чтоНаписание макросов для обработки электронных писем делится на две части.Часть 1 решает, как лучше выбрать электронные письма для обработки.Часть 2 решает, как достичь желаемого эффекта, обрабатывая выбранные электронные письма.Я опишу четыре различных метода выбора электронных писем и покажу, как использовать каждый из этих методов.Однако я предоставлю только один макрос для обработки выбранных писем.Каждый из четырех методов выбора будет вызывать один и тот же макрос обработки.Это демонстрирует, что на самом деле есть две части, и покажет вам, как работают различные методы выбора, и решит, какой из них наиболее подходит для ваших текущих и будущих требований.
Мой макрос обработки немного сложнее, чем ваш.Ваш макрос разработан специально для работы с правилом.Мой макрос будет работать с выбором пользователя, сканированием папки, событием нового элемента и правилом.
Мое понимание ваших требований заключается в следующем: электронные письма от «test@noreplay.com» содержат вложения.Вложения должны быть сохранены в «C: \ Attachments», перезаписывая все предыдущие вложения с тем же DisplayName
.Обработанные электронные письма должны быть перемещены в папку «Тест» в папке «Входящие», которая получила электронное письмо.Вы использовали правило для перемещения электронных писем, но не знаете, как сохранить вложения, используя правило.
Первая часть моего макроса обработки похожа на вашу, хотя я внес несколько изменений.Поскольку макрос Outlook должен работать с папками Outlook, я зарезервирую слово «папка» для Outlook.Я использую «путь», когда мне нужно обратиться к папкам на диске.Я не пишу Outlook.MailItem
или Outlook.Attachment
, когда MailItem
или Attachment
подойдет.Вам понадобится префикс «Outlook», если компилятор не знает, какая библиотека определяет MailItem
и Attachment
;что здесь не применимо.Я не знаю, в каком магазине находится папка «Входящие», которую вы хотите проверить, поэтому я назвал ее «DoeJA@Gmail.com».Замените это имя названием вашего магазина.Я большой пользователь оператора With
и включил два.
Имейте в виду, что есть различныеразличные виды привязанности.Я никогда не видел некоторых типов, поэтому не знаю, имеют ли они DisplayName
, но вполне вероятно, что ваши электронные письма имеют только самый распространенный тип вложений.Если у вас возникла проблема с сохранением вложений, опишите проблему, и я предложу, как ее избежать.SaveAsFile
перезаписывает любой существующий файл с таким же именем без предупреждения.Это не проблема, поскольку это соответствует вашим требованиям.
Вы используете правило для перемещения электронного письма в нужную папку, но только один из моих макросов выбора использует правило, поэтому макрос обработки должен переместить электронное письмо, если это необходимо.Если электронное письмо уже находится в папке «Тест» в папке «Входящие», его не нужно перемещать.
У всех почтовых элементов есть папка, в которой они находятся как родительский.Папка находится либо в другой папке, либо в магазине.Содержащая папка или хранилище является родителем папки.У магазина нет родителя.В моем макросе обработки вы найдете:
With ItemCrnt
If .Parent.Name = "Test" And .Parent.Parent.Name = "Inbox" Then
' MailItem is already in destination folder
Else
.Move FldrDest
End If
End With
ItemCrnt.Parent.Name
- имя папки, содержащей почтовый элемент.Если почтовый элемент находится в необходимой папке, это имя будет «Тест».ItemCrnt.Parent.Parent.Name
- это имя папки, в которой находится почтовый элемент.Если почтовый элемент находится в необходимой папке, это имя будет «Входящие».Таким образом, этот код переместит почтовый элемент в папку назначения, если он еще не находится в папке назначения.Обратите внимание, как я могу связать свойства вместе с точками.Будьте осторожны с этой функцией.У магазина нет родителя, поэтому, если ItemCrnt
находится в папке «Test», ItemCrnt.Parent.Parent.Parent.Name
выдаст ошибку.
Первый макрос выбора, SelectEmailsUser
, требует, чтобы пользователь выбрал одно или несколько писем перед запуском макроса обработки.Я никогда не использовал этот подход в реальной установке, но считаю его бесценным во время разработки.При таком подходе я могу начать с одного письма, которое легко обрабатывать.Тестируя макрос обработки, я могу медленно вводить все более сложные электронные письма и несколько электронных писем за один прогон.Ни один другой подход не предоставляет такой контроль над последовательностью, в которой электронные письма представляются макросу.
Второй макрос выбора, SelectEmailsScan
, использует подход, который я использую чаще всего.При таком подходе я читаю папку вверх или вниз, проверяя свойства каждого письма и решая, какую из них я хочу обработать.
Вы хотите переместить обработанные электронные письма, что усложняет работу, если вы используете простой цикл For-Loop.Папка является примером коллекции.С коллекцией вы обычно получаете доступ к ее элементам по позициям: 1, 2, 3, 4 и так далее.Если вы перемещаете почтовый элемент 5 в другую папку, вы удаляете этот почтовый элемент из этой папки и добавляете его в другую.Когда вы удаляете почтовый элемент 5, почтовый элемент 6 становится почтовым элементом 5, почтовый элемент 7 становится почтовым элементом 6 и так далее.Если ваш цикл For-Loop теперь проверяет почтовый элемент 6, вы проверяете старый почтовый элемент 7 и игнорируете старый почтовый элемент 6. Существует несколько обходных путей, но проще всего проверить электронные письма в обратном порядке: 1000,999, 998 и так далее.Теперь, если вы удалите электронную почту 998, вы не возражаете, что электронные письма 1000 и 999 меняют положение, потому что вы уже изучили их.
Третий макрос выбора, InboxItems_ItemAdd
, использует событие нового элемента.Вы можете попросить Outlook запускать макрос каждый раз, когда что-то происходит.Мой код просит Outlook запустить макрос при добавлении нового электронного письма в папку «Входящие».Этот макрос вызывает мой макрос обработки, если электронное письмо было отправлено конкретным отправителем.Это соответствует вашему правилу, за исключением того, что мой макрос перемещает письмо в папку «Test» и сохраняет вложения.
Четвертый выборМетод предполагает связывание «сценария» с правилом.Это правило должно выбирать электронные письма, отправленные «test@noreplay.com».При желании это правило может перемещать выбранные письма в папку «Тест».Если этого не произойдет, мой макрос обработки переместит его.Параметр правила «Запустить скрипт», который сбивает с толку.Существует несколько языков сценариев, включая VBscript.«Сценарий» не может использовать ни один из этих языков сценариев;это должен быть макрос Outlook VBA.
Параметр правила «Запуск сценария» также сбивает с толку из-за противоречивой информации.Некоторые сайты говорят, что Microsoft отключила его и предоставляют сложные инструкции о том, как его отключить.Другие сайты не упоминают о такой проблеме.Параметр правила «Запустить скрипт» работает в моей системе, поэтому я могу только надеяться, что он работает в вашей системе.Если это не работает, вам придется выбрать один из других подходов.
Установка и тестирование
Я смоделировал вашу систему настолько, насколько смог.У меня есть два адреса электронной почты, которые я назову Address1 и Address2.Адрес1 - мой основной адрес, который известен моей семье, друзьям и выбранным поставщикам.Address2 - это тот, который я публикую открыто и от которого я откажусь, если его заберет слишком много мошенников.
Я создал папку Outlook «Тест» в «Входящие» на Адрес1.Я создал папку на диске «C: \ Attachments».Я отслеживаю электронную почту, приходящую на адрес1 с адреса2.Вам придется изменить названия моего магазина, но в противном случае мои макросы должны работать в вашей системе без изменений.
Пожалуйста, удалите существующее правило.Мне нужно, чтобы вы удалили свое правило, потому что (1) оно будет мешать методам выбора с 1 по 3 и (2) я не могу обнаружить, как добавить скрипт в существующее правило.Удалите существующий код, который вам не нужен.
На вашем изображении показано, что вы поместили свой код в Модуль 1.Когда вы начинаете новые проекты, вы можете добавить Module2, Module3 и так далее.Вскоре становится проблемой найти модуль, содержащий код, который вы хотите посмотреть сегодня.У вас открыто окно свойств.(F4 открывает окно свойств, если оно теперь закрыто.) Единственное свойство модуля - это его имя, которое вы можете изменить по умолчанию из ModuleNN.Я предлагаю вам переименовать «Module1» в «ModXxxxx», где «Xxxxx» - это имя, которое что-то для вас значит.«Мод» не важен, но я считаю его полезным.Если у вас есть макрос «Xxxxx» в модуле «Xxxxx», вы не можете получить доступ к этому макросу.Обозначая все мои модули с префиксом «Mod», я избегаю этой проблемы.
У Option Explicit
вверху каждого модуля.Посмотрите это утверждение, чтобы узнать о преимуществах, которые оно предлагает.Посмотрите любое утверждение в моем коде, которое вы не узнаетеПри необходимости возвращайтесь с вопросами, но чем больше вы сможете исследовать для себя, тем быстрее вы будете разрабатывать.
Если вы хотите попробовать макросы DsplSingleEmail1 в DsplSingleEmail3, вы можете скопировать и вставить этот ответ в свой модуль.Вам может понадобиться скопировать несколько нежелательных писем, чтобы сохранить «Файл данных Outlook», если вы хотите попробовать Experiment3.
Метод выбора 1
Скопируйте следующий код в свой модуль:
Public Sub SaveAttachAndMoveEmail(ByRef ItemCrnt As MailItem)
Dim Attach As Attachment
Dim FldrDest As Folder
Dim PathSave As String
PathSave = "C:\Attachments"
Set FldrDest = Session.Folders("Address1").Folders("Inbox").Folders("Test")
With ItemCrnt
For Each Attach In .Attachments
With Attach
.SaveAsFile PathSave & "\" & .DisplayName
End With
Next
If .Parent.Name = "Test" And .Parent.Parent.Name = "Inbox" Then
' MailItem is already in destination folder
Else
.Move FldrDest
End If
End With
End Sub
Sub SelectEmailsUser()
Dim Exp As Explorer
Dim ItemCrnt As MailItem
Set Exp = Outlook.Application.ActiveExplorer
If Exp.Selection.Count = 0 Then
Call MsgBox("Pleaase select one or more emails then try again", vbOKOnly)
Exit Sub
Else
For Each ItemCrnt In Exp.Selection
With ItemCrnt
Debug.Print .ReceivedTime & "|" & .Subject & "|" & .SenderEmailAddress
End With
Call SaveAttachAndMoveEmail(ItemCrnt)
Next
End If
End Sub
Macro SaveAttachAndMoveEmail
- это мой макрос обработки, который я объяснил выше.Замените «Address1» на имя магазина, содержащего папку «Входящие», которую вы хотите отслеживать.Макрос SelectEmailsUser
использует ActiveExplorer
для доступа к электронным письмам, выбранным пользователем.Макрос выводит несколько свойств каждого письма в Immediate Window.Чтобы протестировать макрос, я выбрал несколько писем с вложениями и без них, а также внутри и снаружи папки «Тест».Я предполагаю, что все ваши электронные письма в «Тест».Почему бы не переместить некоторые назад в папку «Входящие», затем выбрать и запустить макрос SelectEmailsUser
.
Метод выбора 2
Добавьте следующий код в ваш модуль:
Sub SelectEmailsScan()
Dim FldrSrc As Folder
Dim InxItemCrnt As Long
Set FldrSrc = Session.Folders("myemail@gmail.com").Folders("Inbox")
For InxItemCrnt = FldrSrc.Items.Count To 1 Step -1
With FldrSrc.Items.Item(InxItemCrnt)
If .Class = olMail Then
If .SenderEmailAddress = "myemail@gmail.com" Then
Call SaveAttachAndMoveEmail(FldrSrc.Items.Item(InxItemCrnt))
End If
End If
End With
Next
End Sub
Замените «Address1» на название магазина, содержащегоВходящие, которые вы хотите отслеживать.
Я проверил этот код (и более поздний код), отправив письма со своего второго аккаунта на мой адресрвые.Вы можете проверить этот код, переместив предыдущие электронные письма, отправленные «test@noreplay.com» из папки «Test» в папку «Inbox».Как я уже сказал, этот подход я использую чаще всего.Монитор Outlook для просмотра интересных электронных писем кажется более простым, но я нахожу контроль над возможностью запуска макроса, когда я хочу больше узнать о том, как я управляю своей жизнью.
Метод выбора 3
В редакторе VBA окно Project Explorer обычно находится внизу слева.Верхняя строка - «Объекты Microsoft Outlook».Если напротив этой строки есть «+», нажмите «+», чтобы развернуть «Объекты Microsoft Outlook».Следующая строка вниз - «ThisOutlookSession».Нажмите «ThisOutlookSession», чтобы выбрать его.Область кода становится пустой.Ранее вы видели код в вашем модуле.ThisOutlookSession - это еще одна область, в которой вы можете разместить код.Вы можете разместить любой код здесь, но я резервирую его для кода, который ДОЛЖЕН быть размещен здесь.Скопируйте следующий код в «ThisOutlookSession»:
Option Explicit
Private WithEvents InboxItems As Items
Private Sub Application_Startup()
Set InboxItems = Session.Folders("Address1").Folders("Inbox").Items
End Sub
Private Sub InboxItems_ItemAdd(ByVal ItemCrnt As Object)
With ItemCrnt
If .Class = olMail Then
If .SenderEmailAddress = "test@noreplay.com" Then
Call SaveAttachAndMoveEmail(ItemCrnt)
End If
End If
End With
End Sub
Private WithEvents InboxItems As Items
определяет объект InboxItems
.
Private Sub Application_Startup() … End Sub
указывает подпрограмму, которая должна запускаться при запуске Outlook.Наличие такой подпрограммы означает, что Outlook немедленно спросит, хотите ли вы включить макросы.Вы должны ответить «Да», если хотите отслеживать события.
Set InboxItems = Session.Folders("Address1").Folders("Inbox").Items
указывает, какую папку вы хотите отслеживать.Когда элемент добавляется в эту папку, выполняется подпрограмма Xxxxx_ItemAdd
.Xxxxx
- это имя объекта, который вы определили Private WithEvents …
.Вы можете отслеживать столько папок, сколько пожелаете, при условии, что вы указываете отдельный объект WithEvents
для каждой папки.
Код в макросе InboxItems_ItemAdd
проверяет, является ли элемент почтовым элементом и был отправлен «test @ noreplay».com».Если это правда, он вызывает мой макрос обработки.Вам нужно выйти из Outlook (не забывая сохранить «VbaProject.OTM»), а затем перезапустить его, чтобы активировать мониторинг папки «Входящие».
Если вы просматриваете папку «Входящие», когда приходит сообщение из «test @ noreplay».com », вы можете увидеть, что он появляется на короткое время, а затем исчезает при перемещении в папку« Test ».Я проверил мониторинг событий, отправив электронные письма со своего второго адреса электронной почты.Вам нужно будет дождаться получения писем с test@noreplay.com.
Метод выбора 4
Перед настройкой метода 4 необходимо отключить метод 3.Вы можете удалить код из «ThisOutlookSession», но я помещаю кавычки по левому краю, чтобы превратить все операторы в комментарии, чтобы они были доступны для справки в следующий раз, когда мне нужно будет следить за событием.Отключив метод 3, закройте Outlook и снова откройте его.
Вам нужно будет создать новое правило вместо того, которое я вам дал удалить.Правило, которое я создал, чтобы проверить этот подход, выбирало электронные письма с моего адреса2.Он не переместил эти электронные письма в «Test», потому что это делает мой макрос обработки.Мое правило включало запуск сценария, который у вас не выполнялся.Мои шаги по созданию этого правила были следующими:
- Переместить одно из целевых электронных писем из «Тест» в «Входящие».
- Выберите это целевое электронное письмо.
- Вкл.На вкладке «Главная» нажмите «Правила».
- Нажмите «Создать правило».Появится окно «Create Rule».
- Отметьте галочкой «From test@noreplay.com».
- Убедитесь, что больше ничего не отмечено.
- Нажмите «Advanced».Откроется окно «Мастер правил».
- Поставьте галочку «От test@noreplay.com», но больше ничего не отмечено.
- Нажмите «Далее».Появится другое окно «Мастер правил».
- Нажмите «Запустить сценарий», который находится внизу списка.
- Убедитесь, что больше ничего не отмечено.
- Нажмите «скрипт» в поле «Шаг 2» внизу.Если вы не сделали этого раньше в этом запуске Outlook, вам будет предложено включить макросы.Откроется окно «Выбор сценария».
- Выберите «Project1.SaveAttachAndMoveEmail» и нажмите «ОК».Примечание 1: имя макроса, вероятно, будет усечено.Примечание 2: этоВыбор, вероятно, уже выбран и является вашим единственным выбором.
- Нажмите «Далее».Появится другое окно «Мастер правил».
- Убедитесь, что ничего не отмечено.
- Нажмите «Далее».Появится последнее окно «Мастер правил».
- Введите другое имя для правила, если вам не нравится имя Outlook по умолчанию.
- Вы можете поставить галочку «Запускать это правило сейчас для сообщений, уже находящихся в папке« Входящие »», чтобы удалить перемещенное вами электронное письмо.из «Test».
- Нажмите «Finish».Если вы отметили «Запустить это правило для сообщений, уже находящихся в папке« Входящие »», вы увидите окно хода выполнения при выполнении правила.
Я не могу найти хорошую документацию по опции «Запустить сценарий».Мои эксперименты показывают, что макрос, указанный в окне «Выбор сценария», должен быть Public
и должен иметь список параметров, который соответствует правилам для таких макросов.Я читал, что такие макросы могут иметь четыре параметра.Первый параметр является обязательным, но остальные могут быть опущены.Первый параметр должен быть «ByRef itm As MailItem» или какой-либо разумный вариант.