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