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

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

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

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

Проанализируем типичную ошибку начинающих разработчиков: попытку найти свойство цвета непосредственно у объекта данных (СтрокаТабличнойЧасти или СтрокаТаблицыЗначений). В платформе 1С объекты коллекций данных хранят только прикладные значения (ссылки, числа, строки) и не содержат свойств оформления (таких как ЦветФона или ЦветТекста).

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

Решение для обычных форм: событие ПриПолученииДанных

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

Разберем по шагам реализацию эффективной раскраски:

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

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


// В модуле формы создаем переменную для хранения списка выделяемых позиций
Перем мВыделяемыеПозиции;

Процедура ПриОткрытии()
    мВыделяемыеПозиции = Новый Соответствие;
КонецПроцедуры

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

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

    ЦветПодсветки = Новый Цвет(255, 230, 230); // Светло-красный цвет

    Для Каждого Оформление Из ОформленияСтрок Цикл
        ДанныеСтроки = Оформление.ДанныеСтроки;
        Если ДанныеСтроки = Неопределено Тогда
            Продолжить;
        КонецЕсли;

        // Проверяем наличие номенклатуры в нашем соответствии
        Если мВыделяемыеПозиции[ДанныеСтроки.Номенклатура] <> Неопределено Тогда
            // Устанавливаем цвет фона для всей строки
            Оформление.ЦветФона = ЦветПодсветки;
            
            // При необходимости можно покрасить только конкретную ячейку:
            // Оформление.Ячейки.Номенклатура.ЦветФона = ЦветПодсветки;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Решение для управляемых форм: УсловноеОформление

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

Разберем по шагам алгоритм для управляемой формы:

  1. Формируем объект СписокЗначений, куда помещаем все значения номенклатуры, требующие выделения.
  2. Очищаем предыдущие программно созданные правила или всю коллекцию УсловноеОформление.Элементы, чтобы избежать дублирования условий.
  3. Создаем новый элемент оформления, задаем цвет фона, оформляемые поля и настраиваем отбор по условию вхождения в сформированный список.

Рассмотрим пример кода для управляемой формы:


&НаСервере
Процедура ВыделитьСтрокиПоСпискуНаСервере(МассивНоменклатуры)
    // 1. Формируем список значений для отбора
    СписокДляВыделения = Новый СписокЗначений;
    СписокДляВыделения.ЗагрузитьЗначения(МассивНоменклатуры);

    // 2. Очищаем существующие правила условного оформления (или находим конкретное)
    УсловноеОформление.Элементы.Очистить();

    Если СписокДляВыделения.Количество() = 0 Тогда
        Возврат;
    КонецЕсли;

    // 3. Создаем новый элемент условного оформления
    ЭлементОформления = УсловноеОформление.Элементы.Добавить();

    // Настраиваем оформление: цвет фона
    ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ЦветФона", WebЦвета.СветлоЖелтый);

    // Указываем поля таблицы, которые будут окрашиваться
    ПолеОформления = ЭлементОформления.Поля.Элементы.Добавить();
    ПолеОформления.Поле = Новый ПолеКомпоновкиДанных("ТаблицаДанных");

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

Альтернативный вариант для управляемых форм: реквизит-флаг

Если список строк для выделения формируется сложным алгоритмом или объемы списка номенклатуры слишком велики для передачи в условие отбора, рекомендуется добавить в саму таблицу данных булев реквизит (например, ВыделенаЦветом). В этом случае в таблице формы один раз статически настраивается условное оформление по условию ТаблицаДанных.ВыделенаЦветом Равно Истина, а в коде достаточно лишь проставить значение Истина в нужных строках данных.

← На главную