Разработка интерфейсов на управляемых формах в платформе 1С:Предприятие требует от разработчика понимания механизмов отрисовки данных. Часто возникает задача: выделить цветом строки в списке (например, справочника или документа) в зависимости от значения какого-либо реквизита. Ситуация усложняется, когда цвета не зафиксированы жестко на этапе разработки, а динамически добавляются пользователями или хранятся непосредственно в базе данных в виде индексов, кодов или строк.
В этой статье мы подробно разберем, как решить эту задачу. Мы проанализируем два полярных подхода: классический метод с программным заполнением коллекции Условного Оформления формы и современный высокопроизводительный способ с использованием обработчика события ПриПолученииДанныхНаСервере, доступного в платформе начиная с версии 8.3.10.
Представим сценарий: у нас есть динамический список документов или задач. В каждом объекте базы данных хранится ссылка на проект или категорию, для которой назначен индивидуальный цвет отображения (например, реквизит Цвет типа Строка, содержащий XML-сериализованное значение цвета, либо числовой индекс цвета). Нам необходимо сделать так, чтобы каждая строка в динамическом списке окрашивалась в цвет, соответствующий этому реквизиту.
Стандартное условное оформление формы, настраиваемое вручную в конфигураторе, здесь бессильно, так как количество цветов заранее неизвестно и они могут создаваться пользователями динамически. Нам потребуется программное решение.
---
Этот способ основан на динамическом добавлении правил в системную коллекцию УсловноеОформление управляемой формы. Суть метода заключается в предварительной выборке всех уникальных цветов, которые используются в текущих объектах, и последующем создании индивидуального правила оформления для каждого значения.
Рассмотрим пошагово, как реализовать этот алгоритм при создании формы на сервере. Мы напишем процедуру, которая выбирает уникальные цвета запросом, а затем обходит их в цикле, добавляя элементы оформления.
&НаСервере
Процедура ИнициализироватьУсловноеОформление()
// Шаг 1. Очищаем старые правила, если процедура вызывается повторно
УсловноеОформление.Элементы.Очистить();
// Шаг 2. Выбираем из базы данных только те проекты, у которых задан цвет
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| Проекты.Ссылка КАК Проект,
| Проекты.Цвет КАК СтрокаЦвета
|ИЗ
| Справочник.Проекты КАК Проекты
|ГДЕ
| Проекты.Цвет <> """"";
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
Возврат;
КонецЕсли;
Выборка = РезультатЗапроса.Выбрать();
// Шаг 3. Начинаем обход и динамически наполняем коллекцию Условного Оформления
Пока Выборка.Следующий() Цикл
// Преобразуем сохраненную XML-строку обратно в объект платформы "Цвет"
Попытка
ОбъектЦвет = СериализаторXDTO.XMLЗначение(Тип("Цвет"), Выборка.СтрокаЦвета);
Исключение
// Если формат строки некорректен, пропускаем элемент
Продолжить;
КонецПопытки;
// Создаем новый элемент условного оформления
ЭлементОформления = УсловноеОформление.Элементы.Добавить();
// Настраиваем оформление: устанавливаем цвет фона
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ЦветФона", ОбъектЦвет);
// Настраиваем отбор: правило сработает, когда поле "Проект" равно текущему проекту из выборки
ЭлементОтбора = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Список.Проект");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = Выборка.Проект;
ЭлементОтбора.Использование = Истина;
// Указываем, какие именно поля списка нужно раскрасить (например, "Наименование" и "Срок")
ПолеОформления = ЭлементОформления.Поля.Элементы.Добавить();
ПолеОформления.Поле = Новый ПолеКомпоновкиДанных("СписокНаименование");
ПолеОформления.Использование = Истина;
ПолеОформленияСрок = ЭлементОформления.Поля.Элементы.Добавить();
ПолеОформленияСрок.Поле = Новый ПолеКомпоновкиДанных("СписокСрокДействия");
ПолеОформленияСрок.Использование = Истина;
КонецЦикла;
КонецПроцедуры
Выделим ключевые особенности этого подхода:
СериализаторXDTO для десериализации цвета из строкового представления, хранящегося в реквизите справочника. Это очень удобный и надежный способ хранения настроек отображения.УсловноеОформление со своим уникальным отбором через ЭлементОтбораКомпоновкиДанных.ЭлементОформления.Поля.Элементы. Если этого не сделать, будет раскрашена вся строка целиком.Важное ограничение метода: Данный способ отлично работает, если количество уникальных цветов в справочнике невелико (в пределах 20-30 вариантов). Если же в вашей базе данных сотни или тысячи уникальных сущностей с индивидуальной раскраской, создание сотен правил условного оформления приведет к колоссальным задержкам при открытии формы и прокрутке списка, так как клиентское приложение будет вынуждено обрабатывать гигантский массив правил рендеринга.
---
Начиная с версии платформы 1С **8.3.10**, разработчики получили в руки мощнейший инструмент оптимизации динамических списков — обработчик события таблицы ПриПолученииДанныхНаСервере. Этот механизм позволяет отказаться от тяжеловесных правил глобального условного оформления формы и красить строки порционно — только те, которые выводятся на экран пользователя прямо сейчас.
Событие срабатывает на сервере без контекста формы (контекст формы не передается, что экономит трафик и процессорное время) в момент, когда табличная часть на клиенте запрашивает очередную порцию строк при скроллинге. Мы можем перехватить этот момент, быстро запросить цвета именно для отображаемых строк и раскрасить их «на лету».
Разберем детальную схему реализации этого метода. Нам понадобятся обработчик события таблицы списка и вспомогательная функция получения цвета.
&НаСервереБезКонтекста
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
// Шаг 1. Получаем массив ключей (ссылок на объекты) только для отображаемых на экране строк.
// Обычно это не более 30-50 элементов, что гарантирует мгновенную работу запроса.
МассивСсылок = Строки.ПолучитьКлючи();
Если МассивСсылок.Количество() = 0 Тогда
Возврат;
КонецЕсли;
// Шаг 2. Запрашиваем цвета из базы данных пакетным запросом строго по списку отображаемых строк
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Задачи.Ссылка КАК Ссылка,
| Задачи.Проект.Цвет КАК СтрокаЦвета
|ИЗ
| Задача.ЗадачиПользователей КАК Задачи
|ГДЕ
| Задачи.Ссылка В (&МассивСсылок)
| И Задачи.Проект.Цвет <> """"";
Запрос.УстановитьПараметр("МассивСсылок", МассивСсылок);
ТаблицаЦветов = Запрос.Выполнить().Выгрузить();
// Шаг 3. Обходим строки, переданные в событие, и напрямую применяем оформление
Для Каждого ТекущаяСтрока Из Строки Цикл
// Ищем соответствие в полученной таблице цветов по ключу строки
СтрокаДанных = ТаблицаЦветов.Найти(ТекущаяСтрока.Ключ, "Ссылка");
Если СтрокаДанных <> Неопределено Тогда
Попытка
// Десериализуем цвет
ОбъектЦвет = СериализаторXDTO.XMLЗначение(Тип("Цвет"), СтрокаДанных.СтрокаЦвета);
// Красим фон ячеек строки.
// Мы можем обратиться к свойству Оформление конкретной строки и установить ЦветФона напрямую
ТекущаяСтрока.Значение.Оформление["ЦветФона"].УстановитьЗначение(ОбъектЦвет);
// При необходимости можно задать оформление для конкретных колонок:
// ТекущаяСтрока.Значение.Оформление["Наименование"].УстановитьЗначение("ЦветФона", ОбъектЦвет);
Исключение
// Игнорируем ошибки сериализации некорректных данных
Продолжить;
КонецПопытки;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Рассмотрим, почему этот метод считается эталонным для больших динамических списков:
&НаСервереБезКонтекста гарантирует, что при прокрутке списка не будет передаваться тяжелый контекст формы (все ее реквизиты, невидимые элементы и т.д.), что критически важно для работы через веб-клиент или при медленном интернет-соединении.Оформление строки данных динамического списка, минуя громоздкую структуру условного оформления всей формы.---
Для наглядности проведем сравнительный анализ двух архитектурных решений, чтобы вы всегда могли сделать осознанный выбор при проектировании интерфейсов ваших решений.
| Критерий сравнения | Метод №1: Глобальное УО формы | Метод №2: Событие ПриПолученииДанныхНаСервере |
|---|---|---|
| Минимальная версия платформы | Любая версия 8.3 (и даже 8.2) | Начиная с версии 8.3.10 |
| Производительность на больших базах | Низкая (создание сотен правил замедляет интерфейс) | Экстремально высокая (обрабатываются только видимые строки) |
| Влияние на веб-клиент | Негативное (нагружает рендеринг в браузере) | Отсутствует (отрисовка происходит порционно и плавно) |
| Простота отладки и поддержки кода | Просто (весь код выполняется один раз при создании формы) | Средне (требуется аккуратная работа с безымянным контекстом) |
| Дополнительные возможности | Только стандартные параметры оформления | Позволяет динамически менять форматы данных, выводить текст и шрифты |
Выяснив сильные стороны каждого метода, мы рекомендуем использовать Метод №2 как основной стандарт разработки в современных конфигурациях на платформе 1С:Предприятие 8.3. К использованию Метода №1 стоит прибегать лишь в случае работы на старых версиях платформы или когда гарантировано, что список оформляемых объектов ограничен жестким и небольшим лимитом элементов.
Применяя данные подходы, вы сможете создавать не только функциональные, но и визуально приятные, отзывчивые интерфейсы, которые по достоинству оценят конечные пользователи ваших программных продуктов.