При работе с управляемыми формами в платформе «1С:Предприятие 8.3» разработчики часто сталкиваются с задачей визуального выделения данных. Если в обычных формах мы могли использовать событие ПриВыводеСтроки или ПриПолученииДанных, то в управляемом интерфейсе подход в корне изменился. Здесь за визуализацию отвечает механизм Условного оформления. Особенно сложной задача становится тогда, когда колонки в дереве значений (или таблице) создаются динамически программным кодом, и нам нужно раскрасить не всю строку целиком, а конкретную ячейку в зависимости от её значения.
В этой статье мы подробно разберем, как реализовать программную раскраску ячеек для динамического дерева значений, проанализируем типичные ошибки и предложим оптимизированный код решения.
Представим ситуацию: мы формируем отчет или таблицу мониторинга, где строки — это организации, а колонки — даты периода. Количество колонок заранее неизвестно и зависит от выбранного пользователем интервала. В каждой ячейке хранится статус (например, «1» — не загружено, «2» — загружено, «3» — синхронизировано). Нам нужно, чтобы ячейки окрашивались в разные цвета (красный, оранжевый, зеленый) в зависимости от этих цифр.
Главная сложность заключается в том, что на этапе разработки формы этих колонок не существует. Следовательно, мы не можем настроить условное оформление в конфигураторе. Нам придется создавать правила оформления программно в тот же момент, когда мы генерируем колонки дерева.
Прежде чем красить ячейки, мы должны создать структуру данных. Проанализируем процесс добавления динамических колонок. Важно помнить, что в управляемых формах создание колонки — это двухэтапный процесс: добавление реквизита в данные формы и добавление элемента управления (поля формы) в интерфейс.
Рассмотрим пример кода, который подготавливает структуру дерева:
// 1. Получаем объект дерева значений из реквизита формы
ДеревоОбъект = РеквизитФормыВЗначение("ДЗ_РезАнализа");
// 2. Добавляем колонки в сам объект (данные)
ИмяПоля = "д" + СтрЗаменить(Формат(ТекДата,"ДЛФ=Д"), ".", "_");
ДеревоОбъект.Колонки.Добавить(ИмяПоля, Новый ОписаниеТипов("Строка"));
// 3. Создаем массив новых реквизитов для формы
МассивДобавляемыхРеквизитов = Новый Массив;
МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы(ИмяПоля, Новый ОписаниеТипов("Строка"), "ДЗ_РезАнализа"));
// 4. Фиксируем изменения реквизитов формы
ИзменитьРеквизиты(МассивДобавляемыхРеквизитов);
// 5. Создаем элемент формы (визуальную колонку)
НовыйЭлемент = Элементы.Добавить(ИмяПоля, Тип("ПолеФормы"), Элементы.ГруппаДерева);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.ПутьКДанным = "ДЗ_РезАнализа." + ИмяПоля;
Важный нюанс: Метод ИзменитьРеквизиты является тяжелой операцией. Если колонок много, рекомендуется сначала собрать все реквизиты в массив внутри цикла, а вызвать метод один раз после завершения цикла.
Теперь перейдем к самому главному — программному раскрашиванию. Мы выяснили, что условное оформление работает как «фильтр». Чтобы покрасить конкретную ячейку, нам нужно указать три сущности:
ЦветФона).Рассмотрим, как это выглядит в коде внутри цикла по датам:
// Создаем новый элемент условного оформления на форме
ЭлементУО = УсловноеОформление.Элементы.Добавить();
// 1. Устанавливаем цвет фона (Зеленый для статуса "Синхронизировано")
ЭлементУО.Оформление.УстановитьЗначениеПараметра("ЦветФона", WebЦвета.ЗеленаяЛужайка);
// 2. Настраиваем условие (Отбор)
// Нам нужно проверить значение именно в текущей динамической колонке
ЭлементОтбора = ЭлементУО.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ДЗ_РезАнализа." + ИмяПоля);
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = "++"; // Наше условное обозначение статуса
ЭлементОтбора.Использование = Истина;
// 3. Указываем оформляемое поле (чтобы красилась только ячейка, а не строка)
ОформляемоеПоле = ЭлементУО.Поля.Элементы.Добавить();
ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных(ИмяПоля);
ОформляемоеПоле.Использование = Истина;
Проанализируем ситуацию, с которой столкнулся автор темы. В процессе разработки возникли две основные проблемы:
Первая проблема: Почему красится вся строка?
Это происходит, если в коллекции Поля элемента условного оформления пусто. По умолчанию платформа применяет правила ко всем колонкам строки, если не заданы конкретные ограничения. Для раскраски именно ячейки обязательно добавьте ПолеКомпоновкиДанных с именем вашей динамической колонки.
Вторая проблема: Неправильные пути к данным.
Обратите внимание: в Отборе (ЛевоеЗначение) мы указываем путь к данным реквизита, например, "ДЗ_РезАнализа.д2023_10_01". А в Полях оформления указывается имя элемента формы (колонки). Часто разработчики путают эти понятия, что приводит к неработоспособности оформления.
Выясним, как сделать решение стабильным. Если процедура формирования дерева вызывается несколько раз (например, при нажатии кнопки «Обновить»), старые правила условного оформления никуда не исчезают. Они накапливаются в коллекции УсловноеОформление.Элементы.
Проанализируем последствия: при каждом обновлении у вас будет добавляться по 30-50 новых правил. Через несколько итераций форма начнет заметно тормозить при прокрутке. Поэтому всегда начинайте процедуру формирования с очистки:
УсловноеОформление.Элементы.Очистить();
Также помните о типах данных. Если ваша колонка имеет тип Число, то в условии ПравоеЗначение должно быть числом (например, 3), а не строкой ("3"). Несоответствие типов — одна из самых частых причин, по которым раскраска «вдруг» перестает работать.
Сведем все полученные знания в единую надежную процедуру, которую можно использовать в своих разработках:
&НаСервере
Процедура ОбновитьЦветаДереваНаСервере()
// Очищаем старое оформление, чтобы не плодить дубли при обновлении
УсловноеОформление.Элементы.Очистить();
// Допустим, у нас уже созданы динамические колонки с именами д01_01_2024 и т.д.
// Пройдем в цикле по списку наших динамических имен
Для Каждого ИмяКолонки Из СписокИменДинамическихКолонок Цикл
// Создаем правило для статуса "Ошибка" (красный)
НовыйЭлемент = УсловноеОформление.Элементы.Добавить();
НовыйЭлемент.Оформление.УстановитьЗначениеПараметра("ЦветФона", WebЦвета.Красный);
// Условие: Значение в ячейке равно "-"
Отбор = НовыйЭлемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Отбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ДЗ_РезАнализа." + ИмяКолонки);
Отбор.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
Отбор.ПравоеЗначение = "-";
// Применяем ТОЛЬКО к этой ячейке
ПолеОформления = НовыйЭлемент.Поля.Элементы.Добавить();
ПолеОформления.Поле = Новый ПолеКомпоновкиДанных(ИмяКолонки);
// Повторяем для других статусов (Зеленый, Оранжевый) при необходимости...
КонецЦикла;
КонецПроцедуры
Таким образом, мы выяснили, что программное управление оформлением — это мощный инструмент, позволяющий создавать гибкие и информативные интерфейсы в 1С. Главное — четко разделять данные и их визуальное представление, не забывать об очистке коллекции элементов оформления и следить за точностью указания путей к оформляемым полям.