Как связать отбор по сегменту номенклатуры с параметром запроса в СКД

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

При разработке собственных отчетов на базе типовых решений, таких как 1С:ERP, Комплексная автоматизация или Управление торговлей 11, программисты часто сталкиваются с механизмом сегментации номенклатуры. В текстах запросов типовых отчетов можно встретить конструкцию, которая на первый взгляд кажется нерабочей: параметр ИспользуетсяОтборПоСегментуНоменклатуры в схеме всегда выключен (установлен в Ложь), однако при установке пользователем отбора по сегменту он магическим образом активируется. Рассмотрим подробно, как работает этот механизм и как правильно реализовать его в своем отчете.

Анализ типовой конструкции в запросе

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


(Продажи.АналитикаУчетаНоменклатуры.Номенклатура, Продажи.АналитикаУчетаНоменклатуры.Характеристика) В
    (ВЫБРАТЬ
        ОтборПоСегментуНоменклатуры.Номенклатура,
        ОтборПоСегментуНоменклатуры.Характеристика
    ИЗ
        ОтборПоСегментуНоменклатуры
    ГДЕ
        ОтборПоСегментуНоменклатуры.ИспользуетсяОтборПоСегментуНоменклатуры = &ИспользуетсяОтборПоСегментуНоменклатуры)

Проанализируем ситуацию: в схеме компоновки данных (СКД) на закладке "Параметры" значение ИспользуетсяОтборПоСегментуНоменклатуры жестко задано как Ложь. Если мы просто скопируем этот код в свой отчет, отбор по сегменту работать не будет. Это происходит потому, что платформа 1С сама по себе не знает о логической связи между полем отбора "Сегмент номенклатуры" и этим булевым параметром. Эта связь реализуется программно на уровне конфигурации.

Программная активация отбора в модуле объекта

Выясним причину, почему параметр меняет свое значение. В типовых конфигурациях за это отвечает общий модуль СегментыСервер. Чтобы механизм заработал в вашем отчете, необходимо перехватить процесс компоновки результата. Для этого в модуле объекта отчета нужно прописать процедуру ПриКомпоновкеРезультата.

Рассмотрим пример кода, который необходимо добавить:


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

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

Метод СегментыСервер.ВключитьОтборПоСегментуНоменклатурыВСКД выполняет важную работу: он сканирует КомпоновщикНастроек (как фиксированные настройки, так и пользовательские), ищет там поле СегментНоменклатуры и, если оно заполнено, устанавливает параметр ИспользуетсяОтборПоСегментуНоменклатуры в значение Истина.

Важность точного именования объектов

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

Проанализируем список обязательных имен:

  1. Имя параметра: Должно быть строго ИспользуетсяОтборПоСегментуНоменклатуры.
  2. Имя поля в СКД: Поле, по которому пользователь делает отбор, должно называться СегментНоменклатуры.
  3. Временная таблица/Подзапрос: В тексте запроса должна фигурировать таблица с именем ОтборПоСегментуНоменклатуры, содержащая поля Номенклатура и Характеристика.

Если в вашем запросе нет характеристик, все равно рекомендуется оставлять поле Характеристика (можно заполнить его значением NULL или ЗНАЧЕНИЕ(Справочник.ХарактеристикиНоменклатуры.ПустаяСсылка)), так как типовой алгоритм ожидает определенную структуру таблицы.

Настройка поля отбора в СКД

Разберем по шагам, как настроить само поле отбора в схеме компоновки данных. Просто добавить поле в запрос недостаточно. Часто требуется, чтобы поле "Сегмент номенклатуры" вело себя корректно в пользовательском интерфейсе.

Для этого в СКД на закладке "Наборы данных" для поля СегментНоменклатуры обратите внимание на Параметры выбора. В типовых решениях там часто установлены ограничения, например, по способу формирования сегмента (Отбор.СпособФормирования). Это позволяет пользователю выбирать только те сегменты, которые подходят для данного отчета (например, только динамические или только статические).

Также проверьте Связи параметров выбора. Если эти настройки не будут соответствовать типовым, обработчик в модуле СегментыСервер может проигнорировать ваш отбор, посчитав его некорректным.

Зачем нужна такая сложность (вопрос производительности)

Выясним, почему разработчики 1С не используют простое соединение с регистром сведений "Номенклатура в сегментах". Основная причина — оптимизация запросов на уровне SQL-сервера.

Конструкция ГДЕ ИспользуетсяОтборПоСегментуНоменклатуры = &ИспользуетсяОтборПоСегментуНоменклатуры работает как "предохранитель". Если параметр равен Ложь, оптимизатор базы данных понимает, что все условие ложно, и даже не пытается выполнять вложенный запрос к таблицам сегментов. Это критически важно для производительности в крупных базах данных ERP-систем. Если бы мы использовали обычное ЛЕВОЕ СОЕДИНЕНИЕ, запрос работал бы медленнее из-за избыточных соединений таблиц, даже если пользователь не выбрал ни одного сегмента.

Итоги реализации

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

Следуя этой инструкции, вы сможете бесшовно интегрировать мощный механизм сегментации номенклатуры в свои разработки, сохраняя при этом высокую производительность и совместимость с типовыми механизмами 1С:Предприятия.

← На главную