Как в СКД сделать жесткий отбор по группе иерархии в запросе без возможности изменения пользователем?

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

При разработке отчетов в системе компоновки данных (СКД) часто возникает задача ограничить выборку данных определенной веткой справочника. Например, сформировать отчет строго по товарам из группы «Аксессуары». При этом нередко требуется скрыть данный отбор от конечного пользователя и защитить его от случайного изменения или сброса при перенастройке варианта отчета.

Рассмотрим несколько способов реализации такого отбора, разберем синтаксис языка запросов 1С, возможности вкладки Параметры в СКД, а также программные механизмы платформы.

Способ 1. Получение группы внутри текста запроса через вложенный запрос

Если группа справочника не является предопределенным элементом и создана пользователями в режиме «1С:Предприятие», в тексте запроса нельзя просто написать строку с наименованием в скобках после оператора В ИЕРАРХИИ. Оператор ожидает ссылку на элемент или массив ссылок. Однако мы можем получить эту ссылку прямо в тексте запроса с помощью вложенной выборки.

Посмотрим на пример текста запроса, в котором условие отбора накладывается по наименованию папки:


ВЫБРАТЬ
    РеализацияТоваровУслугТовары.Количество КАК Количество,
    РеализацияТоваровУслугТовары.Сумма КАК Сумма,
    РеализацияТоваровУслугТовары.Ссылка.Дата КАК Дата,
    РеализацияТоваровУслугТовары.Номенклатура КАК Номенклатура
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
ГДЕ
    РеализацияТоваровУслугТовары.Номенклатура В ИЕРАРХИИ
        (ВЫБРАТЬ ПЕРВЫЕ 1
            Номенклатура.Ссылка
        ИЗ
            Справочник.Номенклатура КАК Номенклатура
        ГДЕ
            Номенклатура.Наименование = "Аксессуары"
            И Номенклатура.ЭтоГруппа = ИСТИНА)

Разберем важные нюансы этого подхода:

  1. Поиск по наименованию: реквизит Наименование в справочниках по умолчанию не индексируется. Вложенный запрос к большой таблице справочника может выполнять полное сканирование. Кроме того, если пользователи создадут дубль группы с таким же наименованием или переименуют папку, отчет выдаст неверные данные или окажется пустым.
  2. Поиск по коду: поиск по коду более надежен, так как поле Код индексируется платформой. Запрос будет выглядеть аналогично, но в условии фильтрации папки будет указано Номенклатура.Код = "000000123". Однако при переносе данных через правила обмена или перенумерации справочника код также может измениться.

Способ 2. Использование параметров СКД с вычислением через выражение

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

Разберем по шагам, как настроить такой вариант:

  1. В тексте запроса набора данных используем стандартную параметризацию:
    
    ВЫБРАТЬ
        РеализацияТоваровУслугТовары.Количество КАК Количество,
        РеализацияТоваровУслугТовары.Сумма КАК Сумма,
        РеализацияТоваровУслугТовары.Ссылка.Дата КАК Дата,
        РеализацияТоваровУслугТовары.Номенклатура КАК Номенклатура
    ИЗ
        Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
    ГДЕ
        РеализацияТоваровУслугТовары.Номенклатура В ИЕРАРХИИ (&НужнаяПапка)
    
  2. Перейдем на вкладку Параметры схемы компоновки данных. Платформа автоматически добавит параметр НужнаяПапка.
  3. Установим флаг в колонке Ограничение доступности. Это полностью скроет параметр из пользовательского интерфейса, и оператор не сможет увидеть его или изменить значение.
  4. В колонке Выражение пропишем вызов встроенного языка для получения ссылки: Справочники.Номенклатура.НайтиПоКоду("000000123") или: Справочники.Номенклатура.НайтиПоНаименованию("Аксессуары")

В этом случае текст запроса остается чистым и легко читаемым, а логика получения группы вынесена на уровень метаданных схемы компоновки.

Способ 3. Использование предопределенных элементов и функции ЗНАЧЕНИЕ()

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

В этом случае отпадает необходимость во вложенных запросах, поиске по коду или наименованию. В тексте запроса можно напрямую обратиться к элементу через конструкцию ЗНАЧЕНИЕ():


ВЫБРАТЬ
    РеализацияТоваровУслугТовары.Количество КАК Количество,
    РеализацияТоваровУслугТовары.Сумма КАК Сумма,
    РеализацияТоваровУслугТовары.Ссылка.Дата КАК Дата,
    РеализацияТоваровУслугТовары.Номенклатура КАК Номенклатура
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
ГДЕ
    РеализацияТоваровУслугТовары.Номенклатура В ИЕРАРХИИ (ЗНАЧЕНИЕ(Справочник.Номенклатура.Аксессуары))

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

Способ 4. Программная установка через ФиксированныеНастройки в модуле объекта

Иногда требуется задавать значение программно (например, читать его из константы или дополнительных настроек), но гарантировать, что пользователь не собьет отбор стандартными кнопками формы. Для этого в СКД предусмотрен механизм ФиксированныеНастройки.

Проанализируем правильную точку применения программных настроек. Устанавливать их в модуле формы (например, в процедуре ПриОткрытии) не рекомендуется, так как при формировании отчета регламентным заданием в фоновом режиме форма не создается вовсе. Корректное место — модуль объекта отчета, событие ПриКомпоновкеРезультата.

Посмотрим на пример кода в модуле объекта:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    СсылкаНаГруппу = Справочники.Номенклатура.НайтиПоКоду("000000123");
    
    // Устанавливаем значение в фиксированные параметры
    ПараметрНужнаяПапка = КомпоновщикНастроек.ФиксированныеНастройки.ПараметрыДанных.Элементы.Найти("НужнаяПапка");
    Если ПараметрНужнаяПапка <> Неопределено Тогда
        ПараметрНужнаяПапка.Значение = СсылкаНаГруппу;
        ПараметрНужнаяПапка.Использование = Истина;
    КонецЕсли;
    
КонецПроцедуры

Преимущество объекта ФиксированныеНастройки заключается в том, что установленные в нем параметры и отборы защищены платформой: они не видны в пользовательском интерфейсе и не сбрасываются при нажатии кнопки «Установить стандартные настройки».

Особенности производительности оператора В ИЕРАРХИИ

При использовании конструкции В ИЕРАРХИИ платформа 1С на уровне СУБД строит временную таблицу, куда рекурсивно собирает все вложенные элементы и подгруппы выбранного родительского узла. После этого выполняется операция соединения с целевой таблицей.

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

← На главную