Как программно вывести иерархию справочника в табличный документ 1С

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При разработке отчетов и печатных форм в 1С часто возникает задача вывести структуры данных (например, справочники подразделений, номенклатуры или статей затрат) с сохранением их родительской иерархии и группировкой строк в табличном документе. Разберем, как правильно составить запрос, настроить выборку и реализовать автогруппировку строк.

Основные механизмы вывода иерархических структур

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

  1. Конструкция УПОРЯДОЧИТЬ ПО ... ИЕРАРХИЯ или ИТОГИ ПО ... ИЕРАРХИЯ в запросе: позволяет упорядочить записи или построить древовидные итоги с учетом уровня вложенности родителей.
  2. Метод Выборка.Уровень(): возвращает числовой уровень текущей записи в иерархическом дереве (0 для верхнего уровня, 1 для подчиненных групп и т. д.).
  3. Методы табличного документа НачатьАвтогруппировкуСтрок() и ЗакончитьАвтогруппировкуСтрок(): автоматически создают элементы интерфейса для сворачивания и разворачивания подчиненных уровней.
  4. Метод ТабличныйДокумент.Вывести(Область, Уровень): принимает второй параметр — уровень группировки, благодаря которому строка помещается в соответствующий уровень структуры.

Использование конструктора запроса с обработкой результата

Самый простой и быстрый способ сгенерировать готовый каркас кода для вывода иерархического справочника — воспользоваться встроенным конструктором запроса с обработкой результата.

Разберем пошагово процесс получения кода для вывода справочника Подразделения:

  1. Откроем модуль формы или объекта и через контекстное меню вызовем Конструктор запроса с обработкой результата.
  2. Выберем нужный справочник и его поля (например, Наименование или Ссылка).
  3. На вкладке Порядок укажем сортировку УПОРЯДОЧИТЬ ПО Наименование ИЕРАРХИЯ (или по полю Ссылка).
  4. На вкладке Обработка результата выберем вывод в табличный документ с автогруппировкой.

В результате конструктор сформирует следующий компактный и рабочий код:


Процедура СформироватьОтчет()

    Макет = ПолучитьМакет("Макет");
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |    Подразделения.Наименование КАК Наименование
        |ИЗ
        |    Справочник.Подразделения КАК Подразделения
        |
        |УПОРЯДОЧИТЬ ПО
        |    Наименование ИЕРАРХИЯ";
    
    РезультатЗапроса = Запрос.Выполнить();
    
    ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
    ОбластьШапкаТаблицы = Макет.ПолучитьОбласть("ШапкаТаблицы");
    ОбластьДетальныхЗаписей = Макет.ПолучитьОбласть("Детали");
    
    ТабДок = ЭлементыФормы.ПолеОтчета;
    ТабДок.Очистить();
    ТабДок.Вывести(ОбластьЗаголовок);
    ТабДок.Вывести(ОбластьШапкаТаблицы);
    
    // Включаем механизм группировки строк
    ТабДок.НачатьАвтогруппировкуСтрок();
    
    ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
    
    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
        ОбластьДетальныхЗаписей.Параметры.Заполнить(ВыборкаДетальныеЗаписи);
        // Выводим область с передачей текущего уровня иерархии
        ТабДок.Вывести(ОбластьДетальныхЗаписей, ВыборкаДетальныеЗаписи.Уровень());
    КонецЦикла;
    
    // Завершаем формирование группировок
    ТабДок.ЗакончитьАвтогруппировкуСтрок();

КонецПроцедуры

Вывод подчиненных детальных записей (например, сотрудников)

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

В таких случаях рекомендуется использовать предложение ИТОГИ ПО с явным указанием иерархии:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |    Соответствие.Подразделение КАК Подразделение,
    |    Работники.Сотрудник КАК Сотрудник
    |ИЗ
    |    РегистрСведений.РаботникиОрганизаций.СрезПоследних КАК Работники
    |    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СоответствиеПодразделений КАК Соответствие
    |    ПО Работники.ПодразделениеОрганизации = Соответствие.ПодразделениеОрганизации
    |ГДЕ
    |    Работники.ПричинаИзмененияСостояния <> ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.Увольнение)
    |
    |ИТОГИ ПО
    |    Подразделение ИЕРАРХИЯ";

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


Результат = Запрос.Выполнить();
ТабДок.НачатьАвтогруппировкуСтрок();

ВыборкаПодразделения = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);

Пока ВыборкаПодразделения.Следующий() Цикл
    // Выводим родительские группы и подразделения
    ОбластьГруппа.Параметры.Заполнить(ВыборкаПодразделения);
    ТабДок.Вывести(ОбластьГруппа, ВыборкаПодразделения.Уровень());
    
    // Получаем детальные записи сотрудников для текущего подразделения
    ВыборкаДетали = ВыборкаПодразделения.Выбрать();
    Пока ВыборкаДетали.Следующий() Цикл
        Если ЗначениеЗаполнено(ВыборкаДетали.Сотрудник) Тогда
            ОбластьСтрока.Параметры.Заполнить(ВыборкаДетали);
            ТабДок.Вывести(ОбластьСтрока, ВыборкаДетали.Уровень());
        КонецЕсли;
    КонецЦикла;
КонецЦикла;

ТабДок.ЗакончитьАвтогруппировкуСтрок();

Типичные ошибки при работе с иерархическими выборками

  1. Путаница между УПОРЯДОЧИТЬ ПО ИЕРАРХИЯ и ИТОГИ ПО ИЕРАРХИЯ: Конструкция УПОРЯДОЧИТЬ ПО дает плоскую выборку, отсортированную в порядке иерархии, а ИТОГИ ПО создает узлы группировок для каждого уровня иерархии.
  2. Непоследовательно передаваемый уровень: Если при вызове метода Вывести() пропускать значения уровней (например, передать уровень 0, а затем сразу уровень 3), автогруппировка строк может отображаться некорректно.
  3. Потеря родительских групп при соединениях таблиц: При использовании левых или внутренних соединений с детальными таблицами родительские папки справочника, не содержащие напрямую записей, отсекаются. Секция ИТОГИ ПО ... ИЕРАРХИЯ позволяет восстановить полную структуру дерева каталогов.
← На главную