При настройке обмена данными между конфигурациями 1С (например, УПП 1.3 и УТ 11.4) часто возникает задача селективной регистрации документов. Стандартных средств отбора в Планах обмена не всегда достаточно, особенно когда логика регистрации зависит от содержимого табличных частей документа и настроек конкретного узла-получателя. В данной статье мы разберем, как правильно реализовать фильтрацию регистрации документа Установка цен номенклатуры по типам цен, указанным в настройках узла плана обмена.
Для начала проанализируем, где именно должен выполняться код фильтрации. В механизме Конвертации данных 2.0 предусмотрено несколько ключевых обработчиков для правил регистрации объектов. Ошибка многих разработчиков заключается в неправильном выборе контекста выполнения кода.
Рассмотрим основные обработчики:
Узел. Код, написанный здесь, будет применяться ко всем узлам данного плана обмена глобально.Узел — ссылке на элемент плана обмена.Если нам нужно проверить, подходит ли документ под условия конкретного магазина или филиала (узла), мы должны использовать обработчик «При обработке».
Предположим, мы добавили в План обмена табличную часть ТипыЦенНоменклатуры и реквизит ИспользоватьОтборПоТипамЦенНоменклатуры. Рассмотрим ситуацию, когда нам нужно проверить, содержит ли регистрируемый документ хотя бы один тип цен, входящий в разрешенный список для конкретного узла.
Для оптимизации процесса в обработчике регистрации можно использовать следующий алгоритм:
// Пример кода для фильтрации в правилах регистрации
ТекстЗапроса = "ВЫБРАТЬ РАЗЛИЧНЫЕ
| ОбменТипЦены.ТипЦеныНоменклатуры
|ИЗ
| ПланОбмена.[ИмяПланаОбмена].ТипыЦенНоменклатуры КАК ОбменТипЦены
|ГДЕ
| ОбменТипЦены.Ссылка = &Узел
| И ОбменТипЦены.Ссылка.ИспользоватьОтборПоТипамЦенНоменклатуры";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "[ИмяПланаОбмена]", ПРО.ИмяПланаОбмена);
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("Узел", Узел); // Параметр Узел доступен в обработчике "При обработке"
РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
ТаблицаТиповЦен = РезультатЗапроса.Выгрузить().ВыгрузитьКолонку("ТипЦеныНоменклатуры");
ПодходитДляОбмена = Ложь;
Для Каждого СтрокаТЧ Из Объект.ТипыЦен Цикл
Если ТаблицаТиповЦен.Найти(СтрокаТЧ.ТипЦены) <> Неопределено Тогда
ПодходитДляОбмена = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если Не ПодходитДляОбмена Тогда
Отказ = Истина;
КонецЕсли;
КонецЕсли;
В этом примере мы используем параметр ПРО.ИмяПланаОбмена, чтобы сделать код более универсальным. Обратите внимание, что мы устанавливаем Отказ = Истина, только если документ не соответствует условиям отбора. Если Отказ будет установлен в Истина, запись в таблицу регистрации (Changes) для данного узла создана не будет.
Проанализируем ситуацию, когда регистрация не происходит, несмотря на корректный код в ПРО. Одной из неочевидных причин является настройка Режима выгрузки объектов в самом плане обмена.
Существует три основных режима:
Если для документа Установка цен номенклатуры установлен режим «Выгружать при необходимости», то прямая запись документа не вызовет его появление в обмене, если он не связан, например, с документом реализации, который уже зарегистрирован. Для документов, которые должны уходить в базу-приемник самостоятельно, следует устанавливать режим «Выгружать всегда».
При написании запросов в правилах регистрации программисты иногда пытаются опираться на данные регистра СоответствияОбъектовИнформационныхБаз. Выясним, почему это может привести к пустому результату. Данный регистр заполняется после успешной выгрузки и получения подтверждения от базы-приемника. Он хранит связку УникальныйИдентификатор источника и приемника.
На этапе первичной регистрации нового документа записей в этом регистре еще не существует. Поэтому использовать его для логики «должен ли этот объект регистрироваться впервые» нельзя. Этот регистр полезен только для анализа уже «синхронизированных» ранее объектов.
Важно помнить, что код ПРО выполняется при каждом вызове метода Записать() для объекта. Если выполнять тяжелые запросы внутри регистрации, это может существенно замедлить работу пользователей в системе.
Рассмотрим способы оптимизации:
ПараметрыСеанса (если объем данных невелик).Узел.Код или Узел.ВашРеквизит напрямую. Платформа 1С оптимизирует такие обращения, если объект уже находится в кэше.НайтиСтроки() со структурой отбора или выгрузку колонки в массив/соответствие для быстрого поиска.Существует мнение, что проще зарегистрировать всё подряд, а фильтровать уже в Правилах выгрузки данных (ПВД) непосредственно в момент формирования XML-файла. Разберем, почему это плохая практика:
_DocumentChngR) будет расти бесконечно.Резюме: всегда стремитесь отсекать лишние данные на самом раннем этапе — в правилах регистрации объектов (ПРО) в обработчике «При обработке».