Как исправить ошибку «Несоответствие фасету MaxLength = 80» при обмене 1С с сайтом?

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Торговля и дистрибуция
← На главную

При настройке регулярной выгрузки товаров и свойств из 1С на сайт (например, под управлением CMS «1С-Битрикс») разработчики часто сталкиваются с непредвиденным прерыванием процесса обмена. Одной из наиболее коварных ошибок является сбой валидации XDTO-пакета из-за несоответствия ограничению длины строки. В этой статье мы подробно разберем, почему возникает ошибка «Несоответствие фасету MaxLength = '80'», проанализируем её причины и рассмотрим три практических способа решения проблемы с примерами кода.

Выясняем причину: почему падает обмен?

Давайте разберем архитектуру обмена данными. В основе большинства интеграций 1С с интернет-магазинами лежит стандарт CommerceML 2.x или 3.x. Передача информации происходит через XML-файлы, структура которых жестко регламентирована встроенными XML-схемами (XSD).

В этих схемах для каждого реквизита задается строгий тип данных с ограничениями (фасетами). В частности, для идентификаторов объектов часто используется глобальный тип Идентификатор80 или аналогичные ему типы со свойством maxLength = "80". Это означает, что любое значение, передаваемое в данный XML-атрибут, обязано быть длиной не более 80 символов.

В реальных базах данных (особенно в отраслевых конфигурациях, например, для ювелирной торговли, одежды или автозапчастей) идентификаторы свойств или характеристик могут формироваться динамически. Программа пытается транслитерировать длинное наименование свойства (например, состав камней в украшении: «10mm-nit-silikonovaya-pokrytaya-zhemchuzhnoj-ehmuls...») или собирает составной ключ из нескольких уникальных идентификаторов (GUID). Если длина итоговой строки превышает 80 символов, платформа 1С генерирует ошибку соответствия типов XDTO, и выгрузка полностью прекращается.

Ниже мы подробно рассмотрим три метода решения этой проблемы, начиная с простых «быстрых» правок кода и заканчивая надежными архитектурными подходами.


Способ 1. Программное ограничение длины строки (функция Лев)

Самый простой и очевидный способ обойти ошибку — принудительно обрезать передаваемую в XML-атрибут строку до разрешенных 80 (или чуть меньше) символов непосредственно перед формированием XDTO-объекта.

Рассмотрим ситуацию на примере общего модуля Б_ОбменССайтомСервер. Посмотрим на строку кода, которая вызывает падение системы:


XDTOСправочник.ИдЗначения = XMLСтрока(ВыборкаЗначенийСвойств.ПереченьКамнейТранслит);

Для устранения ошибки нам необходимо применить встроенную функцию 1С Лев(), которая возвращает указанное количество символов с начала строки. Изменим код следующим образом:


// Ограничиваем длину передаваемой строки до безопасных 75 символов
ИдентификаторТранслит = ВыборкаЗначенийСвойств.ПереченьКамнейТранслит;
XDTOСправочник.ИдЗначения = XMLСтрока(Лев(ИдентификаторТранслит, 75));

Аналогично следует поступить со всеми остальными полями идентификаторов, где потенциально может возникнуть переполнение длины строки (например, Предложение.Ид при выгрузке торговых предложений с характеристиками):


// Пример обрезки составного идентификатора торгового предложения
XDTOПредложение.Ид = XMLСтрока(Лев(СтрокаИдентификатораПредложения, 80));

Важное предупреждение о рисках коллизий: Этот метод прост в реализации, однако таит в себе серьезную опасность. Если в вашей базе есть два похожих свойства, у которых первые 75 символов транслита совпадают (например, разница кроется лишь в самом конце длинного описания), после обрезки они получат абсолютно одинаковые идентификаторы. При загрузке на сайт это приведет к тому, что одно свойство перезапишет другое, либо CMS выдаст ошибку уникальности данных.


Способ 2. Модификация схемы XSD в планах обмена

Если вы хотите избежать риска коллизий из-за обрезки уникальных ключей, правильным решением будет расширить лимит длины строки в самой схеме XSD, которую использует модуль обмена 1С.

