Как передать данные из табличной части в управляемой форме для отправки в HTML-письме?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке внешних обработок и документов на платформе 1С:Предприятие 8.3 (Управляемые формы) часто возникает задача отправки данных клиенту или контрагенту по электронной почте. Наиболее презентабельный вид имеют письма, тело которых оформлено в виде HTML-таблицы. Однако начинающие разработчики часто сталкиваются с трудностями при попытке передать данные из табличной части, расположенной на форме, в процедуру отправки почты. В этой статье мы подробно разберем, как правильно работать с контекстом управляемой формы, как извлечь данные табличной части и какими способами можно сформировать красивое HTML-письмо.

Понимание контекста: Клиент и Сервер в Управляемых Формах

Прежде чем переходить к написанию кода, давайте проанализируем архитектурную специфику управляемого приложения. Данные на форме представлены специальными типами данных платформы. Наша табличная часть на форме имеет тип ДанныеФормыКоллекция, а не привычная нам ТаблицаЗначений.

Важно помнить следующие правила:

  1. Интерактивные действия (нажатие на кнопку отправки) всегда начинаются на клиенте (директива выполнения &НаКлиенте).
  2. Отправка почты и любая сложная обработка данных должны выполняться исключительно на сервере (директива выполнения &НаСервере или &НаСервереБезКонтекста), так как системные механизмы работы с почтой (например, объект ИнтернетПочта) недоступны на стороне тонкого или веб-клиента.
  3. Для обращения к данным табличной части на сервере нет необходимости передавать их специальными параметрами. Они уже находятся в контексте формы и доступны через основной реквизит формы — Объект.

Рассмотрим подробнее, как получить доступ к строкам таблицы. Если на форме наша табличная часть называется Товары, то обратиться к ней в серверном контексте формы можно как Объект.Товары. Это коллекция, которую мы можем легко обойти в цикле.

Способ 1. Ручное формирование 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-сущности.

Способ 2. Преобразование табличной части в полноценную Таблицу Значений

Иногда над данными табличной части перед отправкой требуется произвести сложные манипуляции: сгруппировать строки по складам, отсортировать по алфавиту, свернуть дубли или сделать выборку по определенному условию. С объектом ДанныеФормыКоллекция такие операции проделать сложно, так как его функционал ограничен.

В этом случае лучшей практикой является преобразование коллекции формы в стандартную системную таблицу значений. Для этого используется встроенная функция платформы ДанныеФормыВЗначение.

Выясним, как это выглядит на практике:


&НаСервере
Процедура ОбработатьИОтправитьДанные()
    
    // Конвертируем данные формы в физическую Таблицу Значений
    ТаблицаДанных = ДанныеФормыВЗначение("Объект.Товары", Тип("ТаблицаЗначений"));
    
    // Теперь нам доступны все мощные методы работы с Таблицей Значений!
    // Например, отсортируем данные по возрастанию цены:
    ТаблицаДанных.Сортировать("Цена Возр");
    
    // Или свернем таблицу для получения уникальных позиций номенклатуры с подсчетом общего количества
    ТаблицаДанных.Свернуть("Номенклатура", "Количество, Сумма");
    
    // Передаем готовую ТЗ в функцию генерации HTML
    КодHTML = СформироватьHTMLИзТЗ(ТаблицаДанных);
    
    // Вызываем процедуру отправки письма
    ОтправитьЭлектронноеПисьмо(КодHTML);
    
КонецПроцедуры

Способ 3. Использование Табличного Документа для генерации HTML (Рекомендуемый)

Писать HTML-теги вручную в коде — трудоемкий процесс, который часто приводит к ошибкам отображения в разных почтовых клиентах (Outlook, Gmail, Яндекс.Почта). Существует элегантный и надежный способ: использовать ТабличныйДокумент 1С в качестве визуального конструктора, настроить его стили средствами платформы, а затем программно выгрузить в формат HTML.

Проанализируем этот метод по шагам:

  1. Создаем новый пустой ТабличныйДокумент на сервере.
  2. Выводим в него данные из табличной части или подготовленной таблицы значений (можно использовать программное построение или заранее созданный макет).
  3. Записываем документ во временный файл с типом ТипФайлаТабличногоДокумента.HTML.
  4. Считываем полученный файл в текстовую строку и удаляем временный файл с диска.

