Как в КД 2.0 отменить отправку объекта по условию, чтобы он не считался выгруженным

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

При настройке обмена данными через «1С:Конвертация данных 2.0» (КД 2.0) программисты часто сталкиваются с ситуацией, когда объект уже зарегистрирован на узле плана обмена, но в момент выгрузки выясняется, что он еще «не готов» (например, документ не согласован или не заполнены важные дополнительные реквизиты). Если просто прописать Отказ = Истина в обработчиках КД, объект всё равно получит номер сообщения и при получении подтверждения от базы-приемника регистрация будет удалена. В итоге объект так и не попадет в другую базу, пока его снова не изменят вручную.

Разберем подробно, почему так происходит и как правильно реализовать механизм «отложенной» выгрузки несколькими способами.

Почему стандартный Отказ = Истина не решает проблему номера сообщения

Для начала проанализируем ситуацию на уровне платформы. Механизм планов обмена в 1С работает следующим образом:

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

Рассмотрим способы, которые позволят нам «обмануть» систему или использовать штатные механизмы более корректно.

Способ 1. Повторная регистрация объекта («Финт ушами»)

Это самый быстрый способ, который можно реализовать непосредственно в правилах обмена. Суть заключается в том, чтобы после отказа от выгрузки тут же зарегистрировать объект на узле обмена заново. Повторная регистрация «сбрасывает» номер сообщения (устанавливает его в 0 или NULL), и объект попадет в следующую выборку.

Разберем по шагам реализацию в ПВД (Правила выгрузки данных) в обработчике «Перед выгрузкой»:


// Проверяем условие готовности объекта (например, статус согласования)
Если Объект.СтатусСогласования <> Перечисления.СтатусыСогласования.Согласован Тогда
    // Отменяем текущую выгрузку
    Отказ = Истина;
    
    // Регистрируем объект заново, чтобы он не пропал из плана обмена
    // Ссылка на узел часто доступна в параметрах обмена или её можно найти
    УзелОбмена = ПланыОбмена.СинхронизацияДанныхЧерезУниверсальныйФормат.НайтиПоНаименованию("УПП");
    Если НЕ УзелОбмена.Пустая() Тогда
        ПланыОбмена.ЗарегистрироватьИзменения(УзелОбмена, Объект.Ссылка);
    КонецЕсли;
КонецЕсли;

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

Способ 2. Использование Правил регистрации объектов (ПРО)

Более правильный архитектурный подход — сделать так, чтобы объект вообще не регистрировался на плане обмена, пока не выполнено условие. Для этого используются Правила регистрации объектов (ПРО). Рассмотрим, как настроить фильтрацию на этапе регистрации.

Алгоритм действий следующий:

  1. Выгружаем существующие ПРО из базы-источника (обычно через обработку «Регистрация изменений для обмена»).
  2. Загружаем их в конфигурацию «Конвертация данных 2.0».
  3. Находим нужное правило для справочника или документа.
  4. В обработчике «Перед обработкой» или «При регистрации» пишем код проверки условия.

Пример кода в ПРО:


// Если документ не согласован, мы вообще запрещаем его регистрацию на узле
Если Объект.Состояние <> Перечисления.СостоянияДокументов.Согласован Тогда
    Отказ = Истина;
КонецЕсли;

Плюс этого метода в том, что база не будет пытаться выгружать объект при каждом сеансе связи. Минус — если объект уже зарегистрирован, а потом его состояние изменилось на «не готов», нам придется вручную или программно снимать регистрацию.

Способ 3. Работа с обработчиком ПриОтправкеДанных (на уровне платформы)

Если у вас есть доступ к конфигуратору базы-источника, можно использовать наиболее надежный метод, предоставляемый платформой 1С. В модуле менеджера или объекта плана обмена существует обработчик ПриОтправкеДанных.

Рассмотрим, как это работает. В этом событии доступен параметр Игнорировать. Если установить его в Истина, платформа не просто пропустит объект, но и не будет считать его отправленным. Номер сообщения не будет привязан к объекту для этого сеанса.


Процедура ПриОтправкеДанных(ЭлементДанных, ОтправкаЭлемента)
    
    // ЭлементДанных может быть УдалениемОбъекта, поэтому проверяем тип
    Если ТипЗнч(ЭлементДанных) = Тип("ДокументОбъект.ВнутреннийДокумент") Тогда
        Если ЭлементДанных.Согласован = Ложь Тогда
            // Указываем платформе пропустить объект БЕЗ снятия регистрации
            ОтправкаЭлемента = ОтправкаЭлементаДанных.Игнорировать;
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

Этот метод является самым «чистым» с точки зрения производительности и логики работы планов обмена.

Сложные условия (связанные объекты)

Иногда решение о выгрузке зависит не от самого объекта, а от наличия других данных. Например, накладная должна выгружаться только после того, как по ней проведен складской ордер. Сама накладная при проведении ордера не меняется, а значит, регистрация на ней не появится автоматически.

В этом случае проанализируем стратегию «связанной регистрации»:

Рекомендации по оптимизации

Выясним, какой метод лучше выбрать в зависимости от ситуации:

  1. Если база типовая и менять её код нельзя — используйте Способ 1 (перерегистрация в ПВД). Это просто, хоть и не очень производительно.
  2. Если обмен идет через БСП (Синхронизация данных) — используйте Способ 2 (Правила регистрации объектов). Это штатный путь для конфигураций типа ДО 2.1, ERP или УТ 11.
  3. Если вы создаете собственный план обмена и хотите максимальной надежности — используйте Способ 3 (обработчик ПриОтправкеДанных).

Важно: При использовании перерегистрации (Способ 1) всегда следите за тем, чтобы не возникло «бесконечного цикла». Если объект никогда не сможет удовлетворить условию выгрузки, он будет «мусорить» в каждом пакете обмена, увеличивая время выполнения регламентного задания.

← На главную