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

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

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

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

Архитектурная концепция: Разделение данных и интерфейса

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

Цветовое оформление появляется только тогда, когда данные проецируются на форму визуальными элементами:

  1. Табличным полем — в случае использования обычных форм (платформа 1С 8.0, 8.1, 8.2).
  2. Таблицей формы — в случае использования управляемых форм (платформа 1С 8.2, 8.3, 8.5).

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

Оптимальный алгоритм: Проверка по регистру сведений без зависаний

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

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

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

Посмотрим на пример кода, который подготавливает данные на сервере перед выводом их пользователю:


// Пример подготовки данных на сервере
Процедура ЗаполнитьФлагиНаличияВРегистре()
    
    // Переносим данные таблицы формы во временную таблицу для выполнения запроса
    ТаблицаДанных = РеквизитФормыВЗначение("Объект.НашаТаблица");
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |    ВТ_Данные.НомерСтроки КАК НомерСтроки,
        |    ВТ_Данные.Номенклатура КАК Номенклатура
        |ПОМЕСТИТЬ ВТ_ИсходныеДанные
        |ИЗ
        |    &ТаблицаДанных КАК ВТ_Данные
        |;
        |
        |////////////////////////////////////////////////////////////////////////////////
        |ВЫБРАТЬ
        |    ВТ_ИсходныеДанные.НомерСтроки КАК НомерСтроки,
        |    ВЫБОР
        |        КОГДА Рег.Номенклатура ИСПОЛНЯЕТСЯ НЕ НЕОПРЕДЕЛЕНО ТОГДА ИСТИНА
        |        ИНАЧЕ ЛОЖЬ
        |    КОНЕЦ КАК ЕстьВРегистре
        |ИЗ
        |    ВТ_ИсходныеДанные КАК ВТ_ИсходныеДанные
        |    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НашРегистр КАК Рег
        |        ПО ВТ_ИсходныеДанные.Номенклатура = Рег.Номенклатура";
        
    Запрос.УстановитьПараметр("ТаблицаДанных", ТаблицаДанных);
    РезультатЗапроса = Запрос.Выполнить().Выгрузить();
    
    // Переносим полученные флаги обратно в исходную таблицу
    Для Каждого СтрокаРезультата Из РезультатЗапроса Цикл
        СтрокаТЗ = ТаблицаДанных[СтрокаРезультата.НомерСтроки - 1];
        СтрокаТЗ.ЕстьВРегистре = СтрокаРезультата.ЕстьВРегистре;
    КонецЦикла;
    
    // Возвращаем измененные данные на форму
    ЗначениеВРеквизитФормы(ТаблицаДанных, "Объект.НашаТаблица");
    
КонецПроцедуры

Реализация в Управляемых формах (1С 8.3 / 8.2)

В управляемом интерфейсе окрашивание строк реализуется через мощный встроенный механизм платформы — Условное оформление. Рассмотрим подробнее два варианта его настройки: интерактивный и программный.

Вариант 1. Интерактивная настройка условного оформления

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

  1. Откройте форму в конфигураторе и в правом верхнем углу выберите вкладку «Условное оформление».
  2. Нажмите кнопку «Добавить» для создания нового элемента оформления.
  3. В появившемся окне в поле «Оформление» нажмите кнопку выбора. Найдите параметр Цвет фона, установите напротив него флажок и выберите нужный зеленый цвет (например, из палитры Web-цветов или цветов стиля). Нажмите «ОК».
  4. Перейдите к полю «Условие». Добавьте новый элемент отбора. В качестве левого значения выберите поле вашей таблицы Объект.НашаТаблица.ЕстьВРегистре, вид сравнения укажите Равно, а в качестве правого значения установите Истина.
  5. Перейдите к полю «Оформляемые поля». Добавьте туда все колонки вашей таблицы формы. Если вы добавите только одну колонку, окрасится исключительно она. Если добавите все — будет подсвечена вся строка целиком.

Вариант 2. Программная настройка условного оформления

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


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

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

Реализация в Обычных формах (1С 8.0 / 8.1 / 8.2)

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

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

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


Процедура ТабличноеПолеПриПолученииДанных(Элемент, ОформленияСтрок)
    
    // ОформленияСтрок содержит массив объектов оформления только для тех строк,
    // которые в данный момент физически видны на экране пользователя.
    Для Каждого ОформлениеСтроки Из ОформленияСтрок Цикл
        
        // Получаем ссылку на данные текущей строки таблицы значений
        ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки;
        
        // Проверяем, заполнена ли строка и установлен ли наш служебный флаг
        Если ДанныеСтроки <> Неопределено И ДанныеСтроки.ЕстьВРегистре Тогда
            // Устанавливаем мягкий зеленый цвет фона для всей строки
            ОформлениеСтроки.ЦветФона = Новый Цвет(220, 255, 220); 
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры

Решение проблемы с методами выбора строк

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

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

  1. В конфигураторе создается новая общая форма (или форма в рамках обработки), которую мы назовем ФормаВыбораИзТаблицы.
  2. На эту форму помещается таблица (реквизит формы с типом ТаблицаЗначений).
  3. Для таблицы настраивается условное оформление (интерактивно или программно в процедуре ПриСозданииНаСервере, как описано выше).
  4. В форму передается исходная таблица значений в качестве параметра при ее открытии.
  5. При выборе пользователем нужной строки форма закрывается и возвращает выбранное значение (или структуру данных) в вызывающую процедуру через обработчик оповещения.

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

← На главную