Примеры запросов для работы с иерархическими справочниками 

В данном разделе показаны примеры решения типовых задач при работе с иерархическими справочниками.

Получение элементов иерархического справочника, находящихся в подчинении заданной группы

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

Копировать в буфер обмена

ВЫБРАТЬ
    Номенклатура.Код,
    Номенклатура.Наименование КАК Наименование,
    Номенклатура.ЗакупочнаяЦена 
ИЗ
    Справочник.Номенклатура КАК Номенклатура

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

В данном примере будут получены все записи справочника Номенклатура, находящиеся в группе &Группа, включая ее саму, ее подчиненные группы и элементы, принадлежащие подчиненным группам.

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

Копировать в буфер обмена

ВЫБРАТЬ
    Номенклатура.Код,
    Номенклатура.Наименование КАК Наименование,
    Номенклатура.ЗакупочнаяЦена 
ИЗ
    Справочник.Номенклатура КАК Номенклатура

ГДЕ
    Номенклатура.Родитель = &Группа

Такой запрос выберет группы и элементы, находящиеся в подчинении группы со ссылкой &Группа.

Проверка наличия подчиненных элементов у элемента справочника

Для проверки наличия подчиненных записей элемента справочника можно пользоваться запросом, аналогичным представленному:

Копировать в буфер обмена

ВЫБРАТЬ ПЕРВЫЕ 1
    Номенклатура.Ссылка
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.Родитель = &Родитель

В данном примере ссылка элемента, для которого необходимо проверить наличие дочерних элементов, записывается в параметр запроса "Родитель". После выполнения такого запроса необходимо проверить результат на пустоту. Если результат не пустой, то подчиненные записи есть. Иначе - нет. Пример:

Копировать в буфер обмена

Если Запрос.Выполнить().Пустой() Тогда
    Сообщить("Зписей нет");
Иначе 
    Сообщить("Записи есть");
КонецЕсли;

Получение всех родителей элемента

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

Пример:

Копировать в буфер обмена

ТекущийЭлементНоменклатуры = ЭлементНоменклатура;

Запрос = Новый Запрос("ВЫБРАТЬ 
                      | Номенклатура.Родитель, 
                      | Номенклатура.Родитель.Родитель, 
                      | Номенклатура.Родитель.Родитель.Родитель, 
                      | Номенклатура.Родитель.Родитель.Родитель.Родитель, 
                      | Номенклатура.Родитель.Родитель.Родитель.Родитель.Родитель 
                      |ИЗ 
                      | Справочник.Номенклатура КАК Номенклатура 
                      |
                      |ГДЕ 
                      | Номенклатура.Ссылка = &ТекущийЭлементНоменклатуры";

Пока Истина Цикл
    Запрос.УстановитьПараметр("ТекущийЭлементНоменклатуры", ТекущийЭлементНоменклатуры); 
    Результат = Запрос.Выполнить(); 
    Если Результат.Пустой() Тогда 
        Прервать; 
    КонецЕсли; 
    Выборка = Результат.Выбрать(); 
    Выборка.Следующий(); 
    Для НомерКолонки = 0 По Результат.Колонки.Количество() - 1 Цикл 
        ТекущийЭлементНоменклатуры = Выборка[НомерКолонки]; 
        Если ТекущийЭлементНоменклатуры = Справочники.Номенклатура.ПустаяСсылка() Тогда 
            Прервать; 
        Иначе 
            Сообщить(ТекущийЭлементНоменклатуры); 
        КонецЕсли; 
    КонецЦикла; 

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

В данном примере в окно служебных сообщений выводятся все родители для ссылки, записанной в переменную ЭлементНоменклатура. В цикле выбирается по 5 родителей ссылки.

Если число уровней в справочнике ограничено и невелико, то возможно получение всех родителей одним запросом без цикла.

Вывод иерархического справочника в отчет

Для вывода иерархического справочника в отчет с сохранением иерархии необходимо пользоваться запросом аналогичным следующему:

Копировать в буфер обмена

ВЫБРАТЬ
    Номенклатура.Код,
    Номенклатура.Наименование КАК Наименование,
    Номенклатура.ЗакупочнаяЦена 
ИЗ
    Справочник.Номенклатура КАК Номенклатура 
УПОРЯДОЧИТЬ ПО
    Наименование ИЕРАРХИЯ

Данный запрос выбирает все  записи из справочника и производит упорядочивание по иерархии. Результат будет упорядочен по наименованию, с учетом иерархии.

Для того чтобы группы справочника размещались выше элементов необходимо в данном запросе заменить предложение УПОРЯДОЧИТЬ ПО на следующее:

Копировать в буфер обмена

УПОРЯДОЧИТЬ ПО
    Номенклатура.ЭтоГруппа ИЕРАРХИЯ,
    Наименование

Результат по-прежнему будет упорядочен по иерархии, однако группы будут располагаться выше элементов.

Возможна также замена предложения УПОРЯДОЧИТЬ ПО на предложение АВТОУПОРЯДОЧИВАНИЕ. В этом случае результат будет упорядочен в соответствии с настройками справочника, т.е. если в справочнике указано, что группы должны располагаться выше элементов, то они будут расположены выше.

Получить иерархическую структуру справочника также возможно и при помощи итогов.

Пример:

Копировать в буфер обмена

ВЫБРАТЬ
    Номенклатура.Код, 
    Номенклатура.Наименование КАК Наименование, 
    Номенклатура.ЗакупочнаяЦена

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

ГДЕ 
    (Номенклатура.ЭтоГруппа = ЛОЖЬ)

УПОРЯДОЧИТЬ ПО Наименование

ИТОГИ ПО Номенклатура.Ссылка ТОЛЬКО ИЕРАРХИЯ

Получение итогов по иерархии

Для получения итогов по иерархии в запросе необходимо в предложении ИТОГИ ПО указать ключевое слово ИЕРАРХИЯ после указания поля, по которому будет рассчитываться итоги. Пример отчета "Обороты номенклатуры" с получением итогов по иерархии:

Копировать в буфер обмена

ВЫБРАТЬ
    УчетНоменклатурыОбороты.Номенклатура КАК Номенклатура,
    УчетНоменклатурыОбороты.Номенклатура.Представление,
    УчетНоменклатурыОбороты.КоличествоОборот КАК КоличествоОборот
ИЗ
    РегистрНакопления.УчетНоменклатуры.Обороты КАК УчетНоменклатурыОбороты
ИТОГИ СУММА(КоличествоОборот) ПО
   Номенклатура ИЕРАРХИЯ

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

В случае, когда не нужны итоги по элементам, а нужны итоги только по группам, нам необходимо использовать в итогах конструкцию ТОЛЬКО ИЕРАРХИЯ. Пример:

Копировать в буфер обмена

ВЫБРАТЬ
    УчетНоменклатурыОбороты.Номенклатура КАК Номенклатура,
    УчетНоменклатурыОбороты.Номенклатура.Представление,
    УчетНоменклатурыОбороты.КоличествоОборот КАК КоличествоОборот
ИЗ
    РегистрНакопления.УчетНоменклатуры.Обороты КАК УчетНоменклатурыОбороты
ИТОГИ СУММА(КоличествоОборот) ПО
   Номенклатура ТОЛЬКО ИЕРАРХИЯ

В результате данного запроса будут итоговые записи только для групп номенклатуры.