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

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

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

Разберем типичную ошибку при попытке изменить оформление напрямую через элемент формы. Допустим, в обработчике события ПриИзменении для поля таблицы пишется следующий код:


&НаКлиенте
Процедура ЗапасыКоличествоПриИзменении(Элемент)
    Элемент.ЦветФона = WebЦвета.Аквамарин;
КонецПроцедуры

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

Почему нельзя покрасить отдельную ячейку через свойство элемента формы?

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

Единственным штатным механизмом точечной раскраски ячеек является декларативное Условное оформление формы или динамического списка. Но и здесь легко допустить грубую ошибку: очищать и пересоздавать правила условного оформления на сервере каждый раз в обработчике ПриИзменении. Такой подход создает лишние серверные вызовы, провоцирует мерцание интерфейса и сбрасывает кэш отрисовки таблицы. Условное оформление должно создаваться один раз (в конфигураторе или при создании формы на сервере), а управлять подсветкой следует через данные строки.

Рассмотрим два надежных и производительных способа реализации подсветки отредактированных ячеек.

Способ 1. Использование признака изменения (флага) в строке таблицы

Этот способ идеально подходит, если требуется зафиксировать сам факт вмешательства пользователя в поле, даже если он ввел то же самое число повторно.

Разберем реализацию по шагам:

  1. Добавим признак изменения. Это может быть дополнительный реквизит табличной части с типом Булево (например, КоличествоИзменено) в метаданных либо колонка, добавленная чисто динамически на форму через ИзменитьРеквизиты в процедуре ПриСозданииНаСервере, чтобы не менять структуру базы данных.
  2. Настроим условное оформление один раз при открытии формы на сервере.
  3. В клиентском событии ПриИзменении выставим флаг в строке таблицы без лишних серверных вызовов.

Посмотрим на пример программной настройки условного оформления в процедуре ПриСозданииНаСервере:


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

КонецПроцедуры

Теперь рассмотрим клиентский обработчик события поля ввода. Обратите внимание: код выполняется исключительно на клиенте, контекстный серверный вызов не требуется:


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

КонецПроцедуры

Как только в текущей строке свойство КоличествоИзменено принимает значение Истина, механизм условного оформления платформы автоматически и мгновенно перерисовывает ячейку нужным цветом.

Способ 2. Сравнение с исходным значением через скрытую колонку (без кода на клиенте)

Бывают ситуации, когда подсвечивать ячейку нужно только в том случае, если текущее значение реально отличается от того, что было записано в документе изначально. Если пользователь случайно отредактировал строку, а затем вернул старое значение назад — подсветка должна пропасть.

Для решения этой задачи можно использовать сравнение двух полей компоновки данных напрямую в условном оформлении.

  1. В форму добавляется скрытая колонка (например, ИсходноеКоличество с числовым типом), куда при инициализации данных копируются исходные показатели.
  2. Создается правило условного оформления, где поле Количество сравнивается с полем ИсходноеКоличество.

Рассмотрим пример кода для процедуры ПриСозданииНаСервере:


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

КонецПроцедуры

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

← На главную