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