Как настроить правила регистрации объектов в КД 2.0 с фильтрацией по типам цен и реквизитам узла

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

При настройке обмена данными между конфигурациями 1С (например, УПП 1.3 и УТ 11.4) часто возникает задача селективной регистрации документов. Стандартных средств отбора в Планах обмена не всегда достаточно, особенно когда логика регистрации зависит от содержимого табличных частей документа и настроек конкретного узла-получателя. В данной статье мы разберем, как правильно реализовать фильтрацию регистрации документа Установка цен номенклатуры по типам цен, указанным в настройках узла плана обмена.

Разбор архитектуры обработчиков правил регистрации (ПРО)

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

Рассмотрим основные обработчики:

  1. Перед обработкой: выполняется один раз для типа объекта метаданных. В этом обработчике еще недоступен параметр Узел. Код, написанный здесь, будет применяться ко всем узлам данного плана обмена глобально.
  2. При обработке: выполняется в цикле для каждого узла, на который потенциально может быть зарегистрирован объект. Именно здесь система предоставляет нам доступ к параметру Узел — ссылке на элемент плана обмена.

Если нам нужно проверить, подходит ли документ под условия конкретного магазина или филиала (узла), мы должны использовать обработчик «При обработке».

Реализация фильтрации через запрос к настройкам узла

Предположим, мы добавили в План обмена табличную часть ТипыЦенНоменклатуры и реквизит ИспользоватьОтборПоТипамЦенНоменклатуры. Рассмотрим ситуацию, когда нам нужно проверить, содержит ли регистрируемый документ хотя бы один тип цен, входящий в разрешенный список для конкретного узла.

Для оптимизации процесса в обработчике регистрации можно использовать следующий алгоритм:


// Пример кода для фильтрации в правилах регистрации
ТекстЗапроса = "ВЫБРАТЬ РАЗЛИЧНЫЕ
               |    ОбменТипЦены.ТипЦеныНоменклатуры
               |ИЗ
               |    ПланОбмена.[ИмяПланаОбмена].ТипыЦенНоменклатуры КАК ОбменТипЦены
               |ГДЕ
               |    ОбменТипЦены.Ссылка = &Узел
               |    И ОбменТипЦены.Ссылка.ИспользоватьОтборПоТипамЦенНоменклатуры";

ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "[ИмяПланаОбмена]", ПРО.ИмяПланаОбмена);

Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("Узел", Узел); // Параметр Узел доступен в обработчике "При обработке"

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

В этом примере мы используем параметр ПРО.ИмяПланаОбмена, чтобы сделать код более универсальным. Обратите внимание, что мы устанавливаем Отказ = Истина, только если документ не соответствует условиям отбора. Если Отказ будет установлен в Истина, запись в таблицу регистрации (Changes) для данного узла создана не будет.

Проблема режима выгрузки «При необходимости»

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

Существует три основных режима:

Если для документа Установка цен номенклатуры установлен режим «Выгружать при необходимости», то прямая запись документа не вызовет его появление в обмене, если он не связан, например, с документом реализации, который уже зарегистрирован. Для документов, которые должны уходить в базу-приемник самостоятельно, следует устанавливать режим «Выгружать всегда».

Работа с регистром «Соответствия объектов информационных баз»

При написании запросов в правилах регистрации программисты иногда пытаются опираться на данные регистра СоответствияОбъектовИнформационныхБаз. Выясним, почему это может привести к пустому результату. Данный регистр заполняется после успешной выгрузки и получения подтверждения от базы-приемника. Он хранит связку УникальныйИдентификатор источника и приемника.

На этапе первичной регистрации нового документа записей в этом регистре еще не существует. Поэтому использовать его для логики «должен ли этот объект регистрироваться впервые» нельзя. Этот регистр полезен только для анализа уже «синхронизированных» ранее объектов.

Оптимизация производительности правил регистрации

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

Рассмотрим способы оптимизации:

Почему фильтрация в ПРО лучше, чем в ПВД?

Существует мнение, что проще зарегистрировать всё подряд, а фильтровать уже в Правилах выгрузки данных (ПВД) непосредственно в момент формирования XML-файла. Разберем, почему это плохая практика:

  1. Раздувание таблиц регистрации: если в базе ежедневно создаются тысячи документов, которые не должны уходить в обмен, ваша таблица изменений (_DocumentChngR) будет расти бесконечно.
  2. Производительность обмена: при выполнении выгрузки системе придется сначала прочитать все зарегистрированные изменения, запустить для них логику ПВД и только потом отсеять. Это кратно увеличивает время выгрузки.
  3. Прозрачность для пользователя: в мониторе обмена пользователь будет видеть, что к выгрузке готово 1000 объектов, но после завершения процесса ушло всего 10. Это создает путаницу и затрудняет диагностику ошибок.

Резюме: всегда стремитесь отсекать лишние данные на самом раннем этапе — в правилах регистрации объектов (ПРО) в обработчике «При обработке».

← На главную