В современных типовых конфигурациях (например, «Управление торговлей 11», «Управление нашей фирмой» или «Комплексная автоматизация») схема XML-обмена хранится непосредственно в метаданных. Давайте разберем по шагам процесс изменения этой схемы:

  1. Откройте базу данных 1С в режиме Конфигуратор.
  2. В дереве метаданных перейдите в ветку Планы обмена.
  3. Найдите план обмена, отвечающий за интеграцию с сайтом (обычно он называется Б_ОбменССайтом или ОбменССайтом).
  4. Найдите внутри плана обмена макет с именем СхемаXSDОбмена (или аналогичный макет со схемой CommerceML).
  5. Экспортируйте этот макет во внешний файл на жесткий диск (тип файла — XML/XSD).
  6. Откройте полученный файл любым текстовым или XML-редактором (например, Notepad++).
  7. Выполните поиск по ключевому слову ИдентификаторГлобальныйТип или найдите ограничение типа, вызывающее ошибку (в нашем случае ищем maxLength value="80").
  8. Измените значение ограничения длины с 80 на более просторное, например, 254:
    
    <xsd:restriction base="xsd:string">
        <xsd:maxLength value="254"/>
    </xsd:restriction>
    
  9. Сохраните изменения в файле и загрузите его обратно в макет схемы плана обмена в Конфигураторе 1С.
  10. Обновите конфигурацию базы данных.

Обратите внимание на ограничения стороны CMS: Увеличение лимита в 1С успешно решит проблему формирования XML-файла. Однако убедитесь, что база данных вашего сайта готова принимать такие длинные идентификаторы. Если в таблицах интернет-магазина под хранение внешних кодов отведено поле типа VARCHAR(80), сайт либо выдаст ошибку импорта, либо незаметно «обрежет» строку при записи, что нарушит последующую синхронизацию.


Способ 3. Профессиональный подход — хэширование данных (MD5)

Как быть, если обрезать строки нельзя из-за риска дублей, а менять схему XSD нежелательно из-за будущих обновлений конфигурации? В профессиональной разработке для решения этой проблемы применяется алгоритм хэширования.

Вместо того чтобы передавать на сайт длинный нечитаемый транслит описания, мы можем сгенерировать из этого описания уникальный хэш-код по алгоритму MD5. Хэш MD5 от строки абсолютно любой длины всегда имеет фиксированный размер — ровно 32 символа (состоит из латинских букв и цифр). Это идеально вписывается в любые ограничения стандартов CommerceML (и 40, и 80 символов).

При этом гарантируется математическая уникальность: даже при минимальном отличии в исходных описаниях товаров мы получим два совершенно разных хэш-кода. Рассмотрим, как реализовать этот подход в коде 1С с использованием встроенного объекта ХешированиеДанных:


// Функция для генерации уникального MD5-идентификатора из исходного текста
Функция ПолучитьMD5ХэшСтроки(ИсходнаяСтрока) Экспорт
    
    Хеш = Новый ХешированиеДанных(ХешФункция.MD5);
    Хеш.Добавить(ИсходнаяСтрока);
    СтрокаХеша = СтрЗаменить(Строка(Хеш.ХешСумма), " ", "");
    
    Возврат НРег(СтрокаХеша); // Возвращаем хэш в нижнем регистре
    
КонецФункции

Теперь мы можем применить эту функцию в модуле обмена при заполнении реквизита XDTO:


// Заменяем длинный транслит на надежный и компактный MD5-хэш
ТекстКамней = ВыборкаЗначенийСвойств.ПереченьКамнейТранслит;
XDTOСправочник.ИдЗначения = XMLСтрока(ПолучитьMD5ХэшСтроки(ТекстКамней));

Использование хэширования — наиболее стабильный, безопасный и отказоустойчивый метод интеграции, исключающий любые коллизии и падения валидатора XML.


Как сохранить изменения при обновлении конфигурации?

Если вы вносите правки непосредственно в общий модуль Б_ОбменССайтомСервер, то при первом же обновлении модуля обмена или конфигурации 1С ваши изменения будут затёрты. Чтобы избежать этого, настоятельно рекомендуется выполнять доработку через механизм расширений конфигурации.

Создайте новое расширение, добавьте в него общий модуль Б_ОбменССайтомСервер и перехватите необходимую процедуру (например, отвечающую за выгрузку свойств товаров) с помощью аннотации &Вместо или &После, реализуя в ней логику хэширования или безопасной обрезки строк.

← На главную