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