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