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