Как программно раскрасить конкретную ячейку в динамическом дереве значений 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с управляемыми формами в платформе «1С:Предприятие 8.3» разработчики часто сталкиваются с задачей визуального выделения данных. Если в обычных формах мы могли использовать событие ПриВыводеСтроки или ПриПолученииДанных, то в управляемом интерфейсе подход в корне изменился. Здесь за визуализацию отвечает механизм Условного оформления. Особенно сложной задача становится тогда, когда колонки в дереве значений (или таблице) создаются динамически программным кодом, и нам нужно раскрасить не всю строку целиком, а конкретную ячейку в зависимости от её значения.

В этой статье мы подробно разберем, как реализовать программную раскраску ячеек для динамического дерева значений, проанализируем типичные ошибки и предложим оптимизированный код решения.

Постановка задачи и анализ ситуации

Представим ситуацию: мы формируем отчет или таблицу мониторинга, где строки — это организации, а колонки — даты периода. Количество колонок заранее неизвестно и зависит от выбранного пользователем интервала. В каждой ячейке хранится статус (например, «1» — не загружено, «2» — загружено, «3» — синхронизировано). Нам нужно, чтобы ячейки окрашивались в разные цвета (красный, оранжевый, зеленый) в зависимости от этих цифр.

Главная сложность заключается в том, что на этапе разработки формы этих колонок не существует. Следовательно, мы не можем настроить условное оформление в конфигураторе. Нам придется создавать правила оформления программно в тот же момент, когда мы генерируем колонки дерева.

Шаг 1: Программное создание колонок и реквизитов

Прежде чем красить ячейки, мы должны создать структуру данных. Проанализируем процесс добавления динамических колонок. Важно помнить, что в управляемых формах создание колонки — это двухэтапный процесс: добавление реквизита в данные формы и добавление элемента управления (поля формы) в интерфейс.

Рассмотрим пример кода, который подготавливает структуру дерева:


// 1. Получаем объект дерева значений из реквизита формы
ДеревоОбъект = РеквизитФормыВЗначение("ДЗ_РезАнализа");

// 2. Добавляем колонки в сам объект (данные)
ИмяПоля = "д" + СтрЗаменить(Формат(ТекДата,"ДЛФ=Д"), ".", "_");
ДеревоОбъект.Колонки.Добавить(ИмяПоля, Новый ОписаниеТипов("Строка"));

// 3. Создаем массив новых реквизитов для формы
МассивДобавляемыхРеквизитов = Новый Массив;
МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы(ИмяПоля, Новый ОписаниеТипов("Строка"), "ДЗ_РезАнализа"));

// 4. Фиксируем изменения реквизитов формы
ИзменитьРеквизиты(МассивДобавляемыхРеквизитов);

// 5. Создаем элемент формы (визуальную колонку)
НовыйЭлемент = Элементы.Добавить(ИмяПоля, Тип("ПолеФормы"), Элементы.ГруппаДерева);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.ПутьКДанным = "ДЗ_РезАнализа." + ИмяПоля;

Важный нюанс: Метод ИзменитьРеквизиты является тяжелой операцией. Если колонок много, рекомендуется сначала собрать все реквизиты в массив внутри цикла, а вызвать метод один раз после завершения цикла.

Шаг 2: Реализация условного оформления для конкретной ячейки

Теперь перейдем к самому главному — программному раскрашиванию. Мы выяснили, что условное оформление работает как «фильтр». Чтобы покрасить конкретную ячейку, нам нужно указать три сущности:

  1. Оформление: какой цвет мы хотим (например, ЦветФона).
  2. Отбор: условие, при котором срабатывает оформление (например, значение в ячейке равно «3»).
  3. Поля: конкретная колонка, к которой применяется цвет. Если не указать поля, покрасится вся строка.

Рассмотрим, как это выглядит в коде внутри цикла по датам:


// Создаем новый элемент условного оформления на форме
ЭлементУО = УсловноеОформление.Элементы.Добавить();

// 1. Устанавливаем цвет фона (Зеленый для статуса "Синхронизировано")
ЭлементУО.Оформление.УстановитьЗначениеПараметра("ЦветФона", WebЦвета.ЗеленаяЛужайка);

