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