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