Отправка писем из Outlook по расписанию


Краткое описание

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


Подробное описание

Представьте ситуацию. Например, вам нужно каждый вторник отправлять однотипные письма-напоминая вашим партнерам или коллегам по работе. Что-то вроде: "Уважаемые коллеги, напоминаем, срок сдачи договоров - пятница. Будьте пунктуальны, от этого зависит ваше вознаграждение".

К сожалению, в стандартном функционале Outlook данной возможности не предусмотрено. Максимум - отложенная отправка, но это совсем другое. С помощью указанного нами способа теперь это возможно. Всё, что необходимо: один раз создать шаблон, один раз настроить задачу в Outlook и теперь каждый вторник в заданное вами время будет происходить отправка нужного вам письма.

Установка макроса довольно-таки проста:

  1. Создайте задачу с именем "Рассылка писем".
  2. В параметрах задачи обязательно включите напоминание и задайте интервал повторений. Указанные дата и время напоминания - есть дата и время отправки писем.
  3. Создайте в Outlook папку с именем "Расписание". Все письма, которые требуется отправлять по графику размещайте в данной папке.
  4. Код скрипта из вложения выше разместите в модуле "ThisOutlookSession".
  5. В модуле VBA при необходимости создайте и добавьте персональный сертификат (на некоторых ПК возможна блокировка выполнения макросов без установленного сертификата). 

Также обратите внимание:

- При необходимости в настройках скрипта можно задать фильтр по теме письма.
- Если на момент отправки письма Outlook выключен, отправка будет возобновлена после включения программы.

Outlook вообще очень гибок в плане автоматизации в среде MS Office. Можно делать много интересных вещей. Была бы необходимость. Поэтому, не стесняйтесь, пишите, спрашивайте.

Вернуться к списку примеров

