Как раскрасить строки динамического списка без добавления полей в метаданные

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

В процессе разработки на платформе 1С:Предприятие 8.3 часто возникает задача визуального выделения определенных строк в Динамическом списке. Стандартный механизм условного оформления отлично работает, когда признак для раскраски уже существует в базе данных (например, пометка удаления или статус документа). Однако, что делать, если критерий раскраски вычисляется «на лету» в процессе работы обработки, а изменять структуру регистра или таблицы (добавлять новые поля) категорически нельзя? Рассмотрим подробный алгоритм решения этой задачи через модификацию запроса динамического списка и программное управление настройками компоновки данных.

Постановка задачи и анализ ограничений

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

Проанализируем ситуацию: для работы Условного оформления платформе требуется «зацепиться» за какое-то поле, которое присутствует в схеме компоновки данных динамического списка. Если такого поля нет в физической таблице, мы должны создать его виртуально.

Решение 1: Добавление расчетного поля в текст запроса

Самый надежный способ — это внедрение в запрос динамического списка искусственного поля, значение которого будет зависеть от внешних параметров. Разберем этот метод по шагам.

Во-первых, переведем запрос динамического списка в режим Произвольного запроса. В тексте запроса мы добавим конструкцию ВЫБОР, которая будет проверять соответствие записи нашему условию. Рассмотрим пример текста запроса:


ВЫБРАТЬ
    Регистр.Период,
    Регистр.Номенклатура,
    Регистр.Сделка,
    ВЫБОР
        КОГДА Регистр.Сделка В (&МассивСделокДляПодсветки)
            ТОГДА ИСТИНА
        ИНАЧЕ ЛОЖЬ
    КОНЕЦ КАК ПометкаРаскраски
ИЗ
    РегистрСведений.ВашРегистр КАК Регистр
ГДЕ
    Регистр.Сделка = &ОтборСделка

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

Решение 2: Программная передача параметров для сложных ключей

Если у регистра сложный ключ (много измерений), передать один массив ссылок может быть недостаточно. Выясним, как поступить в случае с 12 измерениями, о которых упоминалось в обсуждении. Рассмотрим вариант с конкатенацией ключей или проверкой по нескольким массивам.

Проанализируем программный код, который обновляет параметры списка после загрузки данных:


&НаСервере
Процедура ОбновитьПодсветкуСписка(МассивУникальныхКлючей)
    
    // Получаем схему или текст запроса
    Текст = Список.ТекстЗапроса;
    
    // Если нужно динамически менять условие, можно использовать СтрЗаменить
    // Но правильнее один раз прописать параметр в запросе через ВЫБОР
    
    // Устанавливаем параметр - список ключей
    Список.Параметры.УстановитьЗначениеПараметра("МассивКлючей", МассивУникальныхКлючей);
    
КонецПроцедуры

Если сравнение в запросе по 12 полям через И слишком громоздкое, можно сформировать уникальный идентификатор строки в самом запросе. Выглядеть это может так:


ВЫБРАТЬ
    *,
    ВЫБОР 
        КОГДА (Номенклатура.Код + "_" + Сделка.Номер) В (&МассивСоставныхКлючей) 
            ТОГДА ИСТИНА 
        ИНАЧЕ ЛОЖЬ 
    КОНЕЦ КАК ПометкаРаскраски
ИЗ
    РегистрСведений.ВашРегистр

Важно: Будьте осторожны с производительностью при использовании строковой конкатенации в запросах динамических списков, так как это может привести к замедлению работы при больших объемах данных. Оптимально использовать индексированные поля.

Решение 3: Программная настройка Условного оформления

После того как мы добавили поле ПометкаРаскраски в запрос, нам нужно заставить интерфейс реагировать на него. Рассмотрим, как программно добавить элемент условного оформления, чтобы не заставлять пользователя настраивать его вручную через «Еще - Настроить список».

Разберем пример кода, который следует разместить в процедуре ПриСозданииНаСервере или вызвать после обновления данных:


&НаСервере
Процедура НастроитьОформлениеСписка()
    
    // Очистим старые элементы оформления, если они были созданы программно
    УдаляемыеЭлементы = Новый Массив;
    Для Каждого Элемент Из Список.КомпоновщикНастроек.ФиксированныеНастройки.УсловноеОформление.Элементы Цикл
        Если Элемент.Представление = "ПодсветкаДублей" Тогда
            УдаляемыеЭлементы.Добавить(Элемент);
        КонецЕсли;
    КонецЦикла;
    
    Для Каждого Элемент Из УдаляемыеЭлементы Цикл
        Список.КомпоновщикНастроек.ФиксированныеНастройки.УсловноеОформление.Элементы.Удалить(Элемент);
    КонецЦикла;

    // Создаем новый элемент оформления
    ЭлементОформления = Список.КомпоновщикНастроек.ФиксированныеНастройки.УсловноеОформление.Элементы.Добавить();
    ЭлементОформления.Представление = "ПодсветкаДублей";
    
    // Устанавливаем цвет фона
    ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ЦветФона", WebЦвета.СветлоЗеленый);
    
    // Настраиваем условие: ПометкаРаскраски Равно Истина
    ЭлементУсловия = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    ЭлементУсловия.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ПометкаРаскраски");
    ЭлементУсловия.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
    ЭлементУсловия.ПравоеЗначение = Истина;
    ЭлементУсловия.Использование = Истина;
    
    // Указываем, какие поля оформлять (или не добавляем поля, чтобы красить всю строку)
    ПолеОформления = ЭлементОформления.Поля.Элементы.Добавить();
    ПолеОформления.Поле = Новый ПолеКомпоновкиДанных("Номенклатура");
    ПолеОформления.Использование = Истина;

КонецПроцедуры

Нюансы работы с большими объемами данных

Рассмотрим ситуацию, когда количество раскрашиваемых строк очень велико. Если передать в параметр &МассивКлючей десятки тысяч элементов, запрос может выполняться медленно или даже вызвать ошибку переполнения параметров SQL. В таких случаях проанализируем альтернативный путь:

  1. Временные таблицы: К сожалению, динамический список напрямую не поддерживает внешние временные таблицы.
  2. Дополнительный реквизит формы: Можно использовать невидимую колонку в таблице на форме, но это работает только для ТаблицыЗначений, а не для ДинамическогоСписка.
  3. Динамическое построение текста ГДЕ: Вместо одного параметра можно программно генерировать длинное условие ВЫБОР КОГДА (Условие1) ИЛИ (Условие2) ..., но это крайняя мера, так как она сильно усложняет текст запроса.

Для большинства задач метод с виртуальным полем ВЫБОР КОГДА ... КАК Пометка и передачей массива идентификаторов в параметры является наиболее сбалансированным и правильным с точки зрения архитектуры управляемых форм.

Выясним также, почему автор темы не мог использовать стандартное поле Пометка. В его регистре это поле уже занято бизнес-логикой. Это еще раз подтверждает, что создание собственного именованного расчетного поля в тексте запроса — это единственный путь, позволяющий избежать конфликтов с существующими данными и не загромождать структуру метаданных конфигурации.

Заключение

Подведем итоги. Чтобы раскрасить строки динамического списка по «внешнему» условию, мы:

  1. Включаем произвольный запрос в настройках динамического списка.
  2. Добавляем в ВЫБРАТЬ новое поле, используя конструкцию ВЫБОР и параметры.
  3. В программном коде формы устанавливаем значения этих параметров (например, список загруженных объектов).
  4. Через КомпоновщикНастроек.ФиксированныеНастройки создаем правило оформления, привязанное к нашему новому полю.

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

← На главную