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