Как установить отбор по группе номенклатуры или ее коду в системе компоновки данных (СКД)

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

При разработке отчетов на базе Системы компоновки данных (СКД) программисты часто сталкиваются с ограничением: конфигуратор не имеет прямого доступа к данным информационной базы. Это означает, что мы не можем просто нажать кнопку выбора в поле «Значение» настроек отбора и выбрать конкретную группу из справочника Номенклатура. Попытки обойти это через сохранение настроек в XML часто приводят к появлению нечитаемых GUID, что затрудняет поддержку отчета.

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

Способ 1. Использование выражений в параметрах (Поиск по коду или наименованию)

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

Для этого выполним следующие шаги:

  1. Перейдем на закладку Параметры в схеме компоновки данных.
  2. Добавим новый параметр, например, ГруппаНоменклатуры, и укажем тип СправочникСсылка.Номенклатура.
  3. В колонке Выражение напишем вызов функции поиска:

Пример выражения для поиска по коду:

Справочники.Номенклатура.НайтиПоКоду("000000001")

Пример выражения для поиска по наименованию:

Справочники.Номенклатура.НайтиПоНаименованию("Продукция")

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

Способ 2. Работа через параметры запроса и иерархию

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

Если мы хотим использовать отбор внутри текста запроса для повышения производительности, нам следует использовать конструкцию с параметром:


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

Рассмотрим подробнее: параметр &СписокГрупп может иметь тип Список значений. Это позволит нам передать сразу несколько родительских групп. Если же в некоторых частях отчета (например, в других детальных записях) нам нужна вся номенклатура без фильтра, мы можем использовать механизм необязательных условий компоновки данных (фигурные скобки).

Способ 3. Использование предопределенных элементов

Если структура справочника Номенклатура подразумевает наличие фиксированных групп (например, "Товары", "Услуги", "Материалы"), лучшим архитектурным решением будет создание предопределенных элементов в конфигураторе.

В этом случае в настройках СКД на закладке «Настройки» в поле «Правое значение» вы сможете выбрать этот элемент напрямую. 1С подсветит его специальной иконкой, и ссылка будет корректно работать во всех базах, где развернута данная конфигурация, независимо от GUID элементов.

Способ 4. Программная установка отбора в модуле отчета

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

Разберем пример кода в процедуре ПриКомпоновкеРезультата:


Процедура ПриКомпоновкеРезультата(ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь; // Отключаем стандартный вывод для управления процессом
    
    // 1. Находим нужную нам группу в базе по коду
    НужнаяГруппа = Справочники.Номенклатура.НайтиПоКоду("УТ-000012");
    
    Если Не НужнаяГруппа.Пустая() Тогда
        // 2. Получаем настройки компоновщика
        Настройки = КомпоновщикНастроек.ПолучитьНастройки();
        
        // 3. Ищем существующий отбор по полю "Номенклатура" или создаем новый
        ЭлементОтбора = Неопределено;
        Для Каждого Элемент Из Настройки.Отбор.Элементы Цикл
            Если Строка(Элемент.ЛевоеЗначение) = "Номенклатура" Тогда
                ЭлементОтбора = Элемент;
                Прервать;
            КонецЕсли;
        КонецЦикла;
        
        Если ЭлементОтбора = Неопределено Тогда
            ЭлементОтбора = Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
            ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Номенклатура");
        КонецЕсли;
        
        // 4. Устанавливаем параметры отбора
        ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВИерархии;
        ЭлементОтбора.ПравоеЗначение = НужнаяГруппа;
        ЭлементОтбора.Использование = Истина;
        
        // 5. Загружаем измененные настройки обратно
        КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);
    КонецЕсли;
    
    // Продолжаем формирование отчета с новыми настройками
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки);
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(Результат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);

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

Способ 5. Оптимизация через параметры виртуальных таблиц

Проанализируем важный аспект производительности. Если ваш отчет строится на данных виртуальных таблиц (например, ОстаткиИОбороты), установка отбора в общем списке настроек приведет к тому, что 1С сначала выберет все данные из базы, а потом отфильтрует их в памяти. Это крайне неэффективно для больших баз.

Для правильной работы:

  1. В конструкторе запроса перейдите на закладку Компоновка данных.
  2. В поле параметров виртуальной таблицы укажите условие для номенклатуры.
  3. В этом случае СКД сама подставит выбранную в настройках группу непосредственно в SQL-запрос к базе данных, что ускорит отчет в разы.

Способ 6. Фиксированные настройки (Fixed Settings)

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

Фиксированные настройки накладываются поверх пользовательских настроек по правилу "И". В пользовательском интерфейсе этот отбор даже не будет отображаться, что гарантирует сохранность логики отчета. Устанавливаются они аналогично программному методу, описанному выше, но через свойство ФиксированныеНастройки.

Способ 7. Вычисляемые поля для строкового поиска

Рассмотрим ситуацию, когда пользователю удобно вводить код группы текстом прямо в поле отбора. Мы можем создать Вычисляемое поле в СКД с выражением Номенклатура.Родитель.Код.

Назовем это поле "КодГруппы". Теперь пользователь может просто написать "005" в значении отбора, и система автоматически найдет всю номенклатуру, чей непосредственный родитель имеет такой код. Это избавляет от необходимости открывать диалог выбора справочника.

Подведем итог: Для разовых задач и быстрой настройки идеально подходит использование функций поиска в выражениях параметров (НайтиПоКоду). Для системных решений лучше использовать предопределенные элементы или программную установку в ПриКомпоновкеРезультата. Всегда помните о разнице между В группе (только первый уровень) и В иерархии (все уровни вложенности) для корректного отображения данных.

← На главную