В процессе разработки механизмов оповещения часто возникает задача сгруппировать данные из общей таблицы (например, графика отпусков) и отправить руководителю подразделения одно информативное письмо вместо десятка отдельных сообщений по каждому сотруднику. Разберем, как правильно организовать этот процесс, исправить типичные ошибки в циклах и оформить письмо в виде наглядной HTML-таблицы.
Проанализируем ситуацию, представленную в вопросе. Основная ошибка кроется в логике обхода таблицы значений ТЗ1. В исходном коде процедура отправки почты вызывается на каждой итерации цикла по сотрудникам. Это приводит к тому, что система создает новое почтовое сообщение для каждого найденного вхождения, даже если руководитель один и тот же.
Вторая критическая ошибка находится внутри самой процедуры формирования текста. Посмотрим на этот фрагмент:
Для Каждого Строка ИЗ мОтобранныеСтроки Цикл;
ТелоТекста = Строка.Сотрудник + " - запланирован отпуск с " + ...
КонецЦикла;
Здесь переменная ТелоТекста на каждом шаге цикла полностью заменяется новым значением. В итоге, даже если в массив попало несколько сотрудников, в письмо попадет только информация о последнем из них. Выясним, как это исправить.
Первым делом нам необходимо обеспечить накопление строк текста. Для этого переменную нужно инициализировать пустой строкой до начала цикла, а внутри цикла использовать оператор конкатенации (сложения строк). Рассмотрим пример исправления логики:
ТелоТекста = "";
Для Каждого Строка ИЗ мОтобранныеСтроки Цикл
// Накапливаем строки, добавляя перевод строки в конце каждой записи
ТелоТекста = ТелоТекста + Строка.Сотрудник + " - запланирован отпуск с "
+ Формат(Строка.ДатаНачала, "ДФ=dd.MM.yyyy") + " по "
+ Формат(Строка.ДатаОкончания, "ДФ=dd.MM.yyyy") + Символы.ВК;
КонецЦикла;
Однако этого недостаточно для решения проблемы множественных писем. Чтобы руководитель получал одно письмо, нам нужно сначала подготовить уникальный список подразделений (или руководителей), и только затем для каждого из них собирать данные. Проанализируем правильный алгоритм обхода:
ТЗ1 и свернем ее по колонке ТекущееПодразделение, чтобы получить список уникальных отделов.Текстовые письма выглядят сухо и трудночитаемы при большом количестве данных. Гораздо профессиональнее формировать тело письма в формате HTML. Это позволит нам создать красивую таблицу с границами и заголовками. Разберем по шагам, как сформировать такой текст.
Сначала подготовим "шапку" письма и начало таблицы:
ТекстПисьма = "<html><body>";
ТекстПисьма = ТекстПисьма + "<p>Здравствуйте! Скоро начинается отпуск у сотрудников вашего подразделения:</p>";
ТекстПисьма = ТекстПисьма + "<table border='1' cellpadding='5' style='border-collapse: collapse;'>";
ТекстПисьма = ТекстПисьма + "<tr bgcolor='#f2f2f2'><th>ФИО</th><th>Дата начала</th><th>Дата окончания</th></tr>";
Затем пройдемся циклом по строкам и добавим данные в ячейки таблицы <td>:
Для каждого Строка Из мОтобранныеСтроки Цикл
ТекстПисьма = ТекстПисьма + "<tr>";
ТекстПисьма = ТекстПисьма + "<td>" + Строка.Сотрудник + "</td>";
ТекстПисьма = ТекстПисьма + "<td align='center'>" + Формат(Строка.ДатаНачала, "ДФ=dd.MM.yyyy") + "</td>";
ТекстПисьма = ТекстПисьма + "<td align='center'>" + Формат(Строка.ДатаОкончания, "ДФ=dd.MM.yyyy") + "</td>";
ТекстПисьма = ТекстПисьма + "</tr>";
КонецЦикла;
В завершение закроем теги таблицы и документа, после чего установим тип текста письма:
ТекстПисьма = ТекстПисьма + "</table>";
ТекстПисьма = ТекстПисьма + "<p>Просим проконтролировать передачу заявлений.</p></body></html>";
// При отправке обязательно указываем тип текста
ПараметрыПисьма.Вставить("Тело", ТекстПисьма);
ПараметрыПисьма.Вставить("ТипТекста", ТипТекстаПочтовогоСообщения.HTML);
Если в вашей компании работают тысячи сотрудников, поиск по таблице значений в цикле может работать медленно. Рассмотрим, как ускорить этот процесс. Перед началом массовой рассылки рекомендуется добавить индекс к таблице по ключевому полю поиска:
ТЗ2.Индексы.Добавить("ТекущееПодразделение");
Это значительно ускорит выполнение метода НайтиСтроки(). Также, вместо создания структуры отбора на каждой итерации, эффективнее использовать один объект структуры, просто меняя в нем значение свойства.
Для того чтобы сделать механизм рассылки надежным, стоит рассмотреть следующие дополнения:
РегламентныеЗадания, чтобы система сама проверяла график отпусков, например, каждый понедельник в 9:00.РаботаСПочтовымиСообщениями. Это позволит избежать низкоуровневой настройки ИнтернетПочтовыйПрофиль и обеспечит ведение журнала отправок.Попытка...Исключение. Это гарантирует, что если у одного руководителя указан неверный e-mail, рассылка не прервется и остальные адресаты получат свои уведомления.Таким образом, мы проанализировали основные ошибки при формировании рассылок и разобрали два способа решения задачи: от простого накопления текста до создания полноценных HTML-отчетов. Использование таблиц делает информацию наглядной, а правильная группировка данных снижает нагрузку на почтовые серверы и не раздражает руководителей лишними письмами.