Как в плане обмена 1С исключить регистрацию элементов по условию

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

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

Постановка задачи и анализ вариантов решения

Представим типичную ситуацию: в нашей конфигурации создан новый план обмена, в состав которого включен справочник СправочникСсылка.Номенклатура с установленным режимом авторегистрации «Разрешить». Нам необходимо сделать так, чтобы номенклатура, у которой реквизит ВидНоменклатуры равен значению «Услуга», не регистрировалась к обмену и не переносилась во внешнюю базу.

Для решения этой задачи в платформе «1С:Предприятие 8» и типовых конфигурациях существует несколько подходов:

  1. Программное управление коллекцией получателей в обработчиках событий объекта (самый быстрый и производительный способ на уровне платформы).
  2. Использование подписок на события (лучший вариант для нетиповых или самописных конфигураций, позволяющий не изменять код самих объектов).
  3. Использование правил регистрации объектов (ПРО) в типовых конфигурациях на базе БСП (Библиотеки Стандартных Подсистем) и конфигурации «Конвертация данных».

Ниже мы детально разберем каждый из этих вариантов, проанализируем их плюсы, минусы и особенности реализации.

Вариант 1. Программное управление свойством ОбменДанными.Получатели

Этот способ основан на использовании штатных свойств платформы 1С. У любого записываемого объекта (справочника, документа и др.) существует свойство ОбменДанными, содержащее коллекцию Получатели. Эта коллекция определяет, для каких именно узлов планов обмена будет зарегистрировано изменение данного объекта при его записи в базу данных.

Выясним, как работает этот механизм по умолчанию. Когда свойство АвтоЗаполнение коллекции Получатели имеет значение Истина, платформа самостоятельно анализирует состав планов обмена и при записи объекта автоматически добавляет все узлы, для которых разрешена авторегистрация, в список получателей.

Чтобы отменить автоматическую регистрацию по условию, нам достаточно в событии ПередЗаписью или ПриЗаписи объекта выполнить следующий алгоритм:

  1. Установить свойство АвтоЗаполнение в значение Ложь. Это предотвратит автоматический подбор узлов платформой.
  2. Очистить коллекцию Получатели, чтобы гарантировать отсутствие зарегистрированных изменений.

Рассмотрим пример кода, который можно разместить прямо в модуле объекта (например, справочника «Номенклатура»):


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

КонецПроцедуры

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

Вариант 2. Использование подписок на события (для нетиповых конфигураций)

Если вы разрабатываете собственную конфигурацию или дорабатываете существующую, крайне не рекомендуется вносить изменения непосредственно в модули объектов (справочников и документов). Это существенно усложнит последующее обновление конфигурации. Гораздо более гибким и изящным решением является создание Подписки на событие.

Давайте по шагам разберем, как реализовать этот механизм в конфигураторе:

  1. Откройте конфигуратор и перейдите в ветку Общие -> Подписки на события.
  2. Добавьте новую подписку на событие (например, назовите ее ИсключитьРегистрациюНоменклатурыПоУсловию).
  3. В свойстве Источник выберите объект, для которого настраивается фильтрация (например, СправочникОбъект.Номенклатура).
  4. В свойстве Событие выберите значение ПередЗаписью.
  5. В свойстве Обработчик укажите процедуру в общем серверном модуле. Обратите внимание, что общий модуль должен иметь включенные свойства Сервер и Вызов сервера (при необходимости).

Проанализируем пример кода для созданного обработчика подписки в общем модуле:


Процедура ИсключитьРегистрациюНоменклатурыПередЗаписью(Источник, Отказ) Экспорт

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

КонецПроцедуры

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

Вариант 3. Выборочная регистрация (когда нужно зарегистрировать только на некоторых узлах)

Часто задача стоит сложнее: нужно не просто полностью запретить регистрацию, а зарегистрировать объект только для определенных узлов плана обмена. Например, документ должен уходить только в тот филиал (узел), к организации которого он относится. При регулярной синхронизации по расписанию фильтрацию по организациям поверх существующего плана обмена выполняет программа автоматического обмена данными между базами 1С.

В этом случае мы также используем отключение автозаполнения, но затем вручную наполняем коллекцию Получатели теми узлами, которые соответствуют нашему условию. Рассмотрим пример:


