К статье
Практический материал

Справочники и Данные · 11 мин

Как выбрать группу справочника в 1С

Как выбрать группу справочника в 1С: отбор по родителю в запросе, методы Выбрать и НайтиПоНаименованию, проверка ЭтоГруппа, типовые ошибки и примеры кода.

Группа справочника в 1С — это иерархический элемент, который объединяет другие элементы и сам не несёт прикладных данных. С ней работают иначе, чем с обычным элементом: у группы может не быть части реквизитов, её нельзя выбрать в документе как товар или контрагента, а выборки строятся через поле «Родитель» и признак «ЭтоГруппа».

Задача «выбрать группу справочника» встречается в трёх типовых сценариях: найти ссылку на конкретную группу по наименованию, получить список всех групп справочника, отобрать элементы, лежащие внутри заданной группы с учётом вложенности. Ниже разобраны все три подхода на встроенном языке и языке запросов, а также ограничения и частые ошибки.

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

Как устроена иерархия справочника и что такое группа

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

У каждого элемента и группы есть стандартный реквизит «Родитель» — ссылка на группу верхнего уровня. У элементов корня справочника родитель пустой. Признак «ЭтоГруппа» позволяет отличить папку от элемента в выборке: у групп он равен Истина.

Понимание этой структуры важно, потому что фильтр «по группе» всегда сводится к одному из двух условий: либо Родитель равен конкретной группе (только прямые потомки), либо элемент находится в иерархии группы (с учётом всех вложенных уровней).

Как найти группу по наименованию

Если известно имя группы, ссылку на неё получают методом НайтиПоНаименованию. У метода есть параметры, которые ограничивают поиск: точное соответствие наименования, родитель, внутри которого искать, и владелец (для подчинённых справочников).

ГруппаСсылка = Справочники.Номенклатура.НайтиПоНаименованию("Материалы", Истина);

Если Не ГруппаСсылка.Пустая() Тогда

Если ГруппаСсылка.ЭтоГруппа Тогда

// это действительно группа, можно работать

КонецЕсли;

КонецЕсли;

Второй параметр (Истина) требует точного совпадения наименования — без него поиск идёт по началу строки и может вернуть не ту группу. После поиска обязательно проверяйте два условия: ссылка не пустая и найденный объект действительно является группой, иначе код ниже получит элемент вместо папки.

Поиск по предопределённому имени

Если группа создана в конфигураторе как предопределённая, надёжнее всего обращаться к ней через менеджер справочника: Справочники.Номенклатура.ИмяГруппы. Такая ссылка не зависит от переименования в пользовательском режиме и не требует запроса к базе.

Как получить список всех групп справочника запросом

Когда нужны все группы — например, для заполнения списка выбора или дерева на форме — используют запрос с условием по признаку ЭтоГруппа. Это быстрее и нагляднее, чем перебор выборки с проверками в коде.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Номенклатура.Ссылка КАК Группа,

| Номенклатура.Наименование КАК Наименование,

| Номенклатура.Родитель КАК Родитель

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| Номенклатура.ЭтоГруппа

| И НЕ Номенклатура.ПометкаУдаления

|УПОРЯДОЧИТЬ ПО

| Номенклатура.Наименование ИЕРАРХИЯ";

Результат = Запрос.Выполнить().Выбрать();

Конструкция «УПОРЯДОЧИТЬ ПО ... ИЕРАРХИЯ» выдаёт группы в порядке дерева: сначала родитель, затем его подгруппы. Это удобно для вывода в дерево значений на форме. Условие на пометку удаления отсекает «мусорные» группы, которые ещё не удалены физически.

Порядок получения списка групп
  1. 1
    Сформируйте запрос к таблице справочника с условием ЭтоГруппа = Истина
  2. 2
    Добавьте отбор НЕ ПометкаУдаления, чтобы исключить помеченные
  3. 3
    Добавьте упорядочивание ИЕРАРХИЯ, если результат выводится деревом
  4. 4
    Выполните запрос и обойдите выборку или выгрузите в таблицу значений
  5. 5
    Проверьте результат на тестовой базе: количество групп должно совпадать со списком в пользовательском режиме

Как выбрать элементы внутри конкретной группы

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

Условие «Родитель = &Группа» вернёт только прямых потомков — элементы, лежащие непосредственно в этой папке. Элементы вложенных подгрупп в результат не попадут. Такой вариант подходит, когда нужно показать содержимое одной папки, как в проводнике.

Условие «Ссылка В ИЕРАРХИИ(&Группа)» вернёт элементы самой группы и всех её подгрупп любой глубины. Именно этот вариант обычно нужен в отчётах и обработках: «вся номенклатура группы Материалы».

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Номенклатура.Ссылка КАК Ссылка,

| Номенклатура.Наименование КАК Наименование

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| Номенклатура.Ссылка В ИЕРАРХИИ(&Группа)

| И НЕ Номенклатура.ЭтоГруппа";

Запрос.УстановитьПараметр("Группа", ГруппаСсылка);

Сравнение условий отбора

Родитель = &Группа

Только прямые потомки группы. Быстрый запрос, но вложенные подгруппы игнорируются.

Ссылка В ИЕРАРХИИ(&Группа)

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

Родитель В (&СписокГрупп)

Отбор по нескольким группам верхнего уровня, когда иерархия не нужна, а список папок известен заранее.

