Разберем весьма распространенную ситуацию при разработке на платформе 1С:Предприятие 8.3 (например, в конфигурации 1С:ERP). Допустим, мы создали расширение конфигурации, добавили туда собственный справочник и теперь нам нужно перенести данные этого справочника в идентичную базу с помощью стандартной обработки «Выгрузка и загрузка данных XML». Однако при попытке сделать это с использованием запроса или отборов система выдает критическую ошибку.
Проанализируем ситуацию подробнее и выясним причину, по которой стандартные механизмы отказываются работать с объектами из расширений, а затем разберем по шагам, как правильно решить эту задачу.
При попытке выгрузить данные система прерывает работу со следующим сообщением об ошибке:
{ВнешняяОбработка.ВыгрузкаЗагрузкаДанныхXML.Форма.Форма.Форма(479)}: Ошибка при вызове метода контекста (РеквизитФормыВЗначение)
ОбъектНаСервере = РеквизитФормыВЗначение("Объект");
по причине:
Недопустимое значение параметра (параметр номер '1')
Здесь Объект — это основной реквизит формы обработки. Ошибка говорит о том, что платформа не может преобразовать реквизит формы в прикладной объект на сервере из-за несоответствия типов.
Рассмотрим подробнее архитектурные причины возникновения данной ошибки. Обработка «Выгрузка и загрузка данных XML» жестко завязана на метаданные основной конфигурации. Реквизит формы Объект в ней имеет составной тип данных, который формируется на этапе разработки самой обработки.
Когда мы добавляем новый справочник или документ через расширение конфигурации, стандартный контекст внешней обработки этот новый тип просто «не видит». Платформа ожидает объект определенного типа (из основной конфигурации), а получает неизвестный ей тип из расширения. Возникает конфликт.
Иногда программисты пытаются пойти обходным путем и программно устанавливают тип реквизита как ЛюбаяСсылка. Это действительно убирает ошибку метода РеквизитФормыВЗначение, но приводит к другой проблеме: ломаются механизмы фильтрации и подбора в самой обработке. Обработка теряет связь с конкретными объектами метаданных, и в результате выгружается 0 объектов.
Чтобы заставить обработку корректно воспринимать объекты из расширения, нам необходимо поместить ее в тот же контекст, где существуют эти объекты. Посмотрим на алгоритм действий:
Почему это работает? Как только обработка начинает выполняться в контексте расширения, в тип «Справочники» (и в составные типы обработки) автоматически добавляются типы из нашего расширения. Теперь при вызове метода преобразования платформа успешно распознает тип нашего нового справочника, и выгрузка отрабатывает корректно.
Даже если мы успешно выгрузили данные, запустив доработанную обработку из расширения, важно помнить о жестких ограничениях при загрузке. Рассмотрим их внимательно:
Обработка «Выгрузка и загрузка данных XML» изначально предназначена для обмена между абсолютно идентичными базами. Это означает, что в базе-приемнике должно быть выполнено следующее:
Если структура баз будет хоть немного отличаться, при чтении XML-файла база-приемник выдаст ошибку сериализации XDTO. Например, система может определить тип как базовый anyType, либо возникнет ошибка вида «Индекс выходит за границы диапазона».
Если структуры баз не идентичны на 100% или перенос типовой обработки в расширение вам не подходит по архитектурным соображениям, рассмотрим другие инструменты переноса данных:
.xlsx (Excel) или .csv. Это позволяет полностью миновать сложные и капризные механизмы сериализации XDTO.Также помните о сопутствующих ошибках при работе с расширениями. Иногда могут возникать исключения вида «Поле объекта недоступно для записи» или ошибки прав доступа к временным файлам на сервере, когда обработка пытается динамически сгенерировать схемы для новых объектов. При отладке подобных проблем всегда проверяйте, под какими правами выполняется код на сервере.