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