При настройке правил регистрации объектов (ПРО) в конфигурации «1С:Конвертация данных 2.1» нередко возникает задача регистрировать документы только при совпадении строго определенных комбинаций нескольких реквизитов. Классический пример — выгрузка документов РеализацияТоваровУслуг только по определенным парам «Организация — Контрагент», которые заданы в табличной части узла плана обмена.
Разберем, почему штатный визуальный отбор в дереве правил не справляется с этой задачей, и рассмотрим практические способы правильной реализации фильтрации.
Проанализируем типовую ошибку при попытке настроить условие через визуальный редактор отборов. Если в табличной части узла плана обмена заданы допустимые пары:
И в правиле регистрации задаются условия вида:
Организация Равно [Состав].ОрганизацияКонтрагент Равно [Состав].КонтрагентВ этом случае платформа проверяет каждую колонку табличной части отдельно от другой. Внутренний механизм преобразует каждую колонку в отдельный массив значений и выполняет логическую проверку:
Объект.Организация В Списке (Организации) И Объект.Контрагент В Списке (Контрагенты)
В результате возникает эффект декартова произведения: документ с сочетанием Организация «А» и Контрагент «Л» также успешно пройдет проверку и зарегистрируется к обмену, поскольку Организация «А» есть в списке организаций, а Контрагент «Л» — в списке контрагентов. Штатный визуальный отбор не умеет сопоставлять колонки как единый строковый кортеж.
Выясним причину успешного решения: чтобы проверить наличие именно конкретной строки с парой значений, необходимо программно обратиться к табличной части узла и отфильтровать список узлов-получателей в обработчике правила регистрации объекта.
Рассмотрим по шагам программную реализацию в обработчике «После обработки» правила регистрации объектов:
СтруктураОтбора = Новый Структура("Организация, Контрагент");
ЗаполнитьЗначенияСвойств(СтруктураОтбора, Объект);
i = 0;
Пока i < Получатели.Количество() Цикл
// Проверяем наличие строки с точным сочетанием обоих реквизитов
Если Получатели[i].Состав.НайтиСтроки(СтруктураОтбора).Количество() = 0 Тогда
Получатели.Удалить(i);
Иначе
i = i + 1;
КонецЕсли;
КонецЦикла;
В этом коде мы формируем структуру с текущими значениями реквизитов документа и методом НайтиСтроки() проверяем, есть ли такое строгое совпадение в табличной части Состав каждого узла из коллекции Получатели. Если совпадений нет, узел удаляется из списка регистрации.
Обратим внимание на важный нюанс: прямое обращение к табличной части через свойство ссылки узла Получатели[i].Состав при проведении или перезаписи большого количества документов порождает повторные запросы к базе данных, что существенно замедляет работу системы.
Для оптимизации скорости выполнения обмена разберем следующие рекомендации:
УзелОбмена, Организация, Контрагент. Проверка существования комбинации через регистр выполняется быстрым индексным запросом или через считывание среза/ключа записи.Если требуется реализовать фильтрацию без перебора коллекции Получатели в коде ПРО, можно применить следующие подходы:
КлючМаршрутизации), в который записывается конкатенация уникальных идентификаторов или кодов (например, УИД_Организации + "_" + УИД_Контрагента). В этом случае в визуальном дереве ПРО настраивается одна строка отбора по равенству составных ключей.Запретить). В конфигурации создается собственная подписка на событие ПередЗаписью или ПриЗаписи, где в коде модуля проверяется валидность комбинации и вызывается стандартный метод платформы ПланыОбмена.ЗарегистрироватьИзменения(Узел, Ссылка).