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