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

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

При работе с управляемыми формами 1С начинающие разработчики часто сталкиваются с проблемой: при попытке изменить цвет ячейки через свойства элемента формы (например, в обработчике ПриИзменении), окрашивается вся колонка целиком. Это происходит потому, что в управляемом приложении элементы формы (поля ввода в таблице) являются лишь «шаблонами» для отображения данных, а не отдельными объектами для каждой строки. Чтобы выделить конкретную ячейку по условию, необходимо использовать механизм Условного оформления.

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

Почему прямое управление цветом через Элемент не работает?

Проанализируем типичную ошибку. Когда мы пишем Элемент.ЦветТекста = WEBЦвета.Красный; в коде на стороне клиента, мы обращаемся к объекту типа ПолеФормы. Этот объект отвечает за визуальное представление всей колонки. Управляемая форма рисует строки динамически, используя настройки этого объекта для каждой строки. Поэтому, изменив цвет один раз, вы меняете его для всех строк сразу.

Для решения задачи нам нужно передать платформе инструкции: «Рисуй ячейку красным, только если данные в этой конкретной строке соответствуют условию». Эти инструкции хранятся в коллекции УсловноеОформление формы.

Вариант 1: Простое программное добавление условного оформления

Если условие раскраски простое (например, значение в той же строке больше константы), мы можем настроить оформление при создании формы на сервере. Рассмотрим этот процесс по шагам.


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

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

Вариант 2: Использование скрытого реквизита формы в расширениях

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

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

  1. В редакторе формы в расширении добавим новую колонку в таблицу Товары (например, реквизит ПревышенЛимит с типом Булево).
  2. Настроим Условное оформление, где условием будет Товары.ПревышенЛимит Равно Истина.
  3. При изменении количества будем вызывать серверный метод для проверки лимита и установки этого флага.

Рассмотрим пример кода для обработки изменения значения:


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

&НаСервереБезКонтекста
Функция ПроверитьПревышениеНаСервере(Номенклатура, Количество)
    // Здесь выполняем запрос к регистру сведений
    МаксЛимит = РегистрыСведений.ЛимитыПродаж.ПолучитьМаксимум(Номенклатура);
    Возврат Количество > МаксЛимит;
КонецФункции

Вариант 3: Оформление по идентификатору строки (динамическое)

Если вам нужно «подсветить» строку программно в произвольный момент (например, после нажатия кнопки проверки), можно использовать ИдентификаторСтроки. Посмотрим на пример ситуации, когда мы хотим покрасить конкретную строку, зная её индекс.

Важно помнить: номер строки (1, 2, 3...) может измениться при сортировке, поэтому лучше использовать свойство КлючСвязи или внутренний идентификатор.


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

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

Оптимизация производительности

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

Таким образом, мы выяснили, что для оформления ячеек в 1С 8.3 следует всегда использовать Условное оформление, а передавать в него условия лучше всего через скрытые технические реквизиты формы, что особенно актуально при разработке в расширениях.

← На главную