При работе с иерархическими справочниками в 1С, такими как Номенклатура или АналогиНоменклатуры, программисты часто сталкиваются с необходимостью выбрать все элементы, входящие в конкретную папку (группу). Несмотря на кажущуюся простоту, здесь есть несколько подводных камней: от логических различий в операторах запроса до технических ограничений инструментов тестирования, таких как Консоль запросов. В этой статье мы подробно разберем, как правильно строить такие запросы и что делать, если консоль не позволяет выбрать группу в качестве параметра.
Первым делом проанализируем, какой оператор лучше использовать для решения задачи. Рассмотрим два основных подхода к фильтрации по папке:
Если мы напишем условие ГДЕ Номенклатура.Родитель = &Родитель, система вернет только те элементы, которые находятся непосредственно «внутри» указанной папки на первом уровне вложенности. Если в этой папке есть другие подпапки, элементы из них в результат запроса не попадут.
Оператор В ИЕРАРХИИ выполняет рекурсивный поиск. Это означает, что запрос выберет элементы из указанной группы, а также из всех её подпапок на любую глубину вложенности. Для большинства бизнес-задач (например, получение остатков по категории товара) следует использовать именно этот вариант.
Посмотрим на пример правильного построения запроса с использованием иерархии:
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка,
Номенклатура.Наименование КАК Наименование
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.Ссылка В ИЕРАРХИИ(&ГруппаПоиска)
И НЕ Номенклатура.ЭтоГруппа
Разберем важный нюанс: когда мы используем оператор В ИЕРАРХИИ, сама группа (папка), переданная в параметр &ГруппаПоиска, также попадает в результат запроса, так как она формально соответствует условию вхождения в саму себя. Чтобы в списке остались только конечные карточки товаров (элементы), мы добавляем условие ГДЕ НЕ Номенклатура.ЭтоГруппа. Это гарантирует, что в отчет или выборку не попадут пустые строки заголовков групп.
Часто при тестировании запроса в консоли возникает ситуация: вы создали параметр &Родитель, указали тип СправочникСсылка.Номенклатура, но при попытке выбрать значение система открывает список и позволяет нажать только на конечный элемент, игнорируя папки. Выясним причину: это происходит из-за настройки ВыборГруппИЭлементов в форме выбора справочника.
Проанализируем несколько способов решения этой проблемы:
В современных консолях запросов в таблице параметров часто есть колонка «Выражение». Вместо интерактивного выбора ссылки можно написать код на языке 1С, который найдет нужную группу. Например:
Справочники.Номенклатура.НайтиПоКоду("АА-00045976")
После нажатия Enter система сама вычислит ссылку на папку и подставит её в параметр.
Попробуйте просто скопировать код или наименование группы и вставить его непосредственно в поле значения параметра в консоли, затем нажмите Enter. Во многих типовых формах реализован поиск по строке, который может «подтянуть» группу даже при запрете интерактивного выбора.
Если вы часто пользуетесь конкретной обработкой «Консоль запросов» и она ограничивает ваш выбор, можно изменить её форму. Для этого откроем обработку в Конфигураторе, найдем поле, отвечающее за значение параметра, и в свойствах (или в коде при создании параметров) установим значение свойства ВыборГруппИЭлементов в положение Группы и элементы. Это радикальный, но самый удобный способ для разработчика.
Рассмотрим ситуацию, когда вам нужно получить данные не просто из справочника, а из регистра (например, остатки товаров в разрезе группы). Проанализируем типичную ошибку: ставить условие В ИЕРАРХИИ в секции ГДЕ основного запроса. Это замедляет работу, так как система сначала выберет ВСЕ остатки по всем товарам, а потом начнет их фильтровать.
Правильнее передавать условие в параметры виртуальной таблицы. Это выглядит следующим образом:
ВЫБРАТЬ
ТоварыНаСкладахОстатки.Номенклатура,
ТоварыНаСкладахОстатки.В НаличииОстаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(, Номенклатура В ИЕРАРХИИ (&Группа)) КАК ТоварыНаСкладахОстатки
В этом случае СУБД (SQL) получит уже отфильтрованный набор данных, что значительно повысит производительность на больших базах данных.
Если ваша задача — не просто получить плоский список, а увидеть структуру папок в самом результате запроса (как в дереве), нам поможет конструкция ИТОГИ. Выясним, как это работает:
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка,
Сумма(Остаток) КАК Количество
ИЗ
...
СГРУППИРОВАТЬ ПО
Номенклатура.Ссылка
ИТОГИ
Сумма(Количество)
ПО
Номенклатура ИЕРАРХИЯ
Использование ключевого слова ИЕРАРХИЯ после ПО в секции итогов заставляет 1С автоматически добавлять в результат строки-родители для каждого элемента. Это очень удобно для построения иерархических отчетов, где суммы должны суммироваться «вверх» по дереву справочника.
Напоследок проанализируем типы иерархии справочников. В 1С их два:
1. Иерархия групп и элементов — стандартные папки. 2. Иерархия элементов — когда один элемент может быть «родителем» для другого (например, в справочнике подразделений или сотрудников).
Хорошая новость заключается в том, что оператор В ИЕРАРХИИ универсален. Он одинаково эффективно отрабатывает оба случая. Если вы программируете универсальный алгоритм, всегда отдавайте предпочтение В ИЕРАРХИИ, чтобы ваш код корректно работал при изменении структуры метаданных справочника.
Таким образом, мы выяснили, что для успешного получения элементов группы необходимо использовать оператор В ИЕРАРХИИ, не забывать про фильтр ЭтоГруппа и уметь обходить ограничения интерфейса консоли через программный поиск или настройку свойств формы.