Почему не работает отбор в программном условном оформлении и как это исправить

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

Программное создание условного оформления — это мощный инструмент, позволяющий динамически изменять визуальное представление данных в формах 1С. Однако при его реализации разработчики часто сталкиваются с ситуацией, когда оформление либо не применяется вовсе, либо применяется ко всем строкам без учета фильтров. Рассмотрим подробно причины возникновения таких ошибок и разберем правильную методику настройки УсловногоОформления для динамических списков.

Разбор типичных ошибок в типах данных

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


ЭлементУсловия.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("мтаПредполагаемаяДатаСменыСтатуса");
ЭлементУсловия.ВидСравнения = ВидСравненияКомпоновкиДанных.МеньшеИлиРавно;
ЭлементУсловия.ПравоеЗначение = Формат(НачалоДня(ТекущаяДата()), "ДФ=dd.MM.yyyy");

В данном примере разработчик пытается сравнить типизированное поле даты с результатом функции Формат(), которая возвращает строку. В системе компоновки данных (СКД), на базе которой работает условное оформление динамического списка, сравнение даты со строкой будет либо выдавать ошибку, либо работать некорректно. Важный момент: всегда передавайте в ПравоеЗначение объект того же типа, который имеет поле в базе данных. Если это дата — передавайте Дата, если ссылка — СправочникСсылка.

Особенности сравнения со списками значений

Вторая критическая ошибка заключается в использовании неверного вида сравнения. Разберем ситуацию: если мы хотим проверить, что значение поля не входит в определенный набор, мы создаем СписокЗначений. Однако стандартный оператор НеРавно не предназначен для работы с коллекциями.

Рассмотрим, как это должно быть реализовано правильно:


СписокСтатусов = Новый СписокЗначений;
СписокСтатусов.Добавить(Перечисления.СтатусыСделок.Выиграна);
СписокСтатусов.Добавить(Перечисления.СтатусыСделок.Проиграна);

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

Использование ВидСравненияКомпоновкиДанных.НеВСписке или ВидСравненияКомпоновкиДанных.ВСписке — это единственный корректный способ сопоставить значение поля с массивом или списком значений в оформлении.

Работа с пустыми датами и временем

Проанализируем поведение системы при использовании условия МеньшеИлиРавно для дат. Нужно учитывать два технических нюанса:

  1. Пустые значения: В 1С пустая дата (01.01.0001) всегда считается меньше любой заполненной даты. Если в вашем списке есть записи с незаполненной датой, они всегда будут окрашиваться по условию "Меньше или равно ТекущаяДата". Чтобы избежать этого, необходимо добавлять дополнительное условие Заполнено.
  2. Состав даты: Если поле в базе содержит время, а вы сравниваете его с НачалоДня(ТекущаяДата()), то записи за сегодняшний день со временем 10:00:00 не попадут в условие МеньшеИлиРавно, так как они фактически больше, чем 00:00:00. В таких случаях рекомендуется использовать КонецДня(ТекущаяДата()).

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

Выясним причину, по которой оформление может игнорироваться, даже если код написан без синтаксических ошибок. Условное оформление динамического списка выполняется на уровне сервера. Для того чтобы условие "отработало", поле, указанное в ПолеКомпоновкиДанных, должно физически присутствовать в выборке запроса.

Проанализируем следующие рекомендации:

Алгоритм правильного программного добавления оформления

Рассмотрим полный и корректный пример кода, который учитывает все вышеперечисленные аспекты. Мы будем добавлять оформление в начало коллекции, чтобы обеспечить его приоритет над другими правилами.


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

// 2. Создаем новый элемент оформления
ЭлементУО = ЭтаФорма.Список.УсловноеОформление.Элементы.Добавить();
ЭлементУО.Представление = ПредставлениеУО;

// 3. Указываем поля, которые будут раскрашиваться
ПоляОформления = "Статус, Клиент, мтаПредполагаемаяДатаСменыСтатуса";
МассивПолей = СтрРазделить(ПоляОформления, ", ", Ложь);
Для Каждого ИмяПоля Из МассивПолей Цикл
    ПолеОформления = ЭлементУО.Поля.Элементы.Добавить();
    ПолеОформления.Поле = Новый ПолеКомпоновкиДанных(ИмяПоля);
    ПолеОформления.Использование = Истина;
КонецЦикла;

// 4. Формируем группу условий (И)
ГруппаУсловий = ЭлементУО.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
ГруппаУсловий.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ;

// Условие 1: Дата меньше или равна концу сегодняшнего дня
ЭлементУсловия = ГруппаУсловий.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементУсловия.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("мтаПредполагаемаяДатаСменыСтатуса");
ЭлементУсловия.ВидСравнения = ВидСравненияКомпоновкиДанных.МеньшеИлиРавно;
ЭлементУсловия.ПравоеЗначение = КонецДня(ТекущаяДата());

// Условие 2: Дата заполнена (чтобы не красить пустые)
ЭлементУсловия = ГруппаУсловий.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементУсловия.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("мтаПредполагаемаяДатаСменыСтатуса");
ЭлементУсловия.ВидСравнения = ВидСравненияКомпоновкиДанных.Заполнено;

// Условие 3: Статус не в списке исключений
СписокИсключений = Новый Массив;
СписокИсключений.Добавить(Перечисления.СтатусыСделок.Выиграна);
СписокИсключений.Добавить(Перечисления.СтатусыСделок.Проиграна);

ЭлементУсловия = ГруппаУсловий.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементУсловия.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Статус");
ЭлементУсловия.ВидСравнения = ВидСравненияКомпоновкиДанных.НеВСписке;
ЭлементУсловия.ПравоеЗначение = СписокИсключений;

// 5. Устанавливаем оформление (цвет фона)
ЭлементУО.Оформление.УстановитьЗначениеПараметра("ЦветФона", WebЦвета.СветлоКоралловый);

Приоритет оформления

Проанализируем ситуацию, когда несколько правил накладываются друг на друга. В 1С применяется то правило, которое находится ниже в списке (коллекции) элементов условного оформления. Если ваше программное оформление перекрывается стандартным, используйте метод Вставить(0) вместо Добавить(), чтобы поместить правило в начало списка, или наоборот, убедитесь, что оно находится в конце, если оно должно быть самым приоритетным.

Также стоит помнить, что условное оформление формы (ЭтаФорма.УсловноеОформление) имеет приоритет над условным оформлением динамического списка. Если вы не можете добиться результата, проверьте, не заданы ли противоречащие правила на уровне всей формы в конфигураторе.

Подведем итог: для корректной работы программного оформления необходимо строго соблюдать типы данных, правильно выбирать виды сравнения для списков и гарантировать наличие полей в выборке данных. Использование КонецДня() для дат и проверка на Заполнено позволят избежать ложных срабатываний оформления.

← На главную