При разработке или доработке внешних отчетов на управляемых формах разработчики нередко сталкиваются с ошибкой передачи данных между сервером и клиентом. Текст ошибки часто содержит упоминания XDTO, userSettings, additionalProperties или dataSource, из-за чего может сложиться ложное впечатление, что проблема кроется в формируемом объекте ТабличныйДокумент. Разберем механизм возникновения этой ошибки и выясним, как правильно организовать формирование отчета.
Проанализируем типовое проявление ошибки при вызове серверной функции формирования отчета из управляемой формы:
«Ошибка передачи данных между клиентом и сервером. Значение недопустимого типа. Ошибка преобразования данных XDTO: НачалоСвойства: userSettings... additionalProperties... dataSource...»
Посмотрим, что происходит в этот момент на уровне платформы:
&НаСервере) платформа выполняет полную сериализацию контекста всей управляемой формы в XML/XDTO-пакет для передачи обратно на клиент.ПользовательскиеНастройки или Настройки) сохраняются сугубо серверные объекты, не поддерживающие сериализацию XDTO, процесс упаковки данных завершается аварийно.В типовых отчетах или при ручном вызове метода СкомпоноватьРезультат() в коллекцию ДополнительныеСвойства могут программно помещаться такие объекты, как МакетКомпоновкиДанных, ПроцессорКомпоновкиДанных, МенеджерВременныхТаблиц или источники данных схемы. Поскольку они не предназначены для передачи на тонкий клиент, попытка вернуть управление из процедуры &НаСервере вызывает ошибку XDTO.
Если логика формирования отчета выполняется в контекстной процедуре формы &НаСервере, перед завершением серверного вызова необходимо принудительно очистить коллекции дополнительных свойств компоновщика настроек, в которые могли записаться серверные структуры.
Посмотрим на пример кода очистки свойств в обработчике компоновки:
&НаСервере
Функция СформироватьОтчетНаСервере()
ОтчетОбъект = РеквизитФормыВЗначение("Отчет");
ТабДок = Новый ТабличныйДокумент;
ОтчетОбъект.СкомпоноватьРезультат(ТабДок);
// Очищаем дополнительные свойства, содержащие несериализуемые серверные объекты
Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.ДополнительныеСвойства.Очистить();
Отчет.КомпоновщикНастроек.Настройки.ДополнительныеСвойства.Очистить();
Возврат ТабДок;
КонецФункции
Этот прием позволяет оставить форму в валидном состоянии, готовом к сериализации для тонкого клиента.
Наиболее надежный архитектурный подход — исключить передачу контекста всей формы туда и обратно. Для этого вынесем генерацию табличного документа в бесконтекстную процедуру или функцию, а передачу тяжелых данных организуем через временное хранилище.
Разберем реализацию этого метода по шагам:
&НаСервереБезКонтекста только сериализуемые параметры.Рассмотрим пример реализации:
&НаКлиенте
Процедура Сформировать(Команда)
АдресРезультата = "";
СформироватьОтчетБезКонтекста(Отчет.КомпоновщикНастроек.ПолучитьНастройки(), УникальныйИдентификатор, АдресРезультата);
ТабличныйДокументРезультат = ПолучитьИзВременногоХранилища(АдресРезультата);
КонецПроцедуры
&НаСервереБезКонтекста
Процедура СформироватьОтчетБезКонтекста(НастройкиСКД, УникальныйИдентификатор, АдресРезультата)
// Получаем схему компоновки и выполняем компоновку локально
ВнешнийОтчетОбъект = ВнешниеОтчеты.Создать(АдресВнешнегоОтчетаВоВременномХранилище);
ТабДок = Новый ТабличныйДокумент;
ВнешнийОтчетОбъект.СкомпоноватьРезультат(ТабДок);
АдресРезультата = ПоместитьВоВременноеХранилище(ТабДок, УникальныйИдентификатор);
КонецПроцедуры
Если программная компоновка реализуется вручную через КомпоновщикМакетаКомпоновкиДанных и ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент, важно следить за областью видимости создаваемых объектов.
Проанализируем правила работы с объектами компоновки:
МакетКомпоновкиДанных, ПроцессорКомпоновкиДанных и СхемаКомпоновкиДанных в реквизитах управляемой формы.ТабличныйДокумент не передавайте промежуточные служебные структуры в параметры расшифровки или пользовательские настройки.Соблюдение этих правил гарантирует отсутствие ошибок преобразования XDTO при работе отчетов в любых клиентских режимах 1С:Предприятия.