Как программно изменить цвет строки в табличной части управляемой формы 1С?

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

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

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

Выясняем причину: почему код автора темы не заработал?

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


НовыйЭлементОтбора.Левоезначение = Новый ПолеКомпоновкиДанных("Объект.ОплатаПоРеализациям.СуммаДокументаРасчетов");
НовыйЭлементОтбора.Правоезначение = Новый ПолеКомпоновкиДанных("Объект.ОплатаПоРеализациям.СуммаДолга");
НовыйЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно;

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

В условном оформлении формы в качестве правого значения отбора нельзя указывать другое поле компоновки данных.

Правое значение в отборах управляемой формы всегда должно быть константой (литералом): конкретным числом, строкой, датой, булевым значением или предопределенным элементом справочника/перечисления. Попытка сравнить два динамических поля «на лету» силами одного лишь условного оформления платформой просто игнорируется, и оформление не применяется.

Правильное решение: использование расчетного реквизита

Чтобы обойти это ограничение, мы применим стандартный паттерн разработки в среде 1С: добавим в структуру данных вспомогательный расчетный реквизит (флаг), значение которого будем рассчитывать программно, а условное оформление настроим на сравнение этого флага с константой Истина.

Разберем весь процесс реализации этой задачи по шагам.

Шаг 1. Создание вспомогательного реквизита

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

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

Шаг 2. Расчет значения вспомогательного реквизита

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

Для первоначального заполнения флага при открытии формы создадим на сервере вспомогательную процедуру и вызовем ее в обработчике ПриСозданииНаСервере или ПриЧтенииНаСервере:


&НаСервере
Процедура РасчитатьПризнакРазницыСуммНаСервере()
    
    Для Каждого СтрокаТЧ Из Объект.ОплатаПоРеализациям Цикл
        СтрокаТЧ.СуммыРазличаются = (СтрокаТЧ.СуммаДокументаРасчетов <> СтрокаТЧ.СуммаДолга);
    КонецЦикла;
    
КонецПроцедуры

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


&НаКлиенте
Процедура ОплатаПоРеализациямПриИзмененииРеквизитовСуммы(Элемент)
    
    ТекущаяСтрока = Элементы.ОплатаПоРеализациям.ТекущиеДанные;
    Если ТекущаяСтрока <> Неопределено Тогда
        // Рассчитываем флаг на лету без обращения к серверу
        ТекущаяСтрока.СуммыРазличаются = (ТекущаяСтрока.СуммаДокументаРасчетов <> ТекущаяСтрока.СуммаДолга);
    КонецЕсли;
    
КонецПроцедуры

Укажите эту клиентскую процедуру в качестве обработчика события ПриИзменении для обоих элементов управления колонок на форме.

Шаг 3. Как программно закрасить строку целиком

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

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

При этом важно помнить, что в коллекцию Поля условного оформления формы нужно передавать именно имена элементов формы (колонок), а не пути к их данным.

Шаг 4. Пишем эталонный код настройки условного оформления

Объединим все наши наработки в одну процедуру, которая будет вызываться один раз при создании формы на сервере. Этот код полностью решает проблему, описанную автором темы:


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

Эту процедуру достаточно вызвать один раз в стандартном обработчике управляемой формы:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Инициализируем расчетные значения для существующих строк
    РасчитатьПризнакРазницыСуммНаСервере();
    
    // Настраиваем правила отображения цветов
    УстановитьУсловноеОформлениеРазницыСумм();
    
КонецПроцедуры

Рекомендации стандартов разработки 1С

Для создания качественного и быстродействующего кода придерживайтесь следующих правил:

  1. Однократная настройка: Структуру условного оформления формы (добавление элементов оформления, полей и условий отбора) настраивайте строго один раз при создании формы на сервере. Динамическое добавление новых элементов оформления при интерактивных действиях пользователя существенно снижает производительность интерфейса.
  2. Минимизация серверных вызовов: Все изменения признака СуммыРазличаются при редактировании строк пользователем производите исключительно на клиенте в контексте текущих данных строки. Платформа 1С самостоятельно перерисует цвет строки, как только поменяется значение отслеживаемого реквизита, не требуя повторного обращения к серверу.
  3. Явное использование свойств: Несмотря на то что свойство Использование у вновь создаваемых элементов по умолчанию может быть равно Истина, явное его указание в коде (как для самого элемента оформления, так и для его отборов и полей) страхует от потенциальных сбоев в работе платформы на разных релизах.

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

← На главную