Как программно раскрасить строки динамического списка в 1С на основе реквизитов базы данных

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Разработка интерфейсов на управляемых формах в платформе 1С:Предприятие требует от разработчика понимания механизмов отрисовки данных. Часто возникает задача: выделить цветом строки в списке (например, справочника или документа) в зависимости от значения какого-либо реквизита. Ситуация усложняется, когда цвета не зафиксированы жестко на этапе разработки, а динамически добавляются пользователями или хранятся непосредственно в базе данных в виде индексов, кодов или строк.

В этой статье мы подробно разберем, как решить эту задачу. Мы проанализируем два полярных подхода: классический метод с программным заполнением коллекции Условного Оформления формы и современный высокопроизводительный способ с использованием обработчика события ПриПолученииДанныхНаСервере, доступного в платформе начиная с версии 8.3.10.

Постановка задачи и анализ проблемы

Представим сценарий: у нас есть динамический список документов или задач. В каждом объекте базы данных хранится ссылка на проект или категорию, для которой назначен индивидуальный цвет отображения (например, реквизит Цвет типа Строка, содержащий XML-сериализованное значение цвета, либо числовой индекс цвета). Нам необходимо сделать так, чтобы каждая строка в динамическом списке окрашивалась в цвет, соответствующий этому реквизиту.

Стандартное условное оформление формы, настраиваемое вручную в конфигураторе, здесь бессильно, так как количество цветов заранее неизвестно и они могут создаваться пользователями динамически. Нам потребуется программное решение.

---

Метод №1. Программное создание элементов Условного Оформления

Этот способ основан на динамическом добавлении правил в системную коллекцию УсловноеОформление управляемой формы. Суть метода заключается в предварительной выборке всех уникальных цветов, которые используются в текущих объектах, и последующем создании индивидуального правила оформления для каждого значения.

Рассмотрим пошагово, как реализовать этот алгоритм при создании формы на сервере. Мы напишем процедуру, которая выбирает уникальные цвета запросом, а затем обходит их в цикле, добавляя элементы оформления.


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

Выделим ключевые особенности этого подхода:

  1. Мы используем СериализаторXDTO для десериализации цвета из строкового представления, хранящегося в реквизите справочника. Это очень удобный и надежный способ хранения настроек отображения.
  2. Для каждого уникального значения создается отдельный элемент коллекции УсловноеОформление со своим уникальным отбором через ЭлементОтбораКомпоновкиДанных.
  3. Мы явно перечисляем оформляемые поля, добавляя их в коллекцию ЭлементОформления.Поля.Элементы. Если этого не сделать, будет раскрашена вся строка целиком.

Важное ограничение метода: Данный способ отлично работает, если количество уникальных цветов в справочнике невелико (в пределах 20-30 вариантов). Если же в вашей базе данных сотни или тысячи уникальных сущностей с индивидуальной раскраской, создание сотен правил условного оформления приведет к колоссальным задержкам при открытии формы и прокрутке списка, так как клиентское приложение будет вынуждено обрабатывать гигантский массив правил рендеринга.

---

Метод №2. Использование обработчика события ПриПолученииДанныхНаСервере

Начиная с версии платформы 1С **8.3.10**, разработчики получили в руки мощнейший инструмент оптимизации динамических списков — обработчик события таблицы ПриПолученииДанныхНаСервере. Этот механизм позволяет отказаться от тяжеловесных правил глобального условного оформления формы и красить строки порционно — только те, которые выводятся на экран пользователя прямо сейчас.

Событие срабатывает на сервере без контекста формы (контекст формы не передается, что экономит трафик и процессорное время) в момент, когда табличная часть на клиенте запрашивает очередную порцию строк при скроллинге. Мы можем перехватить этот момент, быстро запросить цвета именно для отображаемых строк и раскрасить их «на лету».

Разберем детальную схему реализации этого метода. Нам понадобятся обработчик события таблицы списка и вспомогательная функция получения цвета.


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

Рассмотрим, почему этот метод считается эталонным для больших динамических списков:

  1. Минимальная нагрузка на БД: Запрос выполняется только по тем записям, которые реально видит пользователь (ограничено высотой экрана монитора).
  2. Отсутствие контекста: Директива &НаСервереБезКонтекста гарантирует, что при прокрутке списка не будет передаваться тяжелый контекст формы (все ее реквизиты, невидимые элементы и т.д.), что критически важно для работы через веб-клиент или при медленном интернет-соединении.
  3. Прямой доступ к оформлению: Мы работаем напрямую со свойством Оформление строки данных динамического списка, минуя громоздкую структуру условного оформления всей формы.

---

Сравнение методов: что и когда применять

Для наглядности проведем сравнительный анализ двух архитектурных решений, чтобы вы всегда могли сделать осознанный выбор при проектировании интерфейсов ваших решений.

Критерий сравнения Метод №1: Глобальное УО формы Метод №2: Событие ПриПолученииДанныхНаСервере
Минимальная версия платформы Любая версия 8.3 (и даже 8.2) Начиная с версии 8.3.10
Производительность на больших базах Низкая (создание сотен правил замедляет интерфейс) Экстремально высокая (обрабатываются только видимые строки)
Влияние на веб-клиент Негативное (нагружает рендеринг в браузере) Отсутствует (отрисовка происходит порционно и плавно)
Простота отладки и поддержки кода Просто (весь код выполняется один раз при создании формы) Средне (требуется аккуратная работа с безымянным контекстом)
Дополнительные возможности Только стандартные параметры оформления Позволяет динамически менять форматы данных, выводить текст и шрифты

Выяснив сильные стороны каждого метода, мы рекомендуем использовать Метод №2 как основной стандарт разработки в современных конфигурациях на платформе 1С:Предприятие 8.3. К использованию Метода №1 стоит прибегать лишь в случае работы на старых версиях платформы или когда гарантировано, что список оформляемых объектов ограничен жестким и небольшим лимитом элементов.

Применяя данные подходы, вы сможете создавать не только функциональные, но и визуально приятные, отзывчивые интерфейсы, которые по достоинству оценят конечные пользователи ваших программных продуктов.

← На главную