В разработке на платформе 1С:Предприятие 8.3 часто возникает задача визуального выделения элементов в списках. Одной из наиболее сложных вариаций этой задачи является раскраска строк не по заранее заданным правилам (например, «красный, если долг больше нуля»), а на основе произвольных цветов, коды которых (RGB) хранятся непосредственно в базе данных для каждого элемента справочника. В этой статье мы подробно разберем, как реализовать такую динамическую раскраску в управляемых формах, проанализируем различные подходы и выберем наиболее эффективный.
Традиционно для оформления списков в 1С используется механизм Условного оформления. Однако, если цветов в справочнике может быть неограниченное количество (любой оттенок RGB), создавать правила условного оформления для каждого варианта в конфигураторе невозможно. Программное создание сотен правил УО также негативно скажется на производительности формы.
Оптимальным решением для динамических списков является использование обработчика события ПриПолученииДанныхНаСервере. Рассмотрим подробнее, почему это так:
Перед тем как писать код, нам необходимо убедиться, что данные о цвете доступны в динамическом списке. Предположим, у нашего справочника есть реквизит КодЦвета (тип Число), где хранится RGB-значение.
Разберем важный нюанс: если реквизит КодЦвета не выведен в качестве колонки в таблицу формы, платформа может не подтянуть его данные с сервера для экономии трафика. Чтобы этого избежать, выполним следующие действия:
КодЦвета и установим для него флаг Использовать всегда. Теперь данные будут доступны в коде обработчика, даже если колонка скрыта от пользователя.Теперь перейдем к написанию кода. Нам нужно создать обработчик события для элемента формы (Таблицы), отображающей динамический список. Выясним, как преобразовать числовое значение в объект типа Цвет и применить его.
&НаСервереБезКонтекста
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
// Пройдемся по всем строкам, которые подготовила платформа для отображения
Для каждого СтрокаДинСписка Из Строки Цикл
// 1. Получаем данные текущей строки
ДанныеСтроки = СтрокаДинСписка.Значение.Данные;
// Проверяем наличие реквизита, чтобы избежать ошибок
Если ДанныеСтроки.Свойство("КодЦвета") Тогда
ЦветЧислом = ДанныеСтроки.КодЦвета;
// Если цвет не задан (0), можно пропустить или задать стандартный
Если ЦветЧислом = 0 Тогда
Продолжить;
КонецЕсли;
// 2. Преобразуем число в составляющие RGB
// В 1С цвет в числовом виде обычно хранится как R + G*256 + B*65536
Красный = ЦветЧислом % 256;
Зеленый = Целое(ЦветЧислом / 256) % 256;
Синий = Целое(ЦветЧислом / 65536) % 256;
НовыйЦвет = Новый Цвет(Красный, Зеленый, Синий);
// 3. Устанавливаем оформление для конкретной колонки (например, "Код")
ОформлениеКолонки = СтрокаДинСписка.Значение.Оформление["Код"];
ОформлениеКолонки.УстановитьЗначениеПараметра("ЦветФона", НовыйЦвет);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Часто требуется покрасить не одну ячейку, а всю строку. В объекте ОформлениеСтроки (в контексте УФ это коллекция в СтрокаДинСписка.Значение.Оформление) нет единого параметра «Цвет всей строки». Оформление в управляемых формах всегда применяется к ячейкам. Чтобы добиться эффекта полной закраски, мы должны обойти все доступные поля оформления в цикле.
Проанализируем пример кода для полной раскраски:
Для каждого СтрокаДинСписка Из Строки Цикл
// ... (код получения цвета, описанный выше) ...
// Применяем цвет ко всем ячейкам данной строки
Для каждого ЭлементОформления Из СтрокаДинСписка.Значение.Оформление Цикл
ЭлементОформления.УстановитьЗначениеПараметра("ЦветФона", НовыйЦвет);
КонецЦикла;
КонецЦикла;
При быстрой прокрутке списка событие ПриПолученииДанныхНаСервере вызывается очень часто. Создание объекта Новый Цвет для каждой строки в каждой итерации может создавать лишнюю нагрузку на память. Рассмотрим способ оптимизации с использованием кэша цветов в рамках одного вызова процедуры.
&НаСервереБезКонтекста
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
КэшЦветов = Новый Соответствие;
Для каждого СтрокаДинСписка Из Строки Цикл
КодЦвета = СтрокаДинСписка.Значение.Данные.КодЦвета;
// Ищем цвет в кэше, чтобы не создавать новый объект
ЦветДляУстановки = КэшЦветов.Получить(КодЦвета);
Если ЦветДляУстановки = Неопределено Тогда
// Вычисляем компоненты RGB
R = КодЦвета % 256;
G = Целое(КодЦвета / 256) % 256;
B = Целое(КодЦвета / 65536) % 256;
ЦветДляУстановки = Новый Цвет(R, G, B);
КэшЦветов.Вставить(КодЦвета, ЦветДляУстановки);
КонецЕсли;
// Установка оформления
// ...
КонецЦикла;
КонецПроцедуры
Если в вашем справочнике используется ограниченный набор цветов (например, фиксированная палитра из 10–20 цветов), лучше использовать стандартное Условное оформление формы. Выясним, как это сделать программно в процедуре ПриСозданииНаСервере:
КодЦвета Равно [Значение]).ЦветФона.Важно: Этот метод подходит только для случаев с фиксированным набором цветов. Если пользователь может выбрать любой цвет из палитры RGB, используйте только метод ПриПолученииДанныхНаСервере.
ЦветТекста (белый или черный) для обеспечения контраста.Подводя итог, мы рассмотрели наиболее гибкий способ раскраски динамических списков в 1С 8.3. Использование события ПриПолученииДанныхНаСервере в сочетании с прямой манипуляцией коллекцией Оформление позволяет создавать современные и интуитивно понятные интерфейсы, где визуальное представление данных напрямую зависит от их содержимого.