Комментарии (44)

  1. Евгений 09 января 2016, 22:54 # 0
    Спасибо. Как раз столкнулся с такой задачей, а тут уже всё разложено.
    1. Сергей 06 февраля 2017, 15:57 # 0
      Макрос скопировал, папку создал, письмо в ней есть, задача есть. Но почему-то задача не выполняется, а показывает простым напоминанием. Подскажите, где проблема?
      1. Maxim 13 февраля 2017, 23:34 # 0
        Могу предположить, что у вас отключены макросы в Outlook.
      2. Вячеслав 16 февраля 2017, 13:08 # 0
        Выбивает ошибку в

        Set OutFolder = GetNamespace(«MAPI»).Folders(CStr(Session.CurrentUser)).Folders(«Расписание»)
        1. Maxim 16 февраля 2017, 23:55 # 0
          Здравствуйте, Вячеслав.
          А папка «Расписание» у вас создана?
        2. Алексей 19 февраля 2017, 23:22 # 0
          Как сделать так, чтобы в папке Расписание не создавалась копия отправленного письма? Получается, что в следующий раз отправляется уже 2 одинаковых письма, а потом уже и 3. Приходится копии удалять вручную.
          В макросе есть строка Set NewItem = OutFolder.Items(i).Copy 'создаем копию письма
          Если её удалить, то при отправке из папки удаляется и оригинал письма, а если оставить эту строку, то появляется дубль письма.
          Как найти среднее решение, чтобы только 1 письмо находилось в папке?
          Спасибо.
          1. Maxim 21 февраля 2017, 01:21 # 0
            Set NewItem = OutFolder.Items(i).Copy       	'создаем копию письма
            Call NewItem.Send                            	'отправляем письмо
            По идеи, такого не должно быть, т.к. первая строка из указанного куска кода создает копию письма, а вторая строка отправляет созданную копию письма. Соответственно, если письмо отправляется, то оно из фактической папки отправления (в данном случае это папка Расписание) перемещается в папку Отправленные.
            И это успешно работало в Outlook 2007 (32 бит), ОС Windows 7 (32 бит).

            Возможно, у вас в Outlook настроено, не перемещать папку в Отправленные после отправления.
            Если нет, сообщите версию вашего офиса и ОС, проверю у себя на вашей конфигурации.
            1. Алексей 09 марта 2017, 01:40 # 0
              В настройках стоит «перемещать отправленные письма в определённую папку».
              Если даже поставить галочку напротив «перемещать письма в папку отправленные», то всё равно происходит то же самое. Остаётся дополнительная копия письма.
              Windows XP, Outlook 2010.
              Если есть может дополнительная надстройка или задача, чтобы удалять лишние копии и чтобы в папке было только одно письмо.
              Спасибо.
          2. Александр 21 февраля 2017, 07:20 # 0
            Здравствуйте. Все сделал как описано, но ни чего не происходит. Появляется на рабочем столе только напоминание. Макросы включены. Работаю через Outlook 2010
            1. Алексей 21 февраля 2017, 23:00 # 0
              Создана ли папка Расписание с письмом внутри и точно ли включены макросы?
              1. Александр 27 февраля 2017, 08:21 # 0
                Здравствуйте. Папка создана, письмо внутри. Центр управления безопасностью-параметры макросов -включить все макросы. Папка «расписание» создана в корне учётной записи. Все верно?
                1. Maxim 27 февраля 2017, 21:13 # 0
                  Да, всё именно так. Сообщите версию вашего офиса и ОС, проверю у себя на вашей конфигурации.
                  1. Александр 28 февраля 2017, 08:15 # 0
                    Офис 2010, винда 7 32-разрядная профессиональная, пк находится в корпоративной сети
                    1. Александр 28 февраля 2017, 09:35 # 0
                      Если навести курсор на на часть кода :Set OutFolder = GetNamespace(«MAPI»), то появляется надпись :OutFolder=nothing. Я так понимаю, что папка не найдена.
                      1. Maxim 28 февраля 2017, 14:37 # 0
                        Судя по сообщению, очень на то похоже. Именно поэтому я в первую очередь и предположил, что данной папки у вас нет.

                        Создайте в Outlook пустой модуль и поместите туда нижеуказанный код.
                        Далее запустите процедуру «SelectFolder».
                        После исполнения кода на рабочем столе появится файл «outlook_folder.txt», который будет содержать список папок в вашем Outlook.

                        Убедитесь:
                        1) что в указанном списке папок есть папка Расписание
                        2) папка Расписание находится в блоке вашей дефолтной учетной записи

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

                        Sub SelectFolder()
                            Dim oOutlook As New Application, oNamespace As NameSpace, oChildFolder As MAPIFolder
                            Set oNamespace = oOutlook.GetNamespace("MAPI")
                            'перебираем каждую папку верхнего уровня и получаем список ее подпапок через процедуру DoFolder'
                            For Each oChildFolder In oNamespace.Folders
                                InsertTXT vbCrLf & "-> " & oChildFolder.Name
                                DoFolder oChildFolder
                            Next
                        End Sub
                        
                        Sub DoFolder(ByVal oFolder As MAPIFolder)
                            Dim oChildFolder As Outlook.MAPIFolder
                            For Each oChildFolder In oFolder.Folders
                                InsertTXT oChildFolder.Name
                                DoFolder oChildFolder               'каждую дочернюю папку опять пропускаем через процедуру DoFolder'
                            Next
                        End Sub
                        
                        Function InsertTXT(ByVal txt As String) As Boolean
                            Dim FSO, TS, fName As String
                            fName = CreateObject("WScript.Shell").SpecialFolders("Desktop") & "\outlook_folder.txt"
                            On Error Resume Next: Err.Clear
                            Set FSO = CreateObject("scripting.filesystemobject")
                            Set TS = FSO.OpenTextFile(fName, 8, True): TS.Write txt & vbCrLf: TS.Close
                            Set TS = Nothing: Set FSO = Nothing
                            InsertTXT = Err = 0
                        End Function
                        
                        1. Maxim 03 марта 2017, 09:51(Комментарий был изменён) # 0
                          Кстати, проблема еще может быть из-за этой строки:
                          Set OutFolder = GetNamespace("MAPI").Folders(CStr(Session.CurrentUser)).Folders("Расписание")
                          В частности, из-за Session.CurrentUser, который отображает ФИО пользователя.
                          Если же у вас ящик именуется не в формате ФИО, а как есть (вроде login@domen.ru), то вышеуказанную строку надо заменить на:
                          Set OutFolder = GetNamespace("MAPI").Folders(CStr(Session.Accounts.Item(1))).Folders("Расписание")
                          Цифра 1 в данном случае — это порядковый номер вашего ящика. Если у вас их несколько, то цифра может быть другой.
              2. Андрей 02 марта 2017, 16:24 # 0
                Как сделать так, чтобы к письму прикреплялся ещё какой-нибудь файл?
                1. Maxim 03 марта 2017, 09:38 # 0
                  Если в самом простом виде, то добавить одну строку:
                  Set NewItem = OutFolder.Items(i).Copy           		'создаем копию письма
                  NewItem.Attachments.Add ("C:\Users\Admin\Desktop\test.txt")    	'новая строка: добавить вложение
                  Call NewItem.Send                                          	'отправляем письмо
                  Но это в самом простом виде, когда файл вложения у вас статичен и нет привязки к конкретному письму-шаблону.
                  Прочие условия несложно доработать. Например, вкладывать файл, ориентируясь по его дате создания или наименованию. Или делать вложение, исходя из названия письма или получателя. В общем, здесь уже исходя из задачи.
                2. Андрей 03 марта 2017, 10:44 # 0
                  Maxim, спасибо, всё получилось.
                  1. Алексей 12 марта 2017, 11:25 # 0
                    Maxim,
                    возвращаясь к сообщению excelstore.pro/examples-of-work/internet/sending-emails-from-outlook-on-a-schedule.html#comment-122
                    Может быть есть макрос для очистки папки от дублирующих писем?
                    Или надстройка какая-нибудь? Пока всё, что я находил, платное.
                    1. Maxim 13 марта 2017, 16:08 # 0
                      Такой макрос несложно написать. По какому признаку необходимо удалять дубликаты, по теме письма?
                      А вообще, странно что текущая версия макроса так работает на вашей конфигурации. Я пока еще не проверял, но на этой неделе обязательно проверю.
                      1. Алексей 13 марта 2017, 21:07 # 0
                        В папке 1 письмо с темой, которое отправляется каждый день.
                        Можно даже просто по количеству: если в папке более 1 письма, то лишние удалить.
                        Буду очень признателен за помощь!
                        1. Maxim 14 марта 2017, 00:13(Комментарий был изменён) # 0
                          Как и говорил, макрос простой.
                          Перебор писем осуществляется в папке «Расписание», которая должна располагаться в корне вашего ящика (не быть вложенной в другие папки).
                          Удаление сделал по количеству (удаляются все письма, кроме одного).

                          Sub DeleteMail()
                              Dim OutFolder As Folder, i As Integer, k As Integer
                              
                              'Set OutFolder = GetNamespace("MAPI").Folders(CStr(Session.Accounts.Item(1))).Folders("Расписание")
                              Set OutFolder = GetNamespace("MAPI").Folders(CStr(Session.CurrentUser)).Folders("Расписание")
                              k = OutFolder.Items.Count
                              
                              For i = k To 2 Step -1
                                  OutFolder.Items(i).Delete
                              Next i
                          End Sub
                          Код проверял на Windows 7 (64 bit), Office 2013 (64 bit). На прочих версиях не тестировал.

                          Если заругается на строку:
                          Set OutFolder = GetNamespace("MAPI").Folders(CStr(Session.CurrentUser)).Folders("Расписание")
                          то закоментируйте её и раскоментируйте вышестоящую:
                          Set OutFolder = GetNamespace("MAPI").Folders(CStr(Session.Accounts.Item(1))).Folders("Расписание")
                          1. Алексей 20 марта 2017, 12:47 # 0
                            Добрый день!
                            Макрос работает, спасибо большое!
                            А скажите, пожалуйста, как сделать так, чтобы он запускался раз в сутки?
                            Outlook открыт на рабочей станции 24 часа в сутки.
                            Письмо отправляется с утра и надо, чтобы потом в течение дня макрос удалял лишнюю копию. Можно это реализовать?
                            1. Maxim 20 марта 2017, 13:49 # 0
                              Добрый день.
                              Поставьте макрос на расписание. Например, так: excelstore.pro/examples-of-work/other/run-jobs-on-a-schedule-in-windows.html
                              А вообще, как я писал выше, надо редактировать исходный макрос, чтобы он удалял копию сразу после отправки письма. Поэтому раз у вас работает процедура DeleteMail, то попробуйте включить ее в основную процедуру — Application_Reminder. Это проще и правильнее.
                    2. Алексей 24 марта 2017, 06:48 # 0
                      Добрый день!
                      Потестировал скрипт для ежедневной рассылки писем в течение двух недель. Обнаружил проблему «выходного дня». Т.е. после выходных при включении почты (в понедельник) выполняется отправка письма по просроченному напоминанию от выходных (на выходных ПК выключен). Со вторника уже письма не отправляются. Подскажите, пж-та, как пофиксить данную проблему?
                      1. Maxim 01 апреля 2017, 11:06(Комментарий был изменён) # 0
                        Если в понедельник (после выходных) макрос отрабатывает, то, скорее всего, дело не в коде VBA.
                        Проверьте настройки вашей задачи в outlook. Возможно, именно в них кроется причина.
                        1. Алексей 04 апреля 2017, 13:33(Комментарий был изменён) # 0
                          Дело в том, что макрос отрабатывает в понедельник по субботнему напоминанию. Затем напоминание смещается на воскресенье. Но так как уже понедельник, то больше напоминание не возникает. У меня интерфейс Outlook на английском языке. Вот такие настройки в Task Recurrence: Recurrence pattern=«Daily, Every 1 day(s)», Start date =«03.03.2017 No end date». Также в задаче я установил Reminder на 04.03.2017. Тестировал уже несколько недель, пересоздавая задачи на новые даты. Результат одинаковый: с понедельника по пятницу макрос работает, в следующий понедельник последний раз срабатывает макрос и со вторника работа прекращается. Какие настройки задачи могут на это повлиять?
                          1. Maxim 04 апреля 2017, 16:14 # 0
                            Алексей, макрос не создает напоминаний (задач) и никак не влияет на их работу. Макрос только реагирует на сработавшее напоминание. Вся логика работы напоминаний (задач) исключительно на стороне самого Outlook.

                            Если Outlook ведет себя не так как ожидается, то возможно стоить использовать другой подход. Например:
                            1. не закрывать Outlook, чтобы напоминания не проскакивали;
                            2. доработать макрос, чтобы кроме отправки письма он также корректно смещал бы и дату напоминания;
                            3. использовать планировщик в Windows, который запустит выполнение нужного скрипта независимо от того, открыт Outlook или нет;
                            4. использовать веб-сервис, который по крону будет делать нужную рассылку без привязки к Outlook и Windows.
                      2. Алексей 09 апреля 2017, 15:15 # 0
                        Добрый день!
                        Продолжая тему excelstore.pro/examples-of-work/internet/sending-emails-from-outlook-on-a-schedule.html#comment-141
                        Помогите, пожалуйста, встроить код по удалению копии письма в основной код.
                        Пробовал много вариаций. Или вообще не работает или появляется s019.radikal.ru/i621/1704/7b/87a211797dec.png
                        Но ведь отдельно он работал, просто я где-то недопонимаю.

                        Спасибо!
                        1. Алексей 12 апреля 2017, 16:01 # 0
                          А вот недавно заметил, что эта ошибка появляется и при обычной отправке письма по расписанию. Просто до этого её закрывали до меня.
                          1. Maxim 06 мая 2017, 16:51 # 0
                            Я именно об этом и говорил выше.
                            Макрос не влияет на работу расписания. Логика работы расписания исключительно на стороне Outlook. Макрос только отлавливает нужные события и по ним уже выполняет какие-то действия. Но инициирует данные события именно Outlook.
                        2. Pasha 25 мая 2017, 09:08 # 0
                          Добрый день.
                          Есть у кого макрос на отправку писем за исключением выходных?
                          С указанием времени, мне нужно в рабочие дни отправить утром одно письмо и вечером одно и тоже.
                          Заранее спасибо.
                          1. Maxim 28 мая 2017, 20:21(Комментарий был изменён) # 0
                            Добрый день.
                            В виду проблем с выходными днями, описанных выше, альтернативным решением может быть:
                            1. Использовать планировщик windows, который в нужный интервал времени будет вызывать соответствующий макрос и производить отправку писем.
                            2. Использовать сторонние сервисы по отправке емаил. Т.е. на стороннем сервисе настраиваете отправку письма на ваш ящик в нужный интервал времени. Соответственно, когда данное письмо поступит в ваш outlook, сработает макрос, который в свою очередь запустит нужную вам рассылку.

                            Готового решения нет. Если вопрос актуален, могу написать за соответствующую плату. По вопросам заказа такого решения пишите на почту info@excelstore.pro
                          2. Михаил 08 июня 2017, 12:05 # 0
                            Максим, здравствуйте.
                            Работаю над подобной задачей, но не силен в VBA, да и времени разбираться нет. Если Вам не трудно, подскажите решение.
                            Из сторонней программы (1С), создается задача (напоминание) в Outlook. Как сделать так, что бы по времени этой задачи создавалось и отправлялось письмо.
                            Спасибо.
                            1. Maxim 08 июня 2017, 20:05 # 0
                              Добрый день, Михаил.
                              В макросе из данной статьи именно это и происходит: срабатывает напоминание, макрос его перехватывает и создает/отправляет письмо.
                              Что именно вызывает затруднение в текущем коде макроса?
                              1. Михаил 20 июня 2017, 11:45 # 0
                                Максим, здравствуйте
                                трудность в том, что задача создается программно, и каждый раз новая. соответственно, как я понимаю, и макрос должен каждый раз в нее вписываться заново. Письмо, которое нужно отправить, находиться в виде вложения, в этой задаче.
                                А как создать задачу с записанным в нее макросом я не понимаю. :))
                                Спасибо.
                                1. Maxim 20 июня 2017, 12:55(Комментарий был изменён) # 0
                                  Здравствуйте, Михаил.
                                  Понятно. Тогда макрос из данной темы, конечно, не подойдет.
                                  Но в вашем случае никакой макрос ни в какую задачу записывать не надо. Макрос будет находиться в Outlook-e и он всегда один и неизменен. Иными словами, нужен другой макрос или, как вариант, внешний скрипт, который будет проверять задачи и по нужному времени выдергивать из них вложение (письмо) и отправлять его.
                                  Могу реализовать вам нужный макрос на платной основе. Детали и стоимость разработки можем обсудить в личной переписке. Если актуально, напишите мне на info@excelstore.pro
                                  1. Денис 05 июля 2017, 12:28 # 0
                                    Здравствуйте. Подскажите пожалуйста.
                                    Изначально у меня ругался на с ФИО. Я заменил эту:
                                    Set OutFolder = GetNamespace(«MAPI»).Folders(CStr(Session.Accounts.Item(1))).Folders(«Расписание»)
                                    Но всё равно он ругается на эту же строку. Пишет следующее:
                                    Run-time error '-2147221233 (8004010f)':
                                    Сбой операции. Объект не найден.
                                    Прочитал весь этот форум и не нашёл нужного решения.
                                    1. Maxim 05 июля 2017, 19:52 # 0
                                      Здравствуйте. Папка «Расписание» у вас существует?
                                      1. Денис 06 июля 2017, 12:01 # 0
                                        Разобрался.
                                        Папка была создана в ветке «Файлы данных „Outlook“.
                                        Я перенёс её в ветку под свою почту и всё заработало.
                                        Осталось решить вопрос с дублированием сообщений в папке „Расписание“ и всё будет отлично.
                                        1. Денис 06 июля 2017, 12:23 # 0
                                          И сложность возникает ещё в том, что он делает копию письма, а потом уже отправляю и оригинал и копию. И эта лестница возрастает в геометрической прогрессии
                                          1. Maxim 06 июля 2017, 12:47(Комментарий был изменён) # 0
                                            Лично у меня проблемы с дублированием писем никогда не возникало.
                                            Создается копия письма, далее созданная копия отправляется. Оригинальное письмо остается на месте без изменения. Никаких дублей.
                                            Возможно, данная проблема возникает из-за отличий в версиях офиса или иных настройках Outlook. Проще будет, пожалуй, переписать макрос, чтобы в качестве исходного письма использовал не письмо в папке Outlook, а шаблон письма (.oft), сохраненный на ПК. На выходных напишу соответствующий макрос.
                                            1. Денис 06 июля 2017, 21:05 # 0
                                              Спасибо большое, это будет весьма полезным.
                                              Я пока решил проблему просто убрав цикл перебора. Но хотелось бы конечно посмотреть на то, как это выглядит в профессиональном виде.

                              Регистрация

                              На указанный email придёт письмо со ссылкой для активации.

                              Просто номер вашего сотового телефона.

                              Вы можете указать свой пароль, или оставить это поле пустым и тогда он будет сгенерирован автоматически.

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

                              Ваше имя, для отображения на сайте.