Рассмотрим пример программной реализации этого подхода:


&НаСервере
Функция Получить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), что идеально подходит для отображения в любых почтовых клиентах.

Способ 4. Использование Построителя Отчета для мгновенного вывода

Если табличная часть содержит большое количество колонок и строк, а заниматься ручным проектированием ячеек табличного документа нет времени, можно применить ПостроительОтчета. Этот объект позволяет в автоматическом режиме сформировать аккуратный табличный документ со стандартным оформлением платформы 1С всего в несколько строк кода.

Посмотрим на пример реализации:


&НаСервере
Функция СформироватьHTMLЧерезПостроитель(ТаблицаДанных)
    
    ТабДок = Новый ТабличныйДокумент;
    
    // Используем ПостроительОтчета для быстрого автоматического вывода ТЗ
    Построитель = Новый ПостроительОтчета;
    Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТаблицаДанных);
    Построитель.Вывести(ТабДок);
    
    // Записываем полученный документ в HTML
    ИмяФайла = ПолучитьИмяВременногоФайла("html");
    ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.HTML);
    
    ТекстовыйДок = Новый ТекстовыйДокумент;
    ТекстовыйДок.Прочитать(ИмяФайла, КодировкаТекста.UTF8);
    СтрокаHTML = ТекстовыйДок.ПолучитьТекст();
    
    УдалитьФайлы(ИмяФайла);
    
    Возврат СтрокаHTML;
    
КонецФункции

Финальный этап: Корректная отправка HTML-сообщения

После того как строка с HTML-кодом таблицы успешно сформирована одним из вышеописанных методов, нам необходимо передать ее почтовому серверу. При работе с объектом ИнтернетПочтовоеСообщение критически важно явно указать тип передаваемого текста. Если этого не сделать, получатель письма увидит «сырые» HTML-теги вместо красиво оформленной таблицы.

Рассмотрим пример процедуры отправки готового письма:


&НаСервере
Процедура ВыполнитьОтправкуПочты(ПолучательАдрес, ТемаПисьма, ТелоHTML)
    
    // Заполняем настройки подключения к почтовому серверу
    Профиль = Новый ИнтернетПочтовыйПрофиль;
    Профиль.АдресСервераSMTP = "smtp.mail.ru";
    Профиль.ПортSMTP = 465;
    Профиль.ИспользоватьSSLSMTP = Истина;
    Профиль.Пользователь = "sender@mail.ru";
    Профиль.Пароль = "ваш_пароль_приложения";
    
    // Создаем новое почтовое сообщение
    Письмо = Новый ИнтернетПочтовоеСообщение;
    Письмо.Отправитель.Адрес = "sender@mail.ru";
    Письмо.Отправитель.ОтображаемоеИмя = "Наша Компания";
    
    НовыйПолучатель = Письмо.Получатели.Добавить();
    НовыйПолучатель.Адрес = ПолучательАдрес;
    
    Письмо.Тема = ТемаПисьма;
    
    // Добавляем текст письма и ЯВНО задаем тип текста HTML
    ТекстСообщения = Письмо.Тексты.Добавить();
    ТекстСообщения.ТипТекста = ТипТекстаПочтовогоСообщения.HTML;
    ТекстСообщения.Текст = ТелоHTML;
    
    // Выполняем отправку
    Почта = Новый ИнтернетПочта;
    Попытка
        Почта.Подключиться(Профиль);
        Почта.Отправить(Письмо);
        Почта.Отключиться();
        ВызватьПользовательскоеПредупреждение("Письмо успешно отправлено!");
    Исключение
        ЗаписатьЛогОшибки(ОписаниеОшибки());
        ВызватьИсключение "Не удалось отправить сообщение. Обратитесь к администратору.";
    КонецПопытки;
    
КонецПроцедуры

Подведем итоги: Передача данных табличной части из формы для формирования HTML-письма — это стандартная задача, требующая четкого понимания клиент-серверного взаимодействия в 1С. Мы рассмотрели методы ручной сборки HTML-кода, использование универсального преобразования данных формы в таблицу значений с помощью функции ДанныеФормыВЗначение, а также наиболее технологичные методы автоматической генерации красивой верстки через ТабличныйДокумент и ПостроительОтчета. Выбирайте подход в зависимости от требований к дизайну вашего письма и сложности структуры отправляемых данных!

← На главную