Как программно убрать или зафиксировать условное оформление в динамическом списке?

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

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

Суть проблемы: конфликт программного и пользовательского оформления

Представим ситуацию: в конфигураторе для динамического списка настроено некоторое условное оформление. В процессе доработки мы решаем, что это оформление нужно изменить или удалить программно. Мы пишем код, который очищает коллекцию элементов оформления. Все работает, пока пользователь не зайдет в меню «Ещё» и не выберет пункт «Установить стандартные настройки».

В этот момент платформа сбрасывает все наши программные изменения, сделанные в контексте пользовательских настроек, и возвращает то состояние, которое было задано в метаданных (в конфигураторе). В результате наше программное оформление слетает, а «старое» возвращается.

Давайте разберемся, как правильно управлять этим процессом, какие существуют коллекции условного оформления и как на это влияют версии платформы.

Разделение понятий: Оформление Формы vs Оформление Списка

Прежде чем писать код очистки, мы должны четко понимать, с какой коллекцией работаем. В управляемой форме существуют два независимых механизма:

  1. Условное оформление формы (ЭтаФорма.УсловноеОформление). Это глобальные настройки, которые применяются ко всем элементам формы. Если вы добавите правило сюда, оно будет работать поверх всего и пользователь не сможет его отключить через настройки списка.
  2. Настройки компоновки данных списка (Список.КомпоновщикНастроек.Настройки.УсловноеОформление). Это настройки конкретного динамического списка. Именно с ними работает пользователь через команду «Настроить список».

Частая ошибка — пытаться искать настройки списка в коллекции формы или наоборот. Если наша задача — убрать то, что настроено в свойствах Динамического Списка в конфигураторе, нам нужно обращаться к Компоновщику Настроек.

Вариант 1: Очистка настроек при создании формы

Самый логичный способ избавиться от предустановленного оформления — очистить его в момент инициализации формы. Для этого используем событие ПриСозданииНаСервере.

Код для очистки коллекции условного оформления конкретного списка будет выглядеть так (кстати, существует инструмент для автоматической генерации кода условного оформления — поможет инструмент автоматической генерации кода условного оформления для 1С):


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // Обращаемся к настройкам компоновщика данных списка
    // Список - это имя реквизита типа ДинамическийСписок на форме
    Список.КомпоновщикНастроек.Настройки.УсловноеОформление.Элементы.Очистить();
КонецПроцедуры

Этот код удаляет все правила оформления, заданные разработчиком в конфигураторе для этого списка.

Проблема версий платформы (Баг 8.3.18)

В ходе обсуждения данной темы выяснилось важное обстоятельство. На некоторых версиях платформы (в частности, упоминается 8.3.18) существовала ошибка поведения. Даже если вы вызывали метод Очистить() в процедуре ПриСозданииНаСервере, коллекция визуально очищалась, но при отрисовке формы или при определенных действиях пользователя "фантомные" настройки могли возвращаться или не применяться корректно. Для диагностики подобных конфликтов пригодится анализ конфигурации для выявления переопределений логики.

Из-за этого разработчикам приходилось прибегать к экзотическим решениям, используя события загрузки настроек:


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

Однако, как подтверждает практика, на актуальных версиях платформы (например, 8.3.25 и новее) этот баг исправлен. Стандартная очистка в ПриСозданииНаСервере работает корректно и надежно удаляет оформление, заданное в конфигураторе.

Вывод: Если ваш код очистки не срабатывает, первым делом проверьте версию платформы, на которой запускается сервер предприятия — для этого есть инструмент для отладки кода и поиска ошибок.

Вариант 2: Использование Фиксированных настроек (Рекомендуемый подход)

Если ваша цель — не просто удалить старое, а навязать свое "неудаляемое" оформление, то попытка бороться с пользовательскими настройками (которые сбрасываются кнопкой "Стандартные настройки") — это путь сопротивления.

В платформе 1С предусмотрен специальный механизм для таких задач — Фиксированные настройки. Настройки, помещенные в эту коллекцию:

  1. Применяются всегда.
  2. Не видны пользователю в окне настроек.
  3. Не удаляются при нажатии "Установить стандартные настройки".

Давайте посмотрим, как правильно внедрить свое условное оформление через фиксированные настройки:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // 1. Сначала очищаем обычные настройки, если нужно убрать "мусор" из конфигуратора
    Список.КомпоновщикНастроек.Настройки.УсловноеОформление.Элементы.Очистить();
    
    // 2. Создаем свое "вечное" оформление
    ЭлементУО = Список.КомпоновщикНастроек.ФиксированныеНастройки.УсловноеОформление.Элементы.Добавить();
    
    // Настраиваем оформление (например, красим фон в Красный)
    ПолеОформления = ЭлементУО.Оформление.Элементы.Найти("BackColor");
    ПолеОформления.Значение = WebЦвета.Красный;
    ПолеОформления.Использование = Истина;
    
    // Условие (например, Сумма > 1000)
    ЭлементОтбора = ЭлементУО.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Сумма");
    ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Больше;
    ЭлементОтбора.ПравоеЗначение = 1000;
    ЭлементОтбора.Использование = Истина;
    
    // К каким полям применять
    ПолеОформления = ЭлементУО.Поля.Элементы.Добавить();
    ПолеОформления.Поле = Новый ПолеКомпоновкиДанных("Сумма");
    ПолеОформления.Использование = Истина;
    
КонецПроцедуры

Вариант 3: Блокировка доступа к настройке

Иногда нам нужно, чтобы пользователь видел настройку, но не мог её удалить. В этом случае мы можем управлять свойством РежимОтображения (ViewMode) для конкретного элемента условного оформления.

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


// Создаем элемент в обычных настройках (чтобы пользователь его видел)
ЭлементУО = Список.КомпоновщикНастроек.Настройки.УсловноеОформление.Элементы.Добавить();

// ... настройка цветов и отборов (как в примере выше) ...

// Устанавливаем режим отображения
// Недоступный - пользователь видит галочку, но она "серая", снять нельзя
ЭлементУО.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;

Резюме решения

Чтобы решить проблему автора темы (убрать старое условное оформление и наложить свое, чтобы оно не слетало):

  1. Обновите платформу. Если вы используете старые релизы (например, 8.3.18), механизм очистки в ПриСозданииНаСервере может работать некорректно. Переход на 8.3.25 и выше устраняет эту ошибку.
  2. Используйте правильный момент. Очистку старого оформления лучше всего делать в ПриСозданииНаСервере, обращаясь к Список.КомпоновщикНастроек.Настройки.УсловноеОформление.
  3. Используйте Фиксированные Настройки. Если ваше оформление является частью бизнес-логики и не должно отключаться пользователем, добавляйте его не в Настройки, а в ФиксированныеНастройки компоновщика. Это архитектурно более верное решение, чем попытка перехватить события загрузки пользовательских настроек.
← На главную