При настройке и сопровождении интеграции решений на базе 1С с интернет-магазинами (CMS-системами) специалисты часто сталкиваются со сбоями в механизме интеграции. Одна из распространенных проблем в типовом обмене конфигурации «1С:Управление торговлей, редакция 11» — аварийное завершение процесса выгрузки с ошибкой преобразования типов метаданных.
В этой статье мы подробно разберем ситуацию, когда обмен каталогом товаров работает стабильно, но при активации обмена заказами система выдает критическую ошибку:
Ошибка отображения типов: Отображение типа 'СправочникСсылка.Пользователи' в тип...
Мы выясним причины возникновения этой неполадки, рассмотрим структуру XML-сериализации XDTO и пошагово разберем методы диагностики и исправления ошибки — как стандартными средствами настройки программы, так и с помощью программной корректировки кода.
---
Для интеграции с внешними сайтами в 1С используется стандарт обмена данными CommerceML. На техническом уровне этот процесс опирается на механизмы XDTO (XML Data Transfer Objects). XDTO-пакет описывает строгую схему данных: типы объектов, структуру их свойств и допустимые типы значений этих свойств.
В общем модуле ОбменССайтом при формировании файла выгрузки заказов выполняется процедура СформироватьЗаказыXDTO. Внутри этой процедуры программа обходит таблицу выгружаемых заказов и заполняет свойства XML-структуры:
ДокументXDTO.Номер = ТекСтрока.ЗаказНомерНаСайте;
Согласно схеме XML-пакета CommerceML, свойство Номер (идентификатор документа) должно иметь строковый тип (xs:string). Механизм сериализации 1С ожидает, что в переменной ТекСтрока.ЗаказНомерНаСайте находится обычное текстовое значение. Если вместо строки туда передается ссылка на элемент базы данных 1С (в нашем случае — СправочникСсылка.Пользователи), платформа не может выполнить неявное преобразование сложного ссылочного объекта в примитивный текстовый вид. В результате транзакция обмена прерывается с ошибкой отображения типов.
Рассмотрим детально две основные причины, почему в строковую переменную попадает ссылка на пользователя, и способы решения для каждой из них.
---
Типовой функционал «1С:Управление торговлей 11» связывает заказы на сайте и заказы в информационной базе 1С с помощью механизма Дополнительных реквизитов. В настройках узла обмена указывается, из какого именно реквизита документа «Заказ клиента» нужно считывать номер заказа на сайте.
Если тип этого реквизита настроен некорректно, либо в настройках узла обмена выбран не тот реквизит, возникнет описываемая ошибка. Выполним проверку этих параметров по шагам.
---
Если в вашей конфигурации ранее выполнялись доработки общего модуля ОбменССайтом (или логика обмена переопределена через механизм расширений), причина ошибки может крыться в самом тексте запроса, который собирает данные для выгрузки в таблицу ТаблицаДанныеЗаказов.
При изменении запроса разработчик мог случайно перепутать псевдонимы (alias) выбираемых полей. В результате этого в колонку ЗаказНомерНаСайте начали считываться данные из реквизитов Автор, Менеджер или Ответственный документа «Заказ клиента».
Рассмотрим пример ошибочного фрагмента запроса:
ВЫБРАТЬ
ЗаказКлиента.Ссылка КАК Ссылка,
ЗаказКлиента.Дата КАК Дата,
ЗаказКлиента.Автор КАК ЗаказНомерНаСайте, // ОШИБКА: Ссылка на справочник пользователей вместо строки!
ЗаказКлиента.СуммаДокумента КАК Сумма
ИЗ
Документ.ЗаказКлиента КАК ЗаказКлиента
Чтобы исправить этот код, нам нужно вернуть выборку правильного строкового значения. Если номер заказа действительно хранится в дополнительном реквизите, запрос должен обращаться к табличной части дополнительных реквизитов документа или использовать функции получения значений свойств:
ВЫБРАТЬ
ЗаказКлиента.Ссылка КАК Ссылка,
ЗаказКлиента.Дата КАК Дата,
ЕСТЬNULL(ДопРеквизиты.Значение, "") КАК ЗаказНомерНаСайте
ИЗ
Документ.ЗаказКлиента КАК ЗаказКлиента
ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказКлиента.ДополнительныеРеквизиты КАК ДопРеквизиты
ПО ДопРеквизиты.Ссылка = ЗаказКлиента.Ссылка
И ДопРеквизиты.Свойство = &СвойствоНомерНаСайте
---
Если визуальный анализ настроек и кода не дал результатов, мы можем локализовать сбойный документ с помощью встроенного отладчика 1С. Это позволит понять, в каком конкретно заказе содержатся некорректные данные.
ОбменССайтом.ДокументXDTO.Номер = ТекСтрока.ЗаказНомерНаСайте; (в зависимости от релиза УТ 11, это может быть область строки 5384).
ТекСтрока.ЗаказНомерНаСайте в табло (через контекстное меню или нажатием Shift + F9).ТекСтрока.Ссылка. Это позволит нам узнать ссылку на конкретный документ «Заказ клиента» в базе, у которого заполнены некорректные реквизиты. Мы сможем открыть этот заказ непосредственно в интерфейсе программы и очистить или исправить неверно заполненные поля.---
В некоторых случаях у администратора нет возможности мгновенно исправить исторически накопленные неверные данные в базе или перестроить структуру доп. реквизитов. Чтобы работа интеграции не блокировалась аварийными остановками, мы можем применить защитный код. Он будет преобразовывать любой переданный тип данных в строку в принудительном порядке.
Для этого мы можем внести изменения в общий модуль ОбменССайтом (или реализовать это через расширение конфигурации с помощью аннотации &Вместо или &Перед).
Проанализируем пример кода, который предотвратит падение системы при возникновении расхождений в типах данных:
// Проверяем заполненность значения перед выгрузкой в XDTO-пакет
Если ЗначениеЗаполнено(ТекСтрока.ЗаказНомерНаСайте) Тогда
// Проверим, не передана ли случайно ссылка на справочник Пользователи
Если ТипЗнч(ТекСтрока.ЗаказНомерНаСайте) = Тип("СправочникСсылка.Пользователи") Тогда
// Заменяем объектную ссылку на строковое представление наименования пользователя
ДокументXDTO.Номер = Строка(ТекСтрока.ЗаказНомерНаСайте.Наименование);
Иначе
// Для всех остальных типов применяем явное приведение к строке
ДокументXDTO.Номер = Строка(ТекСтрока.ЗаказНомерНаСайте);
КонецЕсли;
Иначе
// Если значение не заполнено, передаем пустую строку для соблюдения требований схемы XML
ДокументXDTO.Номер = "";
КонецЕсли;
Такой подход гарантирует, что даже при наличии ошибок заполнения документов в информационной базе обмен завершится успешно, а на сайт уйдет текстовое представление ошибочного реквизита вместо падения всей процедуры выгрузки пакета CommerceML.