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