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