При разработке внешних обработок и документов на платформе 1С:Предприятие 8.3 (Управляемые формы) часто возникает задача отправки данных клиенту или контрагенту по электронной почте. Наиболее презентабельный вид имеют письма, тело которых оформлено в виде HTML-таблицы. Однако начинающие разработчики часто сталкиваются с трудностями при попытке передать данные из табличной части, расположенной на форме, в процедуру отправки почты. В этой статье мы подробно разберем, как правильно работать с контекстом управляемой формы, как извлечь данные табличной части и какими способами можно сформировать красивое HTML-письмо.
Прежде чем переходить к написанию кода, давайте проанализируем архитектурную специфику управляемого приложения. Данные на форме представлены специальными типами данных платформы. Наша табличная часть на форме имеет тип ДанныеФормыКоллекция, а не привычная нам ТаблицаЗначений.
Важно помнить следующие правила:
&НаКлиенте).&НаСервере или &НаСервереБезКонтекста), так как системные механизмы работы с почтой (например, объект ИнтернетПочта) недоступны на стороне тонкого или веб-клиента.Объект.Рассмотрим подробнее, как получить доступ к строкам таблицы. Если на форме наша табличная часть называется Товары, то обратиться к ней в серверном контексте формы можно как Объект.Товары. Это коллекция, которую мы можем легко обойти в цикле.
Рассмотрим базовый сценарий, при котором мы вручную обходим каждую строку табличной части на сервере и склеиваем текстовую строку с HTML-тегами. Этот способ отлично подходит для простых таблиц с небольшим количеством колонок.
Разберем по шагам создание серверного обработчика:
&НаСервере
Функция СформироватьHTMLВручную()
// Получаем доступ к табличной части через Объект
ТабличнаяЧасть = Объект.Товары;
// Инициализируем начало HTML-документа и стили таблицы
КодHTML = "<html><body>";
КодHTML = КодHTML + "<h2>Данные вашей спецификации</h2>";
КодHTML = КодHTML + "<table border='1' style='border-collapse: collapse; width: 100%; font-family: Arial, sans-serif;'>";
// Формируем шапку таблицы
КодHTML = КодHTML + "<tr style='background-color: #f2f2f2; text-align: left;'>";
КодHTML = КодHTML + "<th style='padding: 8px;'>Номенклатура</th>";
КодHTML = КодHTML + "<th style='padding: 8px; text-align: right;'>Количество</th>";
КодHTML = КодHTML + "<th style='padding: 8px; text-align: right;'>Цена</th>";
КодHTML = КодHTML + "<th style='padding: 8px; text-align: right;'>Сумма</th>";
КодHTML = КодHTML + "</tr>";
// Обходим строки коллекции ДанныеФормыКоллекция
Для Каждого СтрокаТЧ Из ТабличнаяЧасть Цикл
КодHTML = КодHTML + "<tr>";
КодHTML = КодHTML + "<td style='padding: 8px;'>" + СтрокаТЧ.Номенклатура + "</td>";
КодHTML = КодHTML + "<td style='padding: 8px; text-align: right;'>" + СтрокаТЧ.Количество + "</td>";
КодHTML = КодHTML + "<td style='padding: 8px; text-align: right;'>" + СтрокаТЧ.Цена + "</td>";
КодHTML = КодHTML + "<td style='padding: 8px; text-align: right;'>" + СтрокаТЧ.Сумма + "</td>";
КодHTML = КодHTML + "</tr>";
КонецЦикла;
КодHTML = КодHTML + "</table>";
КодHTML = КодHTML + "</body></html>";
Возврат КодHTML;
КонецФункции
Важное примечание: При формировании HTML вручную помните о безопасности данных. Если текстовые поля вашей табличной части могут содержать спецсимволы (например, "<", ">", "&"), они могут нарушить верстку письма. Рекомендуется обрабатывать такие строки, заменяя опасные символы на их HTML-сущности.
Иногда над данными табличной части перед отправкой требуется произвести сложные манипуляции: сгруппировать строки по складам, отсортировать по алфавиту, свернуть дубли или сделать выборку по определенному условию. С объектом ДанныеФормыКоллекция такие операции проделать сложно, так как его функционал ограничен.
В этом случае лучшей практикой является преобразование коллекции формы в стандартную системную таблицу значений. Для этого используется встроенная функция платформы ДанныеФормыВЗначение.
Выясним, как это выглядит на практике:
&НаСервере
Процедура ОбработатьИОтправитьДанные()
// Конвертируем данные формы в физическую Таблицу Значений
ТаблицаДанных = ДанныеФормыВЗначение("Объект.Товары", Тип("ТаблицаЗначений"));
// Теперь нам доступны все мощные методы работы с Таблицей Значений!
// Например, отсортируем данные по возрастанию цены:
ТаблицаДанных.Сортировать("Цена Возр");
// Или свернем таблицу для получения уникальных позиций номенклатуры с подсчетом общего количества
ТаблицаДанных.Свернуть("Номенклатура", "Количество, Сумма");
// Передаем готовую ТЗ в функцию генерации HTML
КодHTML = СформироватьHTMLИзТЗ(ТаблицаДанных);
// Вызываем процедуру отправки письма
ОтправитьЭлектронноеПисьмо(КодHTML);
КонецПроцедуры
Писать HTML-теги вручную в коде — трудоемкий процесс, который часто приводит к ошибкам отображения в разных почтовых клиентах (Outlook, Gmail, Яндекс.Почта). Существует элегантный и надежный способ: использовать ТабличныйДокумент 1С в качестве визуального конструктора, настроить его стили средствами платформы, а затем программно выгрузить в формат HTML.
Проанализируем этот метод по шагам:
ТабличныйДокумент на сервере.ТипФайлаТабличногоДокумента.HTML.Рассмотрим пример программной реализации этого подхода:
&НаСервере
Функция ПолучитьHTMLЧерезТабличныйДокумент(ТаблицаДанных)
ТабДок = Новый ТабличныйДокумент;
// Создаем заголовки колонок программно
ТабДок.Область("R1C1").Текст = "Товар";
ТабДок.Область("R1C2").Текст = "Кол-во";
ТабДок.Область("R1C3").Текст = "Цена";
// Оформляем шапку: делаем шрифт жирным и задаем серый фон
ОбластьШапки = ТабДок.Область("R1C1:R1C3");
ОбластьШапки.Шрифт = Новый Шрифт(ОбластьШапки.Шрифт, , , Истина);
ОбластьШапки.ЦветФона = Новый Цвет(230, 230, 230);
ОбластьШапки.ГраницаСнизу = Новый Линия(ТипЛинииСеткиТабличногоДокумента.Сплошная, 1);
НомерСтроки = 2;
Для Каждого СтрокаТЗ Из ТаблицаДанных Цикл
ТабДок.Область("R" + НомерСтроки + "C1").Текст = СтрокаТЗ.Номенклатура;
ТабДок.Область("R" + НомерСтроки + "C2").Текст = СтрокаТЗ.Количество;
ТабДок.Область("R" + НомерСтроки + "C3").Текст = СтрокаТЗ.Цена;
// Настраиваем выравнивание чисел по правому краю
ТабДок.Область("R" + НомерСтроки + "C2").ГоризонтальноеПоложение = ГоризонтальноеПоложение.Право;
ТабДок.Область("R" + НомерСтроки + "C3").ГоризонтальноеПоложение = ГоризонтальноеПоложение.Право;
НомерСтроки = НомерСтроки + 1;
КонецЦикла;
// Получаем имя для временного файла на сервере
ИмяФайла = ПолучитьИмяВременногоФайла("html");
// Конвертируем табличный документ в HTML-файл
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.HTML);
// Читаем содержимое сгенерированного HTML-файла в строку
ТекстовыйДок = Новый ТекстовыйДокумент;
ТекстовыйДок.Прочитать(ИмяФайла, КодировкаТекста.UTF8);
СтрокаHTML = ТекстовыйДок.ПолучитьТекст();
// Обязательно удаляем временный файл после чтения
Попытка
УдалитьФайлы(ИмяФайла);
Исключение
// Логируем ошибку при необходимости, но не прерываем процесс
КонецПопытки;
Возврат СтрокаHTML;
КонецФункции
Этот способ гарантирует корректную верстку таблиц без необходимости вручную верстать CSS-стили тегов. Платформа самостоятельно преобразует границы, шрифты, цвета и выравнивание ячеек табличного документа в валидный HTML-код со встроенными стилями (Inlined CSS), что идеально подходит для отображения в любых почтовых клиентах.
Если табличная часть содержит большое количество колонок и строк, а заниматься ручным проектированием ячеек табличного документа нет времени, можно применить ПостроительОтчета. Этот объект позволяет в автоматическом режиме сформировать аккуратный табличный документ со стандартным оформлением платформы 1С всего в несколько строк кода.
Посмотрим на пример реализации:
&НаСервере
Функция СформироватьHTMLЧерезПостроитель(ТаблицаДанных)
ТабДок = Новый ТабличныйДокумент;
// Используем ПостроительОтчета для быстрого автоматического вывода ТЗ
Построитель = Новый ПостроительОтчета;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТаблицаДанных);
Построитель.Вывести(ТабДок);
// Записываем полученный документ в HTML
ИмяФайла = ПолучитьИмяВременногоФайла("html");
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.HTML);
ТекстовыйДок = Новый ТекстовыйДокумент;
ТекстовыйДок.Прочитать(ИмяФайла, КодировкаТекста.UTF8);
СтрокаHTML = ТекстовыйДок.ПолучитьТекст();
УдалитьФайлы(ИмяФайла);
Возврат СтрокаHTML;
КонецФункции
После того как строка с HTML-кодом таблицы успешно сформирована одним из вышеописанных методов, нам необходимо передать ее почтовому серверу. При работе с объектом ИнтернетПочтовоеСообщение критически важно явно указать тип передаваемого текста. Если этого не сделать, получатель письма увидит «сырые» HTML-теги вместо красиво оформленной таблицы.
Рассмотрим пример процедуры отправки готового письма:
&НаСервере
Процедура ВыполнитьОтправкуПочты(ПолучательАдрес, ТемаПисьма, ТелоHTML)
// Заполняем настройки подключения к почтовому серверу
Профиль = Новый ИнтернетПочтовыйПрофиль;
Профиль.АдресСервераSMTP = "smtp.mail.ru";
Профиль.ПортSMTP = 465;
Профиль.ИспользоватьSSLSMTP = Истина;
Профиль.Пользователь = "sender@mail.ru";
Профиль.Пароль = "ваш_пароль_приложения";
// Создаем новое почтовое сообщение
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Отправитель.Адрес = "sender@mail.ru";
Письмо.Отправитель.ОтображаемоеИмя = "Наша Компания";
НовыйПолучатель = Письмо.Получатели.Добавить();
НовыйПолучатель.Адрес = ПолучательАдрес;
Письмо.Тема = ТемаПисьма;
// Добавляем текст письма и ЯВНО задаем тип текста HTML
ТекстСообщения = Письмо.Тексты.Добавить();
ТекстСообщения.ТипТекста = ТипТекстаПочтовогоСообщения.HTML;
ТекстСообщения.Текст = ТелоHTML;
// Выполняем отправку
Почта = Новый ИнтернетПочта;
Попытка
Почта.Подключиться(Профиль);
Почта.Отправить(Письмо);
Почта.Отключиться();
ВызватьПользовательскоеПредупреждение("Письмо успешно отправлено!");
Исключение
ЗаписатьЛогОшибки(ОписаниеОшибки());
ВызватьИсключение "Не удалось отправить сообщение. Обратитесь к администратору.";
КонецПопытки;
КонецПроцедуры
Подведем итоги: Передача данных табличной части из формы для формирования HTML-письма — это стандартная задача, требующая четкого понимания клиент-серверного взаимодействия в 1С. Мы рассмотрели методы ручной сборки HTML-кода, использование универсального преобразования данных формы в таблицу значений с помощью функции ДанныеФормыВЗначение, а также наиболее технологичные методы автоматической генерации красивой верстки через ТабличныйДокумент и ПостроительОтчета. Выбирайте подход в зависимости от требований к дизайну вашего письма и сложности структуры отправляемых данных!