При работе со справочниками, имеющими иерархическую структуру (например, Контрагенты или Номенклатура), часто возникает задача ограничить выборку данных определенной группой. Это может потребоваться как в отчетах, так и в формах выбора или при программной обработке данных. В рамках данной статьи мы подробно разберем все способы реализации такого отбора, начиная от простых запросов и заканчивая настройкой динамических списков и параметров выбора в управляемых формах.
Рассмотрим самый распространенный сценарий: нам необходимо получить из базы данных все элементы, которые входят в конкретную папку, включая элементы во вложенных подпапках. Для этого в языке запросов 1С предусмотрен специальный оператор В ИЕРАРХИИ (в английской версии IN HIERARCHY).
Проанализируем пример кода запроса, который выбирает всех контрагентов из определенной группы:
ВЫБРАТЬ
Контрагенты.Ссылка КАК Контрагент,
Контрагенты.Наименование КАК Наименование
ИЗ
Справочник.Контрагенты КАК Контрагенты
ГДЕ
Контрагенты.Ссылка В ИЕРАРХИИ(&ЦелеваяГруппа)
И НЕ Контрагенты.ЭтоГруппа
Разберем, что происходит в этом запросе. Оператор В ИЕРАРХИИ автоматически проверяет всю цепочку родителей для каждого элемента. Если в иерархии выше по дереву встречается ссылка, переданная в параметр &ЦелеваяГруппа, элемент попадает в результат. Обратите внимание на условие НЕ Контрагенты.ЭтоГруппа. Мы добавили его для того, чтобы в выборку попали только конечные элементы (карточки), исключая сами папки. Если вам нужны и вложенные группы тоже, это условие можно опустить.
Если задача стоит проще — например, нужно, чтобы в поле ввода на форме при нажатии кнопки выбора открывался справочник с уже установленным фильтром по папке, мы можем воспользоваться свойствами конфигуратора. Выясним, как это сделать без написания кода.
Контрагент в документе).Отбор.Родитель, а в колонке "Значение" выберем конкретную группу из справочника.Важное ограничение: использование Отбор.Родитель в параметрах выбора работает только для первого уровня вложенности. Если в вашей целевой группе есть подпапки, элементы из них не будут видны при таком фильтре. Для полноценного отбора "в иерархии" при интерактивном выборе потребуется программная установка настроек.
Рассмотрим ситуацию, когда нам нужно жестко ограничить выбор пользователя в управляемом приложении, используя механизм ФиксированныеНастройки. Это гарантирует, что пользователь не сможет отключить отбор или выйти "выше" по иерархии. Проанализируем реализацию через событие НачалоВыбора:
&НаКлиенте
Процедура КонтрагентНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ПараметрыФормы = Новый Структура;
// Создаем фиксированные настройки компоновки данных
НастройкиКД = Новый НастройкиКомпоновкиДанных;
ОтборКД = НастройкиКД.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ОтборКД.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Ссылка");
ОтборКД.ВидСравнения = ВидСравненияКомпоновкиДанных.ВИерархии;
ОтборКД.ПравоеЗначение = Объект.НужнаяГруппа; // Ссылка на папку
ОтборКД.Использование = Истина;
ПараметрыФормы.Вставить("ФиксированныеНастройки", НастройкиКД);
ОткрытьФорму("Справочник.Контрагенты.ФормаВыбора", ПараметрыФормы, Элемент);
КонецПроцедуры
В данном примере мы отменяем стандартное открытие формы и вызываем её вручную, передавая структуру ФиксированныеНастройки. Ключевым моментом здесь является установка ВидСравнения.ВИерархии для поля Ссылка. Это наиболее надежный способ реализации подбора из конкретной ветки справочника.
Зачастую требуется настроить отбор непосредственно в форме списка справочника, чтобы пользователь видел только данные определенного сегмента. Выясним, как программно изменить отбор в динамическом списке, который уже выведен на экран.
Для этого мы обращаемся к свойству КомпоновщикНастроек нашего списка. Посмотрим на пример кода:
&НаСервере
Процедура УстановитьОтборПоГруппеНаСервере(СсылкаНаГруппу)
// Очищаем существующие отборы по полю Ссылка, если они были
Для Каждого ЭлементОтбора Из Список.КомпоновщикНастроек.Настройки.Отбор.Элементы Цикл
Если Строка(ЭлементОтбора.ЛевоеЗначение) = "Ссылка" Тогда
Список.КомпоновщикНастроек.Настройки.Отбор.Элементы.Удалить(ЭлементОтбора);
КонецЕсли;
КонецЦикла;
// Добавляем новый отбор в иерархии
НовыйОтбор = Список.КомпоновщикНастроек.Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
НовыйОтбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Ссылка");
НовыйОтбор.ВидСравнения = ВидСравненияКомпоновкиДанных.ВИерархии;
НовыйОтбор.ПравоеЗначение = СсылкаНаГруппу;
НовыйОтбор.Использование = Истина;
КонецПроцедуры
Этот метод позволяет гибко управлять видимостью элементов в форме в зависимости от контекста работы пользователя (например, при переключении каких-либо фильтров на панели формы).
При разработке отчетов в СКД механизм иерархии работает наиболее прозрачно для пользователя. Разберем основные моменты:
Если же вы хотите ограничить доступные для выбора группы еще на этапе разработки схемы, вы можете установить условие в тексте запроса набора данных, используя уже знакомый нам синтаксис ГДЕ Ссылка В ИЕРАРХИИ(&ПараметрГруппа).
Напоследок проанализируем ситуацию, когда пользователь должен иметь возможность выбирать в реквизит именно элементы, находящиеся внутри группы, но не саму группу. За это отвечает свойство реквизита Выбор групп и элементов.
Если установить значение Элементы, то даже если форма выбора откроется на нужной группе, пользователь не сможет выбрать саму папку двойным кликом — система заставит его "провалиться" внутрь и выбрать конкретную карточку. Если же установлено Группы и элементы, то папка может быть выбрана как самостоятельное значение. Всегда проверяйте это свойство при настройке фильтрации по иерархии, чтобы избежать логических ошибок в данных.
Таким образом, мы рассмотрели комплексный подход к реализации отбора по группе. Выбор конкретного метода зависит от вашей архитектурной задачи: для простого ограничения в форме достаточно Параметров выбора, для сложных условий — программной настройки Компоновщика или Запроса.