Переход с обычных форм на управляемые в «1С:Предприятии 8» заставил многих разработчиков полностью пересмотреть свои подходы к кастомизации интерфейса. Если на обычных формах мы привыкли использовать интерактивные события табличного поля (такие как ПриВыводеСтроки или ПриПолученииДанных) и напрямую красили ячейки «на лету» с помощью простого кода, то в управляемом интерфейсе (УФ) этот механизм больше не работает.
На управляемых формах вся отрисовка элементов происходит на стороне клиента, в то время как данные живут на сервере. Прямой доступ к визуальному отображению ячеек из кода закрыт. Для решения задач динамического изменения цвета, шрифтов и видимости элементов платформой предоставлен специальный декларативный механизм — Условное оформление. Рассмотрим подробно, как правильно использовать этот инструмент для раскраски таблиц значений, проанализируем типичные ошибки разработчиков и разберем лучшие практики написания программного кода.
Часто разработчики сталкиваются с ситуацией, когда они заходят в свойства формы, открывают вкладку «Условное оформление», создают новое правило, но на форме ничего не меняется. Выясним основные причины этой проблемы, которые чаще всего связаны с невнимательностью при заполнении параметров:
ТаблицаТоваров, то в левом значении отбора путь должен выглядеть как ТаблицаТоваров.ИмяКолонки. Если ошибиться хотя бы в одном символе или случайно сослаться на реквизит объекта (например, Объект.Товары.ИмяКолонки вместо реквизита формы), условное оформление работать не будет.УстановитьУсловноеОформление(). Эти процедуры могут принудительно очищать коллекцию УсловноеОформление и заполнять ее заново программным путем, затирая все наши интерактивные настройки.Для того чтобы избежать конфликтов с типовыми механизмами и сделать решение гибким, рекомендуется настраивать условное оформление программно.
Давайте разберем по шагам, как программно раскрасить строки или отдельные ячейки таблицы значений на управляемой форме. Весь код настройки должен выполняться на сервере, как правило, в обработчике события формы ПриСозданииНаСервере или сразу после процедуры заполнения таблицы данных.
Представим сценарий: у нас есть таблица значений на форме с именем реквизита ТаблицаДанных. В ней присутствует колонка Статус (тип Строка). Нам нужно покрасить текст всей строки в красный цвет, если статус равен «Ошибка», и фон ячейки в зеленый цвет, если статус равен «Выполнено».
Рассмотрим пример реализации этой задачи:
&НаСервере
Процедура НастроитьУсловноеОформлениеФормы()
// 1. Очистим старое оформление, если процедура вызывается динамически
// УсловноеОформление.Элементы.Очистить(); // Раскомментируйте при необходимости
// --- ПРАВИЛО 1: Красим ТЕКСТ всей строки в КРАСНЫЙ при статусе "Ошибка" ---
ЭлементУО_Ошибка = УсловноеОформление.Элементы.Добавить();
// Задаем оформление: красный цвет текста
ЭлементУО_Ошибка.Оформление.УстановитьЗначениеПараметра("ЦветТекста", WebЦвета.Красный);
// Задаем условие отбора: ТаблицаДанных.Статус Равно "Ошибка"
ЭлементОтбора = ЭлементУО_Ошибка.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ТаблицаДанных.Статус");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = "Ошибка";
ЭлементОтбора.Использование = Истина;
// Указываем оформляемые поля. Чтобы покрасить всю строку, добавим все колонки таблицы.
// Важно: Имя поля компоновки должно совпадать с именем элемента формы (колонки таблицы)
МассивКолонок = Новый Массив;
МассивКолонок.Добавить("ТаблицаДанныхНоменклатура");
МассивКолонок.Добавить("ТаблицаДанныхКоличество");
МассивКолонок.Добавить("ТаблицаДанныхСтатус");
Для Каждого ИмяКолонки Из МассивКолонок Цикл
ОформляемоеПоле = ЭлементУО_Ошибка.Поля.Элементы.Добавить();
ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных(ИмяКолонки);
ОформляемоеПоле.Использование = Истина;
КонецЦикла;
// --- ПРАВИЛО 2: Красим только ФОН ячейки "Статус" в ЗЕЛЕНЫЙ при значении "Выполнено" ---
ЭлементУО_Выполнено = УсловноеОформление.Элементы.Добавить();
// Задаем оформление: зеленый фон
ЭлементУО_Выполнено.Оформление.УстановитьЗначениеПараметра("ЦветФона", WebЦвета.СветлоЗеленый);
// Задаем условие отбора: ТаблицаДанных.Статус Равно "Выполнено"
ЭлементОтбораВыполнено = ЭлементУО_Выполнено.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбораВыполнено.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ТаблицаДанных.Статус");
ЭлементОтбораВыполнено.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбораВыполнено.ПравоеЗначение = "Выполнено";
ЭлементОтбораВыполнено.Использование = Истина;
// Оформляем только ОДНУ конкретную ячейку (колонку "Статус")
ОформляемоеПолеСтатус = ЭлементУО_Выполнено.Поля.Элементы.Добавить();
ОформляемоеПолеСтатус.Поле = Новый ПолеКомпоновкиДанных("ТаблицаДанныхСтатус");
ОформляемоеПолеСтатус.Использование = Истина;
КонецПроцедуры
Обратим внимание на важную техническую деталь: при настройке отбора (условия) мы используем путь к данным через точку (например, ТаблицаДанных.Статус), так как отбор работает непосредственно с набором данных реквизита. А при добавлении оформляемых полей мы указываем имя элемента управления на форме (например, ТаблицаДанныхСтатус), так как оформление применяется непосредственно к визуальным элементам интерфейса.
Что делать, если условие для раскраски строк является чрезвычайно сложным? Например, нам нужно подсветить строку желтым цветом, если одновременно выполняются следующие условия: товар просрочен по дате, остаток на складе меньше критического минимума, и у контрагента имеется дебиторская задолженность.
Если мы попытаемся перенести всю эту бизнес-логику в настройки отбора условного оформления, мы получим громоздкую структуру из множества групп «И» / «ИЛИ». Такой код сложно читать, невозможно отлаживать, а сама платформа будет испытывать повышенную нагрузку при перерисовке таблицы на экране пользователя.
Для решения таких задач мы применим лучшую практику разработки в 1С — вспомогательные технические колонки оформления. Идея метода очень проста:
ИндексОформления (тип Число) или ТребуетВнимания (тип Булево). Этот реквизит не нужно выводить пользователю на форму, он будет чисто техническим.1 для предупреждения, 2 для критической ошибки, и 0 для штатной ситуации.ИндексОформления конкретному числу.Рассмотрим пример реализации данного подхода. Сначала рассчитаем индекс оформления при заполнении таблицы данных:
&НаСервере
Процедура ЗаполнитьТаблицуДанныхНаСервере()
// Предположим, мы получили таблицу значений запросом
ТаблицаДанных.Очистить();
// Выполняем запрос к базе данных и выгружаем результат в реквизит формы
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТоварыНаСкладах.Номенклатура КАК Номенклатура,
| ТоварыНаСкладах.ВНаличии КАК Количество,
| ТоварыНаСкладах.МинимальныйОстаток КАК МинимальныйОстаток,
| ТоварыНаСкладах.ДатаПоступления КАК ДатаПоступления
|ИЗ
| РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах";
РезультатЗапроса = Запрос.Выполнить();
ТаблицаДанных.Загрузить(РезультатЗапроса.Выгрузить());
// Теперь рассчитаем техническую колонку "ИндексОформления" в цикле
Для Каждого СтрокаТЗ Из ТаблицаДанных Цикл
// Сложная бизнес-логика проверки условий
ДнейНаСкладе = (ТекущаяДата() - СтрокаТЗ.ДатаПоступления) / 86400;
Если СтрокаТЗ.Количество < СтрокаТЗ.МинимальныйОстаток И ДнейНаСкладе > 30 Тогда
// Ситуация критическая: остаток ниже нормы и товар залежался
СтрокаТЗ.ИндексОформления = 2;
ИначеЕсли СтрокаТЗ.Количество < СтрокаТЗ.МинимальныйОстаток Тогда
// Ситуация предупреждения: просто не хватает остатка
СтрокаТЗ.ИндексОформления = 1;
Иначе
// Нормальное состояние
СтрокаТЗ.ИндексОформления = 0;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Теперь настроим простейшее условное оформление, которое будет реагировать исключительно на значение нашей служебной колонки:
&НаСервере
Процедура НастроитьОформлениеПоИндексу()
// Правило для критического состояния (ИндексОформления = 2) -> Красный фон
ЭлементКритический = УсловноеОформление.Элементы.Добавить();
ЭлементКритический.Оформление.УстановитьЗначениеПараметра("ЦветФона", WebЦвета.СветлоРозовый);
ОтборКритический = ЭлементКритический.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ОтборКритический.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ТаблицаДанных.ИндексОформления");
ОтборКритический.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ОтборКритический.ПравоеЗначение = 2;
ОтборКритический.Использование = Истина;
// Правило для предупреждения (ИндексОформления = 1) -> Желтый фон
ЭлементПредупреждение = УсловноеОформление.Элементы.Добавить();
ЭлементПредупреждение.Оформление.УстановитьЗначениеПараметра("ЦветФона", WebЦвета.ЛегкоЖелтый);
ОтборПредупреждение = ЭлементПредупреждение.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ОтборПредупреждение.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ТаблицаДанных.ИндексОформления");
ОтборПредупреждение.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ОтборПредупреждение.ПравоеЗначение = 1;
ОтборПредупреждение.Использование = Истина;
// Оформляемые поля для обоих правил (красим всю строку)
МассивПолей = Новый Массив;
МассивПолей.Добавить("ТаблицаДанныхНоменклатура");
МассивПолей.Добавить("ТаблицаДанныхКоличество");
Для Каждого ИмяПоля Из МассивПолей Цикл
ПолеКрит = ЭлементКритический.Поля.Элементы.Добавить();
ПолеКрит.Поле = Новый ПолеКомпоновкиДанных(ИмяПоля);
ПолеКрит.Использование = Истина;
ПолеПредупр = ЭлементПредупреждение.Поля.Элементы.Добавить();
ПолеПредупр.Поле = Новый ПолеКомпоновкиДанных(ИмяПоля);
ПолеПредупр.Использование = Истина;
КонецЦикла;
КонецПроцедуры
Этот метод не только ускоряет отрисовку интерфейса, но и делает ваш код понятным для любого другого разработчика, который будет поддерживать данную конфигурацию в будущем.
При использовании условного оформления на управляемых формах крайне важно соблюдать стандарты разработки фирмы «1С» (требования ИТС). Несоблюдение этих правил может привести к существенному замедлению работы интерфейса системы, особенно у клиентов, работающих через веб-клиент (браузер) или при медленном интернет-соединении.
Проанализируем ключевые рекомендации стандартов производительности 1С:
Видимость = Ложь или Доступность = Ложь в параметрах оформления). Это приводит к тому, что браузеру или тонкому клиенту приходится осуществлять полный пересчет геометрии всей таблицы при каждом изменении данных. Вместо этого фильтруйте исходные данные на уровне запроса или накладывайте стандартные отборы на саму таблицу формы.ПриСозданииНаСервере. Не рекомендуется пересоздавать элементы оформления при каждом изменении данных, так как это вызывает полную перезагрузку структуры формы у клиента. Если условия динамические — управляйте значениями в технических колонках данных, а структура условного оформления должна оставаться статической.Используя предложенные методики программной настройки и концепцию вспомогательных колонок, мы получаем мощный, надежный и быстродействующий инструмент визуализации данных на управляемых формах, полностью соответствующий стандартам и ожиданиям пользователей современных систем 1С.