Как настроить выгрузку из ЗУП 3.1 по условию дополнительного реквизита в 1С:Конвертация данных 2.1

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

При работе с инструментом 1С:Конвертация данных 2.1 (КД 2.1) часто возникает необходимость гибкой фильтрации данных. Одной из типичных задач является выгрузка объектов (например, справочника Подразделения), основываясь на значении дополнительного реквизита, созданного пользователем в пользовательском режиме. Рассмотрим, как правильно реализовать такой алгоритм, разберем причины типовых ошибок и выберем наиболее оптимальный способ решения задачи для конфигураций на базе БСП (Библиотеки стандартных подсистем), таких как ЗУП 3.1.

Анализ проблемы: почему возникает ошибка Поле объекта не обнаружено (ДополнительныеСвойства)

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

В современных конфигурациях (ЗУП 3.1, ERP, КА 2, БП 3.0) дополнительные реквизиты и сведения хранятся по правилам БСП:

  1. Дополнительные реквизиты — хранятся в табличной части самого объекта, которая называется ДополнительныеРеквизиты.
  2. Дополнительные сведения — хранятся во внешнем регистре сведений ДополнительныеСведения.

Решение 1: Фильтрация через табличную часть ДополнительныеРеквизиты

Если ваше свойство настроено именно как реквизит (отображается в карточке объекта), то оно находится в табличной части подразделения. Проанализируем правильный алгоритм проверки в обработчике ПКО (Правило конвертации объекта) Перед выгрузкой:


// 1. Находим ссылку на само свойство (план видов характеристик)
СвойствоСсылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Имя", "ИмяВашегоРеквизита");

// 2. Ищем строку с этим свойством в табличной части объекта
НайденнаяСтрока = Объект.ДополнительныеРеквизиты.Найти(СвойствоСсылка, "Свойство");

// 3. Проверяем значение
Если НайденнаяСтрока <> Неопределено Тогда
    // Если значение не ИСТИНА, то отменяем выгрузку объекта
    Если НайденнаяСтрока.Значение <> Истина Тогда
        Отказ = Истина;
    КонецЕсли;
Иначе
    // Если строка в ТЧ не найдена, значит реквизит не заполнен (эквивалентно ЛОЖЬ)
    Отказ = Истина;
КонецЕсли;

Важно помнить: метод НайтиПоРеквизиту по полю Имя ищет внутреннее имя программного идентификатора, которое задается при создании доп. реквизита. Если вы не уверены в имени, можно использовать НайтиПоНаименованию, но это менее надежно, так как пользователи могут изменить заголовок в интерфейсе.

Решение 2: Проверка через регистр ДополнительныеСведения

Если настройка выполнена как дополнительное сведение, данные не хранятся внутри объекта Подразделения. В этом случае нам необходимо обратиться к регистру сведений. Рассмотрим, как это написать в правилах:


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

// Получение значения из регистра
ЗначениеСведения = РегистрыСведений.ДополнительныеСведения.Получить(КлючЗаписи).Значение;

Если ЗначениеСведения <> Истина Тогда
    Отказ = Истина;
КонецЕсли;

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

Оптимизация: Повышение производительности выгрузки

Выполнять поиск ссылки на свойство (НайтиПоРеквизиту) в цикле выгрузки каждого объекта — плохая практика. Если у вас 10 000 подразделений, программа сделает 10 000 лишних поисков. Выясним, как это оптимизировать с помощью глобальных параметров конвертации.

Шаг 1: В обработчике ПВД (Правила выгрузки данных) Перед выгрузкой данных (глобальный уровень) найдем ссылку один раз и сохраним в кэш:


Параметры.Вставить("СсылкаНаДопРеквизит", ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоРеквизиту("Имя", "МойРеквизитДляФильтра"));

Шаг 2: В ПКО справочника используем готовую ссылку из параметров:


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

Профессиональный подход: Использование Запроса в ПВД

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

Создадим ПВД для справочника Подразделения с типом выборки Произвольный алгоритм:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Подразделения.Ссылка
    |ИЗ
    |   Справочник.ПодразделенияОрганизаций КАК Подразделения
    |       ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ПодразделенияОрганизаций.ДополнительныеРеквизиты КАК ДопРеквизиты
    |       ПО ДопРеквизиты.Ссылка = Подразделения.Ссылка
    |ГДЕ
    |   ДопРеквизиты.Свойство.Имя = &ИмяСвойства
    |   И ДопРеквизиты.Значение = ИСТИНА";

Запрос.УстановитьПараметр("ИмяСвойства", "трам-пам-пам");
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл
    ВыгрузитьПоПравилу(Выборка.Ссылка, , , , "Подразделения");
КонецЦикла;

Преимущества этого метода:

Важные нюансы при работе с типами данных

Посмотрим на тип данных значения дополнительного реквизита. В 1С это обычно Характеристика.ДополнительныеРеквизитыИСведения. При сравнении в коде всегда используйте явное приведение или проверку на тип, если реквизит может быть не только Булево, но и другого типа. Использование Если Значение = Истина Тогда — наиболее безопасный вариант, так как он корректно обработает и NULL, и Неопределено, вернув ложный результат условия.

Проанализировав все способы, мы видим, что наиболее надежным и простым для быстрой правки является обращение к табличной части объекта (Решение 1), а для высоконагруженных систем — использование запроса в ПВД.

← На главную