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