// 2. Настраиваем условие (Отбор)
// Нам нужно проверить значение именно в текущей динамической колонке
ЭлементОтбора = ЭлементУО.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ДЗ_РезАнализа." + ИмяПоля);
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = "++"; // Наше условное обозначение статуса
ЭлементОтбора.Использование = Истина;

// 3. Указываем оформляемое поле (чтобы красилась только ячейка, а не строка)
ОформляемоеПоле = ЭлементУО.Поля.Элементы.Добавить();
ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных(ИмяПоля);
ОформляемоеПоле.Использование = Истина;

Разбор типичных ошибок

Проанализируем ситуацию, с которой столкнулся автор темы. В процессе разработки возникли две основные проблемы:

Первая проблема: Почему красится вся строка?
Это происходит, если в коллекции Поля элемента условного оформления пусто. По умолчанию платформа применяет правила ко всем колонкам строки, если не заданы конкретные ограничения. Для раскраски именно ячейки обязательно добавьте ПолеКомпоновкиДанных с именем вашей динамической колонки.

Вторая проблема: Неправильные пути к данным.
Обратите внимание: в Отборе (ЛевоеЗначение) мы указываем путь к данным реквизита, например, "ДЗ_РезАнализа.д2023_10_01". А в Полях оформления указывается имя элемента формы (колонки). Часто разработчики путают эти понятия, что приводит к неработоспособности оформления.

Оптимизация: Очистка и производительность

Выясним, как сделать решение стабильным. Если процедура формирования дерева вызывается несколько раз (например, при нажатии кнопки «Обновить»), старые правила условного оформления никуда не исчезают. Они накапливаются в коллекции УсловноеОформление.Элементы.

Проанализируем последствия: при каждом обновлении у вас будет добавляться по 30-50 новых правил. Через несколько итераций форма начнет заметно тормозить при прокрутке. Поэтому всегда начинайте процедуру формирования с очистки:

УсловноеОформление.Элементы.Очистить();

Также помните о типах данных. Если ваша колонка имеет тип Число, то в условии ПравоеЗначение должно быть числом (например, 3), а не строкой ("3"). Несоответствие типов — одна из самых частых причин, по которым раскраска «вдруг» перестает работать.

Итоговый пример кода

Сведем все полученные знания в единую надежную процедуру, которую можно использовать в своих разработках:


&НаСервере
Процедура ОбновитьЦветаДереваНаСервере()
    
    // Очищаем старое оформление, чтобы не плодить дубли при обновлении
    УсловноеОформление.Элементы.Очистить();
    
    // Допустим, у нас уже созданы динамические колонки с именами д01_01_2024 и т.д.
    // Пройдем в цикле по списку наших динамических имен
    Для Каждого ИмяКолонки Из СписокИменДинамическихКолонок Цикл
        
        // Создаем правило для статуса "Ошибка" (красный)
        НовыйЭлемент = УсловноеОформление.Элементы.Добавить();
        НовыйЭлемент.Оформление.УстановитьЗначениеПараметра("ЦветФона", WebЦвета.Красный);
        
        // Условие: Значение в ячейке равно "-"
        Отбор = НовыйЭлемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
        Отбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ДЗ_РезАнализа." + ИмяКолонки);
        Отбор.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
        Отбор.ПравоеЗначение = "-";
        
        // Применяем ТОЛЬКО к этой ячейке
        ПолеОформления = НовыйЭлемент.Поля.Элементы.Добавить();
        ПолеОформления.Поле = Новый ПолеКомпоновкиДанных(ИмяКолонки);
        
        // Повторяем для других статусов (Зеленый, Оранжевый) при необходимости...
        
    КонецЦикла;
    
КонецПроцедуры

Таким образом, мы выяснили, что программное управление оформлением — это мощный инструмент, позволяющий создавать гибкие и информативные интерфейсы в 1С. Главное — четко разделять данные и их визуальное представление, не забывать об очистке коллекции элементов оформления и следить за точностью указания путей к оформляемым полям.

← На главную