Как настроить отбор в СКД по группе и отдельному элементу справочника?

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

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

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

Анализ логики работы условия «В группе» («В ИЕРАРХИИ»)

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

  1. Если передана группа (папка): платформа выбирает саму группу, а также все подчиненные подгруппы и конечные элементы любого уровня вложенности.
  2. Если передан конечный элемент: платформа воспринимает его как единичный узел собственной иерархии. Запрос отрабатывает точно так же, как при условии Равно, возвращая только этот конкретный элемент.

Таким образом, само по себе условие В группе закрывает обе потребности без изменения типа сравнения. Возникает вопрос: почему же пользователь получает ошибку при попытке выбрать группу в поле отбора?

Выясняем причину ошибки «Выберите элемент, а не группу!»

Данная ошибка вызвана не ограничениями механизма СКД, а поведением элементов формы пользовательского интерфейса. В платформе «1С:Предприятие» у каждого ссылочного поля ввода и у параметров выбора существует свойство ВыборГруппИЭлементов. По умолчанию для полей справочников оно часто принимает значение Элементы или рассчитывается автоматически (Авто), разрешая выбирать только конечные элементы (не папки). При попытке подтвердить выбор группы форма блокирует действие и выдает сообщение об ошибке.

Рассмотрим подробнее проверенные способы решения этой задачи.

Способ 1. Настройка свойства элемента формы отчета

Если в вашем отчете используется собственная форма, настроить поведение поля выбора проще всего на уровне интерфейса формы:

  1. Откроем форму отчета в конфигураторе.
  2. Найдем элемент формы, отвечающий за ввод отбора или параметра (например, поле быстрых пользовательских настроек компоновщика).
  3. В палитре свойств найдем строку Выбор групп и элементов (ВыборГруппИЭлементов).
  4. Установим значение в Группы и элементы.

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

Способ 2. Оформление отбора через расширение языка запросов СКД

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

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


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

Конструкция {ГДЕ Поле.*} указывает СКД, что для поля Контрагент доступны все стандартные операции фильтрации, включая иерархические. В настройках отчета (на вкладке «Настройки» схемы компоновки) разработчик задает отбор по полю Контрагент с видом сравнения В группе и выносит его в «Быстрый доступ» (пользовательские настройки). Платформа применит режим выбора, разрешающий указывать и группы, и элементы.

Способ 3. Передача параметра с явным указанием параметров выбора

Если фильтрация реализована не через стандартные отборы СКД, а через параметр данных запроса вида Контрагент В ИЕРАРХИИ (&Контрагент), настроим доступность групп на вкладке параметров схемы:

  1. Перейдем на вкладку «Параметры» в схеме компоновки данных.
  2. Выберем параметр Контрагент.
  3. В колонке «Параметры выбора» добавим строку: укажем имя параметра ВыборГруппИЭлементов и зададим ему значение Группы и элементы (объект ИспользованиеГруппИЭлементов.ГруппыИЭлементы).
  4. Включим флаг «Ограничение доступности» при необходимости или вынесем параметр в пользовательские настройки.

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

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


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

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

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

Важные нюансы производительности

Обратим внимание на особенности работы с условием В ИЕРАРХИИ на уровне СУБД:

  1. Пустые ссылки: никогда не передавайте незаполненную или пустую ссылку в жесткое условие запроса В ИЕРАРХИИ (&Параметр) без проверки. Если параметр пуст, платформа попытается выполнить поиск принадлежности ко всему дереву таблицы, что вызовет полное сканирование (Table Scan) и критическое падение производительности. Условие всегда должно быть опциональным (заключенным в фигурные скобки {} СКД).
  2. Скорость выполнения: проверка В ИЕРАРХИИ создает временную таблицу с иерархическим деревом узлов. Прямое сравнение Равно по конечному элементу выполняется по индексу быстрее. Если в отчете предполагается частая выборка именно единичных элементов, программная подмена вида сравнения (Способ 4) снизит нагрузку на сервер баз данных.
← На главную