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

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

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

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

Особенности механизма отрисовки в Обычных формах

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

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

Этап 1. Подготовка данных для раскраски

Чтобы при нажатии на кнопку система «узнала», какие именно ячейки нужно покрасить, нам необходимо создать некий признак в самой таблице. Рассмотрим наиболее надежный способ — использование служебной колонки.

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

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


Процедура КнопкаВыделитьЦветомНажатие(Элемент)
    
    // Перебираем строки нашей таблицы (например, ТчНоменклатура)
    Для Каждого СтрокаТЗ Из Объект.ТчНоменклатура Цикл
        
        // Условие, при котором нужно выделить ячейку
        Если СтрокаТЗ.Количество < 0 Тогда
            СтрокаТЗ.СостояниеЦвета = 1; // Устанавливаем флаг для покраски
        Иначе
            СтрокаТЗ.СостояниеЦвета = 0; // Сбрасываем флаг
        КонецЕсли;
        
    КонецЦикла;
    
    // ВАЖНО: Принудительно заставляем форму перерисовать таблицу, 
    // чтобы сработало событие оформления
    ЭлементыФормы.ТчНоменклатура.Обновить();
    
КонецПроцедуры

Этап 2. Реализация через событие ПриВыводеСтроки

Теперь, когда данные подготовлены и метод Обновить() вызван, платформа начнет отрисовывать каждую строку заново. В этот момент для каждой видимой строки будет вызываться предопределенное событие ПриВыводеСтроки. Именно здесь мы и «покрасим» ячейки.

Выясним, как правильно написать код внутри этого события:


Процедура ТчНоменклатураПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
    
    // Проверяем наш служебный флаг, который мы установили по кнопке
    Если ДанныеСтроки.СостояниеЦвета = 1 Тогда
        
        // Вариант 1: Красим всю строку целиком
        // ОформлениеСтроки.ЦветФона = Новый Цвет(255, 200, 200); // Светло-красный
        
        // Вариант 2: Красим только конкретную ячейку (например, "Количество")
        ОформлениеСтроки.Ячейки.Количество.ЦветФона = Новый Цвет(255, 150, 150);
        
        // Можно также изменить шрифт на жирный
        ОформлениеСтроки.Ячейки.Количество.Шрифт = Новый Шрифт(,,Истина);
        
    Иначе
        // Обязательно сбрасываем оформление к стандартному, 
        // иначе при прокрутке цвета могут "залипнуть"
        ОформлениеСтроки.Ячейки.Количество.ЦветФона = ЦветаСтиля.ЦветФонаПоля;
        ОформлениеСтроки.Ячейки.Количество.Шрифт = Новый Шрифт(,,Ложь);
    КонецЕсли;
    
КонецПроцедуры

Оптимизация: Использование события ПриПолученииДанных

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

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

Пример реализации оптимизированной раскраски:


Процедура ТчНоменклатураПриПолученииДанных(Элемент, ОформленияСтрок)
    
    // ОформленияСтрок - это коллекция объектов ОформлениеСтроки
    Для Каждого Оформление Из ОформленияСтрок Цикл
        
        // Получаем данные текущей строки через свойство ДанныеСтроки
        ТекДанные = Оформление.ДанныеСтроки;
        
        Если ТекДанные.СостояниеЦвета = 1 Тогда
             Оформление.Ячейки.Количество.ЦветФона = Новый Цвет(255, 230, 230);
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры

Почему событие срабатывает несколько раз?

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

  1. При движении курсора мыши над строками таблицы.
  2. При получении или потере фокуса окном приложения.
  3. При изменении размеров окна или колонок.
  4. При любом программном обновлении элементов формы.

Критически важно: Никогда не пишите внутри этих событий «тяжелый» код. Не делайте запросы к базе данных (Новый Запрос), не создавайте сложные объекты и не открывайте модальные окна. Это гарантированно приведет к критическому падению производительности программы.

Советы по управлению цветом

При работе с цветами фона и текста рекомендуется придерживаться следующих правил:

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

← На главную