При разработке отчетов или обработок в 1С часто возникает задача визуального представления данных в виде иерархического списка. Например, у нас есть список договоров, и мы хотим, чтобы пользователь видел контрагента как «родительский» элемент, а при раскрытии списка — все его договоры. Часто начинающие разработчики пытаются решить эту задачу средствами языка запросов, используя конструкции ИТОГИ ПО, однако есть более гибкий и профессиональный подход, позволяющий добиться желаемого поведения интерфейса без усложнения кода запроса.
Когда мы пытаемся получить иерархию прямо из запроса, мы ограничиваем гибкость отображения данных. Запрос должен заниматься исключительно выборкой необходимых данных из базы, а их визуальное представление — задача уровня формы и объекта ДеревоЗначений. Если вы используете ИТОГИ ПО в запросе, вы получаете «плоский» результат с итоговыми записями, что не всегда удобно при программной обработке данных в модуле формы. Вместо этого рассмотрим использование структуры, специально предназначенной для иерархии.
Наиболее правильным и удобным способом решения задачи «Контрагент -> Список его договоров» является использование элемента управления ДеревоЗначений. Давайте разберем по шагам, как это реализовать на практике.
РезультатДерево) и установите ему тип ДеревоЗначений.РезультатДерево из списка реквизитов на форму обработки. Платформа 1С автоматически создаст элемент управления «Таблица», который поддерживает иерархическое отображение данных.После того как структура готова, необходимо программно заполнить дерево данными, полученными из запроса. Рассмотрим пример, как это сделать максимально эффективно:
// Предположим, запрос уже выполнен и результат находится в переменной РезультатЗапроса
ВыборкаДетальныхЗаписей = РезультатЗапроса.Выбрать();
// Очищаем дерево перед заполнением
РезультатДерево.Строки.Очистить();
Пока ВыборкаДетальныхЗаписей.Следующий() Цикл
// Ищем строку контрагента (владельца)
СтрокаКонтрагента = РезультатДерево.Строки.Найти(ВыборкаДетальныхЗаписей.Владелец, "Наименование", Истина);
Если СтрокаКонтрагента = Неопределено Тогда
// Создаем новую строку контрагента, если её еще нет
СтрокаКонтрагента = РезультатДерево.Строки.Добавить();
СтрокаКонтрагента.Наименование = ВыборкаДетальныхЗаписей.Владелец;
КонецЕсли;
// Добавляем договор в подчиненные строки контрагента
СтрокаДоговора = СтрокаКонтрагента.Строки.Добавить();
СтрокаДоговора.Наименование = ВыборкаДетальныхЗаписей.Ссылка;
КонецЦикла;
Используя этот алгоритм, мы получаем чистый и понятный код. При таком подходе ДеревоЗначений автоматически обеспечивает пользователю возможность раскрывать и сворачивать группы контрагентов, что полностью соответствует поставленной задаче.
Если задача становится более масштабной и требует дополнительных настроек (отборы, сортировки, вывод дополнительных реквизитов), рекомендуем рассмотреть Систему Компоновки Данных (СКД). Это стандарт де-факто в 1С для работы с отчетами. В СКД вам достаточно добавить поле «Владелец» в раздел «Группировки» настроек отчета. Система сама сгенерирует иерархический отчет с итоговыми записями, группировками и возможностью расшифровки, не требуя от вас ручного написания цикла по обходу запроса.
Для реализации группировки договоров по владельцу в обработке придерживайтесь следующих рекомендаций:
ДеревоЗначений для небольших, специфических интерфейсных задач в обработках.СКД, если необходимо строить полноценный отчет с широкими возможностями для пользователя.Такой подход делает ваше решение легко масштабируемым и понятным для других разработчиков, которые будут поддерживать ваш код в будущем.