Почему при обмене 1С с сайтом обрезаются значения дополнительных реквизитов в XML?

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

При настройке стандартного обмена между 1С и интернет-магазином специалисты часто сталкиваются с неприятной ситуацией: длинные описания товаров или значения дополнительных реквизитов, которые в самой программе отображаются полностью, в итоговом XML-файле (CommerceML) обрезаются до 1024 или более символов. Рассмотрим причины возникновения этой ошибки и разберем по шагам, как восстановить передачу полных данных.

Разберем архитектуру хранения данных в БСП

Для начала проанализируем, как 1С:Предприятие работает с дополнительными реквизитами. Большинство современных конфигураций (УНФ, УТ 11, ERP, КА) используют Библиотеку стандартных подсистем (БСП). В этой библиотеке механизм дополнительных реквизитов реализован с определенной хитростью ради оптимизации производительности базы данных.

В табличной части ДополнительныеРеквизиты у любого объекта (например, справочника Номенклатура) есть два ключевых поля:

  1. Значение — имеет тип Характеристика.ДополнительныеРеквизитыИСведения. Физически в базе данных этот тип имеет ограничение по длине. Если строка превышает лимит (обычно 1024 символа), она не может быть корректно сохранена в этом поле без потери данных.
  2. ТекстоваяСтрока — специальное поле с типом «Строка неограниченной длины».

Выясним причину обрезки: когда вы записываете в дополнительный реквизит очень длинный текст, БСП автоматически помещает первые 1024 символа в поле Значение, а полный текст — в поле ТекстоваяСтрока. Если же программный код обмена обращается только к полю Значение, сайт получает «обрубок» текста.

Проблема программного присвоения значений

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

Проанализируем пример неправильного кода:


НовыйРеквизит = НоваяПозиция.ДополнительныеРеквизиты.Добавить();
НовыйРеквизит.Свойство = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Описание товара");
НовыйРеквизит.Значение = ДлиннаяСтрока; // Здесь произойдет обрезка до 1024 символов

Для корректного сохранения данных необходимо явно задействовать поле ТекстоваяСтрока. Рассмотрим исправленный вариант:


НовыйРеквизит = НоваяПозиция.ДополнительныеРеквизиты.Добавить();
НовыйРеквизит.Свойство = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Описание товара");
НовыйРеквизит.Значение = Лев(ДлиннаяСтрока, 1024); 
НовыйРеквизит.ТекстоваяСтрока = ДлиннаяСтрока; // Сохраняем полный текст

Важно помнить, что в конфигураторе само свойство должно иметь тип «Дополнительное значение» или «Строка» с установленным флагом «Неограниченная длина». Однако, даже при этой настройке, поле Значение в табличной части остается ограниченным типом Характеристика.

Обрезание строк в SQL-запросах выгрузки

Если в базе данных текст хранится полностью, но в XML-файл все равно попадает обрезанная строка, значит проблема кроется в алгоритме формирования самой выгрузки. Посмотрим на работу модуля ОбменССайтом.

Часто для формирования пакета данных система использует временные таблицы и объединение запросов (ОБЪЕДИНИТЬ). В языке запросов 1С существует жесткое ограничение: нельзя объединять поля неограниченной длины. Чтобы обойти это, разработчики типовых решений используют конструкцию ВЫРАЗИТЬ.

Проанализируем ситуацию в коде запроса:


"ВЫБРАТЬ
|   ВЫРАЗИТЬ(ДополнительныеРеквизиты.Значение КАК СТРОКА(1024)) КАК ЗначениеСвойства
|ИЗ
|   Справочник.Номенклатура.ДополнительныеРеквизиты КАК ДополнительныеРеквизиты"

В этом случае, какой бы длинный текст ни был в базе, запрос принудительно «откусит» всё, что идет после 1024-го символа. Чтобы исправить это, необходимо найти в общем модуле (например, ОбменССайтомВыгрузка или ОбменССайтомУНФ) место формирования запроса по свойствам и изменить логику получения значения. Вместо прямого обращения к Значение следует проверять наличие данных в ТекстоваяСтрока.

Ограничения в XDTO-пакетах (CommerceML)

Еще одна скрытая причина — использование XDTO-пакетов. Стандарт CommerceML описывается в 1С через пакеты (например, CML208). Если в схеме данных для типа ЗначениеСвойства или Описание установлено ограничение maxLength, то при сериализации данных в XML платформа может обрезать строку согласно этому правилу.

Выполним следующие шаги для проверки:

  1. Откроем конфигуратор и перейдем в ветку Общие -> XDTO-пакеты.
  2. Найдем пакет, отвечающий за CommerceML (в УНФ это может быть пакет, встроенный в модуль обмена).
  3. Найдем определение типа, используемого для передачи значений свойств.
  4. Проверим свойство maxLength. Если оно установлено в 1024, его необходимо увеличить или убрать ограничение вовсе.

Как настроить отладку фоновых заданий

Выяснить, в каком именно месте происходит обрезка, без отладки практически невозможно. Поскольку обмен с сайтом обычно запускается как фоновое задание, стандартная точка останова может не сработать. Разберем, как это исправить:

  1. В конфигураторе откройте меню Отладка -> Подключение.
  2. Нажмите кнопку Автоматическое подключение.
  3. В появившемся окне установите флажок Фоновые задания.
  4. Теперь точки останова в общих модулях обмена будут срабатывать при запуске процесса выгрузки.

В процессе отладки используйте Замер производительности. Запустите обмен, дождитесь завершения и проанализируйте, в какие модули заходила система. Ищите методы со словами Свойства, Значения и XML. Особое внимание уделите тому, откуда берутся данные: из Выборка.Значение или из Выборка.ТекстоваяСтрока.

Резюмируем: Для решения проблемы необходимо обеспечить сохранение данных в поле ТекстоваяСтрока, скорректировать запросы в модулях обмена, чтобы они не использовали ВЫРАЗИТЬ( ... КАК СТРОКА(1024)), и убедиться, что XDTO-пакеты не накладывают свои ограничения на длину строковых узлов XML.

← На главную