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