При организации интеграции между конфигурациями на платформе 1С:Предприятие разработчики часто сталкиваются с ситуацией, когда одни и те же правила обмена данными (ПОД), созданные в конфигурации «Конвертация данных 2.1», ведут себя совершенно по-разному в зависимости от способа запуска. При выгрузке через встроенную обработку УниверсальныйОбменДаннымиXML справочник Номенклатура выгружается полностью: вместе с элементами переносится вся их иерархическая структура (родительские группы), а также связанные объекты (единицы измерения, номенклатурные группы, производители и другие ссылочные свойства). Однако при привязке этих же правил к узлу плана обмена в рамках регулярного online-обмена принимающая база получает лишь «пустые» ссылки — переносятся только уникальные идентификаторы (UID) и поля поиска родительских групп или свойств, в то время как сами эти объекты в базу-приемник не записываются. В этой статье мы подробно разберем, почему возникает такое поведение, проанализируем его причины и рассмотрим пять способов решения проблемы — от простых программных «костылей» до методологически верных архитектурных настроек.
Для того чтобы понять природу этой проблемы, проанализируем внутренние механизмы работы платформы 1С и Библиотеки стандартных подсистем (БСП). Когда мы запускаем ручную выгрузку через обработку УниверсальныйОбменДаннымиXML, система по умолчанию обходит дерево ссылок выгружаемых объектов на всю доступную глубину. Если у элемента номенклатуры заполнено поле Родитель или указана ссылка на элемент справочника КлассификаторЕдиницИзмерения, обработка автоматически инициирует полную выгрузку этих связанных объектов, сериализуя их структуру в результирующий XML-файл.
В случае интеграции на основе планов обмена (особенно под управлением БСП) логика кардинально меняется. Здесь во главу угла ставится производительность и минимизация трафика. Система применяет жесткую оптимизацию: объекты, на которые есть ссылки в выгружаемом элементе, но которые сами не зарегистрированы на узле плана обмена, выгружаются исключительно в виде «узлов-ссылок» (передаются только GUID и ключевые поля поиска). Платформа исходит из предположения, что если объект (например, родительская группа или свойство) не был изменен в текущей сессии, то он уже существует в базе-приемнике, и передавать его повторно целиком нет никакой необходимости.
Это позволяет решить три важнейшие задачи:
Однако если в базе-приемнике этих связанных объектов еще нет (например, при первоначальном заполнении базы или если они были созданы только в источнике), мы получаем классическую проблему «битых ссылок» или неполных данных. Выясним, как мы можем управлять этим поведением.
Рассмотрим решение, которое часто находят разработчики на форумах (в частности, предложенное в сообщении №6 исходной темы). Оно заключается в принудительном отключении оптимизации планов обмена непосредственно в правилах конвертации объектов (ПКО).
Для этого в конфигурации «Конвертация данных 2.1» для ПКО нужного справочника (например, Номенклатура или ГруппыНоменклатуры) в обработчике события ПередВыгрузкой прописывается следующий код:
ВсеОбъектыВыгружены = Ложь;
ТолькоПолучитьУзелСсылки = Ложь;
Проанализируем работу этих переменных:
ТолькоПолучитьУзелСсылки — эта специальная переменная ядра обмена 1С при значении Ложь принудительно указывает механизму выгрузки, что объект должен быть записан в XML-файл полностью, даже если он выгружается по ссылке из другого объекта и не зарегистрирован на узле плана обмена.ВсеОбъектыВыгружены — установка этой переменной в значение Ложь сбрасывает внутренний кэш выгруженных объектов, заставляя систему повторно сериализовать объект, даже если в рамках текущей транзакции обмена он уже был однажды выгружен.Важное предупреждение! Несмотря на то, что данный способ является самым простым в реализации и действительно решает локальную задачу «здесь и сейчас», применять его в реальных рабочих базах крайне не рекомендуется по следующим причинам:
Перейдем к более цивилизованным и безопасным методам. Если ваша конфигурация построена на базе БСП (Библиотека стандартных подсистем), лучшим решением будет использование встроенных режимов выгрузки объектов, определенных в составе плана обмена.
Разберем этот процесс по шагам:
Установка режима «Выгружать при необходимости» для вспомогательных справочников (классификаторы, группы, свойства) — это самый безопасный и методологически верный способ организации обмена без написания кода.
Если интеграция настраивается непосредственно через правила конвертации в «Конвертации данных 2.1» и мы хотим зафиксировать это поведение на уровне самих правил, не полагаясь на настройки БСП в конфигураторе, мы можем использовать специальную настройку ПКО.
Рассмотрим, как это сделать:
ЗначенияСвойствОбъектов или ГруппыНоменклатуры).Эта настройка работает аналогично режиму БСП «Выгружать при необходимости». При выгрузке основного объекта (номенклатуры) обработчик обмена проанализирует правила для связанных объектов. Если у них взведен данный флаг, система выполнит их полную сериализацию, предотвращая появление пустых ссылок в базе-приемнике, но при этом сохранит защиту от бесконечной рекурсии и не будет выгружать эти справочники целиком без надобности.
Иногда нам требуется гибкость: мы хотим, чтобы полностью выгружался не весь справочник со всеми связями, а только конкретные реквизиты конкретного объекта. Например, мы хотим, чтобы родительская группа выгружалась полностью, а вот справочник складов или контрагентов, указанных в свойствах, переносился только ссылкой.
В этом случае нам поможет использование предопределенной переменной ВыгружатьОбъект в Правилах Конвертации Свойств (ПКС).
Выполним следующие шаги:
Номенклатура.Родитель (или любого другого свойства, которое нужно выгрузить полностью).ПередВыгрузкой напишем простой код:
ВыгружатьОбъект = Истина;
Проанализируем, как это работает. Переменная ВыгружатьОбъект имеет локальную область видимости в контексте конкретного свойства. Устанавливая ее в значение Истина, мы даем команду движку обмена: «Для данного конкретного реквизита текущего объекта проигнорируй оптимизацию планов обмена и выгрузи связанный объект со всеми его реквизитами». Это наиболее гибкий и безопасный программный метод, так как он не отключает глобальные механизмы защиты во всей базе данных, а действует точечно.
Самый профессиональный и архитектурно правильный подход в экосистеме решений 1С — это управление регистрацией изменений. Если нам нужно, чтобы при изменении или создании номенклатуры в приемник уходила вся цепочка ее родительских групп и свойств, мы должны гарантировать, что эти объекты физически зарегистрированы на узле плана обмена к отправке.
Для реализации этого подхода используются **Правила регистрации объектов (ПРО)**. Мы можем настроить их в «Конвертации данных 2.1» (раздел «Правила регистрации») или реализовать этот механизм в модуле плана обмена источника через подписки на события.
Рассмотрим пример реализации через подписку на событие ПередЗаписью или ПриЗаписи номенклатуры. Пропишем алгоритм, который при регистрации элемента номенклатуры автоматически находит всю цепочку его родителей и регистрирует их на узле плана обмена:
Процедура ЗарегистрироватьИерархиюНоменклатуры(ЭлементНоменклатуры, УзелПланаОбмена) Экспорт
ТекущийРодитель = ЭлементНоменклатуры.Родитель;
Пока ЗначениеЗаполнено(ТекущийРодитель) Цикл
// Регистрируем родительскую группу на узле плана обмена
ПланыОбмена.ЗарегистрироватьИзменения(УзелПланаОбмена, ТекущийРодитель);
// Переходим к следующему уровню иерархии
ТекущийРодитель = ТекущийРодитель.Родитель;
КонецЦикла;
КонецПроцедуры
При таком подходе система обмена работает абсолютно штатно и предсказуемо. Когда запускается очередной сеанс обмена данными, платформа видит, что и сам элемент номенклатуры, и все его вышестоящие группы зарегистрированы к отправке. Они выгружаются стандартным образом как полноценные самостоятельные объекты. Это исключает любые коллизии, гарантирует целостность базы данных и сохраняет все преимущества оптимизации планов обмена.
Для того чтобы облегчить выбор оптимального решения для вашего проекта, обобщим все рассмотренные методы в виде итоговых рекомендаций:
Мы надеемся, что этот подробный разбор механизмов сериализации и планов обмена поможет вам спроектировать надежную, быструю и отказоустойчивую систему интеграции ваших прикладных решений на платформе 1С:Предприятие.