Как изменить цвет фона ячеек в таблице управляемой формы 1С 8.3 при сравнении данных

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

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

Разберем проблему: почему нельзя просто присвоить цвет

Проанализируем типичную ошибку начинающих разработчиков. Попытка использовать конструкцию типа Элементы.Таблица.ТекущиеДанные.ИмяПоля.ЦветФона = Цвет приведет к тому, что окрасится либо вся колонка целиком для всех строк, либо код просто не сработает в управляемом приложении. Управляемые формы работают по принципу отделения данных от их визуального представления. Чтобы «покрасить» конкретную ячейку, мы должны создать правило, которое скажет системе: «Если данные в этой строке соответствуют условию X, то поле Y должно иметь красный фон».

Метод 1: Использование «теневых» реквизитов формы

Это самый надежный и производительный метод, особенно когда условие раскраски сложное (например, нужно сравнить значение ячейки со значением из другой таблицы или выполнить запрос к базе данных). Рассмотрим ситуацию, когда у нас есть основная таблица ДанныеОВремени и нам нужно подсветить расхождения с эталонной таблицей.

Шаг 1. Добавление реквизитов-флагов.

В дерево реквизитов формы, непосредственно в саму табличную часть (которая является реквизитом формы, а не метаданными объекта), добавим новые колонки. Например, для колонки Время1 добавим колонку Время1_Ошибка с типом Булево. Важно понимать разницу: мы не меняем структуру документа в конфигураторе, мы добавляем колонки только на уровне формы (Программное создание колонок в табличной части документа).

Шаг 2. Расчет условий на сервере.

Проанализируем ситуацию: нам нужно сравнить текущую таблицу с эталонной. Создадим процедуру, которая заполнит наши флаги:


&НаСервере
Процедура ПроверитьРасхожденияНаСервере()
    
    // Допустим, ТабТиповой - это таблица с эталонными данными
    ТабТиповой = ПолучитьЭталоннуюТаблицуВремени(); 
    
    Для Каждого Стр Из Объект.ДанныеОВремени Цикл
        // Ищем соответствие по сотруднику
        СтрокаЭталона = ТабТиповой.Найти(Стр.Сотрудник, "Сотрудник");
        Если СтрокаЭталона <> Неопределено Тогда
            // Сравниваем значения в колонках за 1-е число
            Если Стр.Время1 <> СтрокаЭталона.Время1 Тогда
                Стр.Время1_Ошибка = Истина; // Устанавливаем флаг
            Иначе
                Стр.Время1_Ошибка = Ложь;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    
КонецПроцедуры

Шаг 3. Настройка Условного оформления.

Теперь настроим само оформление. Это можно сделать как в конфигураторе на закладке «Условное оформление» формы, так и программно. Рассмотрим программный вариант, так как он более гибкий:


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

Метод 2: Динамическое создание правил (для большого количества колонок)

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


&НаСервере
Процедура СоздатьДинамическоеОформление(НачалоПериода, КонецПериода)
    
    Для День = 1 По 31 Цикл
        ИмяПоля = "Время" + День;
        ИмяФлага = ИмяПоля + "_Ошибка";
        
        Элемент = УсловноеОформление.Элементы.Добавить();
        
        // Устанавливаем красный цвет
        Элемент.Оформление.УстановитьЗначениеПараметра("ЦветФона", Новый Цвет(255, 200, 200));
        
        // Настраиваем отбор по скрытому реквизиту-флагу
        Отбор = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
        Отбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.ДанныеОВремени." + ИмяФлага);
        Отбор.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
        Отбор.ПравоеЗначение = Истина;
        
        // Указываем, какую именно колонку раскрашивать
        Поле = Элемент.Поля.Элементы.Добавить();
        Поле.Поле = Новый ПолеКомпоновкиДанных("ДанныеОВремени" + ИмяПоля);
    КонецЦикла;
    
КонецПроцедуры

Важные замечания по оптимизации

При работе с условным оформлением следует придерживаться нескольких правил, чтобы форма не «тормозила»:

  1. Не злоупотребляйте количеством правил. Каждое правило УО увеличивает нагрузку на клиентское устройство при отрисовке таблицы. Старайтесь объединять похожие условия.
  2. Используйте индексацию. Если вы сравниваете две большие таблицы значений на сервере, чтобы найти расхождения, обязательно проиндексируйте их по ключевым полям (например, по Сотруднику), прежде чем использовать метод Найти().
  3. Обновление отображения. Если данные во флагах изменились, а форма не перекрасилась мгновенно, используйте метод ЭтаФорма.ОбновитьОтображениеДанных() на клиенте.
  4. Приоритет оформления. Помните, что правила УО применяются сверху вниз. Если одна и та же ячейка попадает под два правила, применится то, которое находится ниже в списке (или последнее добавленное).

Выясним еще один нюанс: если вам нужно красить ячейку на основании реквизитов ссылочного типа (например, красить номенклатуру, если она входит в определенную группу), лучше всего также вынести это значение в отдельный реквизит формы. Платформа 1С плохо справляется с «проваливанием» через точку в условиях оформления (Объект.Товары.Номенклатура.АссортиментнаяГруппа), что может привести к замедлению работы списка. Подтяните АссортиментнуюГруппу в скрытую колонку при изменении номенклатуры, и используйте эту колонку в Условном оформлении. Это профессиональный подход к разработке высоконагруженных интерфейсов.

← На главную