Как в КД 2.0 не переносить помеченные на удаление элементы, которых нет в базе-приемнике?

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

При настройке синхронизации данных между информационными базами 1С с помощью конфигурации «Конвертация данных 2.0 / 2.1» (КД 2.0) часто возникает специфическая задача. Нам необходимо настроить правила обмена так, чтобы элементы справочников, помеченные на удаление в базе-источнике, переносились в базу-приемник только в том случае, если они там уже существуют (чтобы синхронизировать пометку удаления). Если же в базе-приемнике такого элемента еще нет, создавать новый помеченный на удаление объект не нужно.

В этой статье мы подробно разберем, почему стандартные подходы с использованием отказа от записи приводят к появлению «битых» или пустых элементов, как правильно реализовать эту логику с помощью предопределенных свойств КД и почему измененные правила могут не работать в рабочей базе из-за особенностей механизмов БСП.

Почему не работают очевидные решения с «Отказом»?

Первое, что часто пробуют разработчики — это прописать логику отказа в обработчиках выгрузки или загрузки. Проанализируем, почему эти способы не подходят:

  1. Простой отказ при выгрузке (обработчик ПередВыгрузкой в ПКО):

    Если мы напишем код Отказ = Истина для всех объектов, у которых Источник.ПометкаУдаления = Истина, то такие элементы вообще не попадут в файл выгрузки. Но что произойдет, если этот объект ранее уже был перенесен в приемник? В этом случае пометка удаления, установленная в источнике, никогда не дойдет до приемника. Данные рассинхронизируются: в источнике объект помечен на удаление, а в приемнике он останется активным.

  2. Отказ при загрузке (обработчик ПослеЗагрузки в ПКО):

    Многие пытаются написать в приемнике код вида:

    
    Если НЕ ОбъектНайден И Объект.ПометкаУдаления Тогда
        Отказ = Истина;
    КонецЕсли;
    

    В результате такого подхода в базе-приемнике начинают появляться пустые (или «битые») ссылки. Выясним причину этого поведения. К моменту выполнения обработчика ПослеЗагрузки XML-пакет уже прочитан, и платформа зафиксировала ссылку на новый объект в памяти. Если на этот объект ссылаются другие данные (например, табличные части документов, движения или реквизиты других справочников), то отмена записи самого объекта в обработчике ПослеЗагрузки не отменяет создание ссылки-заглушки. В итоге мы получаем пустую запись в базе данных.

Идеальное решение: использование свойства «НеСоздаватьЕслиНеНайден»

Для корректного решения нашей задачи в архитектуре «Конвертации данных» предусмотрено специальное свойство — НеСоздаватьЕслиНенайден. Рассмотрим, как оно работает.

Когда мы устанавливаем флаг НеСоздаватьЕслиНенайден = Истина на этапе выгрузки для конкретного ПКО (Правила конвертации объектов), то при чтении файла обмена в базе-приемнике сначала выполняется поиск существующего элемента (по уникальному идентификатору или полям поиска):

Разберем по шагам, как это настроить в конфигурации «Конвертация данных 2.0».

Пошаговая настройка правил обмена

Откроем наши правила обмена в КД и перейдем к настройке нужного ПКО справочника.

Шаг 1. Настройка обработчика «Перед выгрузкой» в ПКО

Перейдем на вкладку «Обработчики событий» нашего ПКО и выберем событие ПередВыгрузкой. Нам необходимо проверять, помечен ли объект на удаление в источнике. Если помечен, мы взводим нужный флаг.

Напишем следующий код:


Если Источник.ПометкаУдаления Тогда
    НеСоздаватьЕслиНенайден = Истина;
КонецЕсли;

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

Шаг 2. Оптимизация объема выгрузки в обработчике «При выгрузке» (необязательно)

Если объект помечен на удаление и его, возможно, вообще не будут создавать в приемнике, нам незачем выгружать все его связанные свойства (другие справочники по ссылкам, табличные части и т.д.). Для этого в обработчике ПриВыгрузке ПКО мы можем отключить выгрузку связанных объектов:


Если Источник.ПометкаУдаления Тогда
    // Запрещаем вытягивать подчиненные объекты по ссылкам, экономя трафик и время
    ПКО.НеВыгружатьОбъектыСвойствПоСсылкам = Истина;
КонецЕсли;

Проблема с кэшированием правил в БСП (почему в тесте работает, а в рабочей базе нет)

Очень часто разработчики сталкиваются со следующей ситуацией: в тестовой базе (при ручном запуске обмена через обработку УниверсальныйОбменДаннымиXML) новые правила работают идеально. Но стоит перенести правила в рабочую базу, где настроен автоматический обмен по расписанию, как пустые объекты снова начинают создаваться.

Выясним причину этой проблемы. В современных конфигурациях 1С, построенных на базе БСП (Библиотеки стандартных подсистем), правила обмена не считываются каждый раз из внешнего XML-файла. Они кэшируются непосредственно в самой базе данных — в регистре сведений «Правила для обмена данными» (в некоторых версиях БСП название может немного отличаться, например, «Правила конвертации объектов»).

Когда вы запускаете обмен через регламентное задание, система берет правила именно из этого регистра. Поскольку вы не обновили правила внутри самой информационной базы, система продолжает использовать старый алгоритм.

Чтобы изменения вступили в силу, выполним следующие действия:

  1. Откроем рабочую базу данных (как источник, так и приемник) под правами администратора.
  2. Перейдем в раздел «Администрирование» — «Синхронизация данных».
  3. Откроем список настроенных синхронизаций и перейдем в параметры нужного узла обмена.
  4. Найдем пункт «Загрузить правила обмена» (или аналогичную кнопку ручной загрузки правил).
  5. Укажем путь к нашему сохраненному XML-файлу с обновленными правилами и выполним их загрузку в базу. При этом новые правила запишутся в соответствующий регистр сведений БСП.
  6. Повторим процедуру загрузки правил для второй информационной базы, если обмен двусторонний.

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

← На главную