Выборка групп методом Выбрать без запроса

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

Выборка = Справочники.Номенклатура.Выбрать(ГруппаСсылка);

Пока Выборка.Следующий() Цикл

Если Выборка.ЭтоГруппа Тогда

Продолжить; // пропускаем подгруппы

КонецЕсли;

// работа с элементом: Выборка.Наименование, Выборка.Код

КонецЦикла;

Метод Выбрать возвращает только прямых потомков указанного родителя — аналог условия «Родитель = &Группа». Для обхода всей ветки с подгруппами потребуется рекурсия: при обнаружении группы вызывать ту же процедуру с этой группой в качестве родителя.

bsl
Выборка = Справочники.Номенклатура.Выбрать(ГруппаСсылка);
Пока Выборка.Следующий() Цикл
    Если Не Выборка.ЭтоГруппа Тогда
        Сообщить(Выборка.Наименование);
    КонецЕсли;
КонецЦикла;

Учтите, что Выбрать с отбором по родителю выполняется на сервере, и в управляемом приложении код должен располагаться в серверной процедуре (директива &НаСервере) или в общем модуле с признаком «Сервер».

Как программно ограничить выбор группы в поле ввода

Отдельный сценарий — дать пользователю выбрать именно группу (или наоборот, запретить выбор групп) в поле на форме. Для этого у элемента формы настраивают «Параметры выбора» или «Отбор» динамического списка.

Чтобы в поле можно было выбирать только группы, добавьте параметр выбора с отбором ЭтоГруппа = Истина. Чтобы запретить группы — установите свойство «Выбор групп и элементов» у поля ввода в значение «Элементы» (в обычных формах) или добавьте отбор ЭтоГруппа = Ложь в управляемой форме.

// Разрешить выбор только групп в поле формы

ПараметрВыбора = Новый ПараметрВыбора("Отбор.ЭтоГруппа", Истина);

МассивПараметров = Новый Массив;

МассивПараметров.Добавить(ПараметрВыбора);

Элементы.ГруппаТоваров.ПараметрыВыбора = Новый ФиксированныйМассив(МассивПараметров);

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

Типичные ошибки и проверка результата

Типичные ошибки
01
Использование Родитель = &Группа вместо В ИЕРАРХИИ — элементы вложенных подгрупп молча выпадают из отчёта
02
Отсутствие проверки ЭтоГруппа после НайтиПоНаименованию — в переменную попадает обычный элемент с таким же именем
03
Поиск группы по наименованию без учёта дублей — выбирается первая найденная группа из другой ветки
04
Игнорирование пометки удаления — в выборку попадают удалённые группы и ломают итоги
05
Вызов Выбрать или запроса в клиентской процедуре управляемой формы — ошибка компиляции или падение при выполнении

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

Контрольные точки

Как проверить результат

Ссылка на группу получена
Норма

Ссылка не пустая, ЭтоГруппа = Истина

Тревожный признак

Пустая ссылка или найден обычный элемент

Состав выборки по группе
Норма

Количество элементов совпадает с содержимым папки и подпапок в пользовательском режиме

Тревожный признак

Элементов меньше — вероятно, использовано Родитель = вместо В ИЕРАРХИИ

Поле выбора на форме
Норма

В списке выбора видны только группы (или только элементы) согласно настройке

Тревожный признак

Группы доступны для выбора там, где должны быть запрещены

FAQ

Как проверить, является ли ссылка группой?

Обратитесь к свойству ЭтоГруппа ссылки: Если Ссылка.ЭтоГруппа Тогда. В запросе используйте условие ГДЕ Справочник.ЭтоГруппа. Свойство доступно и на клиенте, поскольку это данные самой ссылки, а не объекта.

Как выбрать группы только верхнего уровня?

Добавьте в запрос два условия: ЭтоГруппа = Истина и Родитель = &ПустаяСсылка, передав в параметр пустую ссылку справочника (Справочники.Номенклатура.ПустаяСсылка()). Получите список корневых папок.

Почему В ИЕРАРХИИ не возвращает элементы?

Чаще всего в параметр передана пустая ссылка или элемент вместо группы. Проверьте, что параметр содержит именно ссылку на группу. Также убедитесь, что справочник иерархический с видом иерархии «Группы и элементы» — иначе конструкция ведёт себя иначе.

Можно ли найти группу по коду?

Да, методом Справочники.Имя.НайтиПоКоду("000000123"). Но коды групп и элементов нумеруются в одной серии, поэтому после поиска обязательно проверяйте ЭтоГруппа. Для предопределённых групп надёжнее обращение по имени через менеджер справочника.

Как перенести элемент в другую группу программно?

Получите объект элемента методом Ссылка.ПолучитьОбъект(), присвойте свойству Родитель ссылку на новую группу и вызовите Записать(). Перед массовым переносом сделайте копию базы и проверьте, не используется ли иерархия в настройках прав доступа и отчётов.

Чем отличается ВыбратьИерархически от Выбрать?

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

Итог

Что важно запомнить

Группу находят по наименованию с проверкой ЭтоГруппа, список групп получают запросом с условием ЭтоГруппа = Истина, а элементы внутри группы отбирают через В ИЕРАРХИИ — условие Родитель = даёт только прямых потомков. Результат всегда сверяйте с содержимым папки в пользовательском режиме.