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