Процедура ПередЗаписью(Отказ)
    
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;
    
    // Отключаем платформенный механизм автоматической регистрации
    ОбменДанными.Получатели.АвтоЗаполнение = Ложь;
    ОбменДанными.Получатели.Очистить();
    
    // Нам нужно отправить документ только в тот узел, который соответствует организации документа
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   НашПланОбмена.Ссылка КАК Узел
        |ИЗ
        |   ПланОбмена.НашПланОбмена КАК НашПланОбмена
        |ГДЕ
        |   НашПланОбмена.Организация = &Организация";
        
    Запрос.УстановитьПараметр("Организация", ЭтотОбъект.Организация);
    
    Выборка = Запрос.Выполнить().Выбрать();
    Пока Выборка.Следующий() Цикл
        // Программно добавляем узел-получатель в коллекцию
        ОбменДанными.Получатели.Добавить(Выборка.Узел);
    КонецЦикла;

КонецПроцедуры

Таким образом, мы получаем полный и гибкий контроль над тем, куда именно отправляются измененные данные. Для визуальной проверки результатов работы таких алгоритмов или ручного изменения состава зарегистрированных узлов непосредственно из карточки элемента или списка можно применить расширение для управления регистрацией объектов в планах обмена с формы.

Вариант 4. Реализация в типовых конфигурациях (БСП + Конвертация данных)

Если вы работаете в современной типовой конфигурации 1С (такой как ERP, Управление торговлей, Комплексная автоматизация или Бухгалтерия предприятия), в них уже интегрирована **Библиотека Стандартных Подсистем (БСП)**. В БСП встроен мощный механизм управления регистрацией объектов без необходимости изменения программного кода базы данных.

Этот механизм работает на основе Правил регистрации объектов (ПРО), которые создаются в специализированной базе «1С:Конвертация данных» (версии 2.1 или 3.0). Чтобы ускорить этот процесс и не выполнять обновление структуры метаданных при добавлении новых объектов, пригодится инструмент для добавления объектов в состав плана обмена в Конвертации данных 2.

Давайте рассмотрим, как устроен этот процесс:

  1. Выгружается структура метаданных вашей информационной базы.
  2. В базе «Конвертация данных» создаются правила регистрации для требуемого плана обмена.
  3. Для конкретного объекта метаданных (например, справочника «Номенклатура») настраивается режим регистрации. Вместо стандартного «Выгружать всегда» выбирается вариант «Выгружать по условию».
  4. В обработчике события Перед обработкой или При регистрации пишется код на встроенном языке. Например:
    
    Если Объект.ВидНоменклатуры = Справочники.ВидыНоменклатуры.Услуга Тогда
        Отказ = Истина; // Это полностью отменяет регистрацию объекта для узла обмена
    КонецЕсли;
    
  5. Правила регистрации выгружаются в файл формата XML.
  6. В рабочей базе в режиме «1С:Предприятие» этот файл загружается через форму настройки синхронизации данных.

При записи любого объекта БСП перехватывает событие записи через свои общие подписки, обращается к загруженным правилам регистрации в формате XML, выполняет написанный там код и автоматически управляет коллекцией получателей. **Преимущество этого метода колоссально:** вам не нужно вносить изменения в конфигурацию через Конфигуратор и снимать ее с поддержки.

Анализ производительности и важные нюансы

Среди разработчиков иногда встречается практика удаления регистрации изменений "постфактум". То есть, сначала объект записывается со стандартной авторегистрацией, а затем запускается фоновое задание или обработка, которая вызывает метод ПланыОбмена.УдалитьРегистрациюИзменений().

Почему это плохая практика? Проанализируем нагрузку на СУБД. При автоматической регистрации изменений во время транзакции записи объекта платформа выполняет запись во вспомогательные таблицы регистрации изменений (таблицы регистрации изменений планов обмена). Это создает дополнительную транзакционную нагрузку. Если вы затем вызываете удаление регистрации, СУБД вынуждена выполнять повторную транзакцию на удаление этих записей. Это удваивает нагрузку на дисковую подсистему и процессор сервера БД.

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

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


НовыйОбъект = Справочники.Номенклатура.НайтиПоКоду("00001").ПолучитьОбъект();
НовыйОбъект.Наименование = "Новое наименование без обмена";

// Передаем специальный параметр в дополнительные свойства объекта
НовыйОбъект.ДополнительныеСвойства.Вставить("ОтключитьМеханизмРегистрацииОбъектов", Истина);
НовыйОбъект.Записать();

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

Используйте описанные методики программного управления коллекцией получателей и правила регистрации БСП для построения надежных, быстродействующих и легко обновляемых систем интеграции на платформе «1С:Предприятие»!

← На главную