При работе с почтовыми объектами в управляемом приложении 1С:Предприятие 8.3 разработчики часто сталкиваются с ошибкой передачи данных между клиентом и сервером. Сообщение системы указывает на отсутствие отображения XDTO для типа ИнтернетПочтовыйПрофиль. Из-за этого возникает ошибочное представление, будто платформа не позволяет передать данные формы или требует обязательно переписать весь код с использования таблиц значений на массивы. В этой статье мы детально проанализируем причины этой проблемы и разберем правильные варианты архитектуры работы с электронными письмами.
Проанализируем текст ошибки, с которой сталкивается разработчик при вызове серверной функции:
Ошибка передачи данных между клиентом и сервером. Значение недопустимого типа. Ошибка преобразования данных XDTO... Отсутствует отображение для типа 'ИнтернетПочтовыйПрофиль'
Главная причина заключается в специфике работы управляемого приложения. Специализированные объекты платформы, такие как ИнтернетПочтовыйПрофиль, ИнтернетПочта и ИнтернетПочтовоеСообщение, не являются сериализуемыми. Это означает, что платформа 1С не может автоматически преобразовать их в формат XDTO для передачи через границу вызова с сервера на клиент или с клиента на сервер.
Если серверная функция возвращает сформированный объект ИнтернетПочтовыйПрофиль на клиент, вызов неизбежно завершается сбоем. Таблица значений в данном случае ни при чем — проблема заключается исключительно в попытке переместить несериализуемый объект между контекстами.
Разберем основной принцип: вся работа с объектами почты должна выполняться строго внутри одной серверной процедуре без возврата почтовых объектов на клиент. Параметры подключения следует передавать с клиента на сервер в виде обычной структуры с примитивными типами данных.
Рассмотрим пример правильного серверного модуля для получения писем и заполнения реквизита формы:
&НаСервере
Процедура ПолучитьПочтуНаСервере(СтруктураНастроек)
// Создаем профиль и заставляем его работать исключительно на сервере
Профиль = Новый ИнтернетПочтовыйПрофиль;
Профиль.АдресСервераВходящейПочты = СтруктураНастроек.Сервер;
Профиль.ПортВходящейПочты = СтруктураНастроек.Порт;
Профиль.Пользователь = СтруктураНастроек.Логин;
Профиль.Пароль = СтруктураНастроек.Пароль;
Почта = Новый ИнтернетПочта;
Попытка
Почта.Подключиться(Профиль);
Исключение
ЗафиксироватьОшибку(ОписаниеОшибки());
Возврат;
КонецПопытки;
Заголовки = Почта.ПолучитьЗаголовки();
Сообщения = Почта.Выбрать(Истина, Заголовки);
// Очищаем реквизит формы перед заполнением
Объект.ТаблицаПисем.Очистить();
Для Каждого Сообщение Из Сообщения Цикл
СтрокаТП = Объект.ТаблицаПисем.Добавить();
СтрокаТП.Дата = Сообщение.ДатаОтправления;
СтрокаТП.ОтКого = Сообщение.Отправитель.Пользователь + " <" + Сообщение.Отправитель.Адрес + ">";
СтрокаТП.Тема = Сообщение.Тема;
КомуВходящие = "";
Для Каждого Получатель Из Сообщение.Получатели Цикл
КомуВходящие = КомуВходящие + Получатель.Пользователь + " <" + Получатель.Адрес + "> ";
КонецЦикла;
СтрокаТП.Кому = КомуВходящие;
ТекстВходящие = "";
Для Каждого ТекстСообщения Из Сообщение.Тексты Цикл
ТекстВходящие = ТекстВходящие + ТекстСообщения.Текст;
КонецЦикла;
СтрокаТП.Текст = ТекстВходящие;
КонецЦикла;
Почта.Отключиться();
КонецПроцедуры
В управляемых формах реквизиты с типом ТаблицаЗначений на самом деле представлены объектом типа ДанныеФормыКоллекция. Преобразовывать данные в массивы или структуры для отображения на форме не требуется.
Существует два основных способа работы с таблицами в контексте управляемой формы:
Добавить() у элемента коллекции реквизита формы (например, Объект.ТаблицаПисем.Добавить()). Это самый простой и быстродействующий способ.ТаблицаЗначений (сортировка, поиск, группировка), таблица создается в памяти на сервере, а затем переносится в реквизит формы с помощью штатного метода:
// Перенос ТаблицыЗначений в реквизит формы
ЗначениеВРеквизитФормы(ТаблицаНаСервере, "Объект.ТаблицаПисем");
// И наоборот, если требуется выгрузить данные формы в ТЗ:
ТаблицаНаСервере = РеквизитФормыВЗначение("Объект.ТаблицаПисем");
Если по условиям архитектуры необходимо передать табличные данные на клиент без привязки к реквизитам формы, можно упаковать таблицу в массив структур. Каждая строка таблицы становится отдельной структурой, где ключами выступают имена колонок.
Рассмотрим универсальную функцию для такого преобразования:
Функция ТаблицаЗначенийВМассив(ТаблицаЗначений) Экспорт
Массив = Новый Массив;
СтруктураСтрокой = "";
НужнаЗапятая = Ложь;
Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
Если НужнаЗапятая Тогда
СтруктураСтрокой = СтруктураСтрокой + ",";
КонецЕсли;
СтруктураСтрокой = СтруктураСтрокой + Колонка.Имя;
НужнаЗапятая = Истина;
КонецЦикла;
Для Каждого Строка Из ТаблицаЗначений Цикл
НоваяСтрока = Новый Структура(СтруктураСтрокой);
ЗаполнитьЗначенияСвойств(НоваяСтрока, Строка);
Массив.Добавить(НоваяСтрока);
КонецЦикла;
Возврат Массив;
КонецФункции
Чтобы избежать ошибок при выгрузке и обработке электронной почты в управляемых формах 1С, соблюдаем следующие правила:
1. Объекты ИнтернетПочтовыйПрофиль и ИнтернетПочта создаются, используются и уничтожаются строго в рамках одной серверной процедуры.
2. С клиента на сервер передаются только простые параметры соединения (логин, пароль, имя сервера) через объект Структура.
3. Вывод списка писем выполняется прямо в реквизит формы (типа ДанныеФормыКоллекция) или через применение функции ЗначениеВРеквизитФормы().