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

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

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

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

Выясняем причину проблемы: почему не получается раскрасить строку напрямую?

Давайте проанализируем ситуацию, с которой столкнулся автор темы. При попытке раскрасить строку кода напрямую через свойства макета-шаблона часто возникает следующая проблема: если мы пишем ОбластьСтрока.ЦветФона = WebЦвета.Красный; перед выводом строки, то один раз окрасив макет, мы получим все последующие строки тоже красного цвета. Это происходит потому, что переменная ОбластьСтрока ссылается на общую область макета-шаблона, изменения в которой применяются ко всем последующим операциям вывода.

Также нередка ошибка Поле объекта не обнаружено (ЦветФона). Она возникает, когда разработчик пытается обратиться к свойству ЦветФона у объекта, который его не поддерживает (например, у параметров макета или некорректно полученного диапазона ячеек).

Давайте последовательно рассмотрим варианты решения этой задачи.

Способ 1. Временное изменение цвета области макета и его восстановление

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

Рассмотрим пример кода, реализующий этот подход:


// 1. Получаем значение константы один раз до начала цикла для экономии ресурсов
КБанки = Константы.Банки.Получить(); 

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

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

Недостатки метода: Если в процессе заполнения параметров или вывода строки внутри блока произойдет непредвиденная ошибка (исключение), код восстановления цвета не отработает. В результате весь оставшийся документ выведется в красном цвете. Кроме того, этот подход заставляет систему лишний раз производить запись свойств в макет-шаблон.

Способ 2. Оформление возвращаемой области после вывода (Рекомендованный способ)

Давайте изучим более надежный и профессиональный инструмент платформы 1С. Метод Вывести() у объекта ТабличныйДокумент не просто переносит данные на экран — он возвращает объект типа ОбластьЯчеекТабличногоДокумента, который представляет собой только что добавленный диапазон строк в результирующем документе.

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


КБанки = Константы.Банки.Получить(); 

Для каждого эл из ТЗБанки Цикл
    // Наполняем макет данными
    ОбластьСтрока.Параметры.ЮрАдрес = эл.ЮрАдрес;
    ОбластьСтрока.Параметры.Банк = эл.Банк;
    ОбластьСтрока.Параметры.ДатаСоздания = эл.ДатаСоздания;
    
    // Выводим строку и сразу получаем ссылку на ее область в итоговом документе
    ВыведеннаяОбласть = ПолеТД.Вывести(ОбластьСтрока);
    
    // Проверяем условие совпадения банка
    Если эл.Банк = КБанки Тогда
        // Раскрашиваем только выведенную область. Макет-шаблон остается нетронутым!
        ВыведеннаяОбласть.ЦветФона = WebЦвета.Красный;
    КонецЕсли;
КонецЦикла;

Преимущества метода: Код избавляется от лишних переменных для сохранения предыдущего состояния цвета. Исключены любые риски искажения исходного макета при возникновении критических ошибок работы программы.

Способ 3. Раскрашивание только определенных колонок (Точечное оформление)

Зачастую перед разработчиком стоит задача закрасить не всю выведенную строку целиком (которая может тянуться через весь лист), а только строго определенный диапазон колонок (например, первые три колонки: «ЮрАдрес», «Банк» и «ДатаСоздания»).

Давайте разберем, как получить точечный доступ к нужным ячейкам на основе координат выведенной строки. Мы воспользуемся свойством Верх полученной области ячеек, чтобы узнать точный номер строки в результирующем табличном документе:


КБанки = Константы.Банки.Получить(); 

Для каждого эл из ТЗБанки Цикл
    ОбластьСтрока.Параметры.ЮрАдрес = эл.ЮрАдрес;
    ОбластьСтрока.Параметры.Банк = эл.Bank;
    ОбластьСтрока.Параметры.ДатаСоздания = эл.ДатаСоздания;
    
    ВыведеннаяОбласть = ПолеТД.Вывести(ОбластьСтрока);
    
    Если эл.Банк = КБанки Тогда
        // Получаем индекс текущей строки в результирующем табличном документе
        НомерТекущейСтроки = ВыведеннаяОбласть.Верх;
        
        // Получаем точную область ячеек с 1-й по 3-ю колонку на текущей строке
        ОбластьОкрашивания = ПолеТД.Область(НомерТекущейСтроки, 1, НомерТекущейСтроки, 3);
        
        // Задаем цвет фона только для выделенного диапазона ячеек
        ОбластьОкрашивания.ЦветФона = WebЦвета.Красный;
    КонецЕсли;
КонецЦикла;

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

Способ 4. Использование двух альтернативных областей макета

Одним из лучших стандартов программирования в 1С является отделение логики визуального оформления от программного кода. Если мы прописываем цвет фона непосредственно в коде (WebЦвета.Красный), то при любом изменении дизайна (например, если заказчик попросит вместо красного цвета сделать шрифт жирным или использовать другой оттенок) нам придется лезть в программный код модуля.

Давайте решим эту задачу более элегантно. В макете отчета создадим две именованные строки:

  1. СтрокаОбычная — стандартная строка с базовым оформлением.
  2. СтрокаВыделенная — строка, у которой в конфигураторе визуально настроен красный фон ячеек, изменены шрифты или рамки по вашему усмотрению.

В коде модуля нам останется лишь динамически выбирать, какую область макета получать на каждой итерации цикла:


КБанки = Константы.Банки.Получить(); 

Для каждого эл из ТЗБанки Цикл
    // Выбираем шаблон макета на основе условия сравнения
    Если эл.Банк = КБанки Тогда
        ТекущаяОбласть = Макет.ПолучитьОбласть("СтрокаВыделенная");
    Иначе
        ТекущаяОбласть = Макет.ПолучитьОбласть("СтрокаОбычная");
    КонецЕсли;
    
    // Заполняем параметры выбранного шаблона
    ТекущаяОбласть.Параметры.ЮрАдрес = эл.ЮрАдрес;
    ТекущаяОбласть.Параметры.Банк = эл.Банк;
    ТекущаяОбласть.Параметры.ДатаСоздания = эл.ДатаСоздания;
    
    // Выводим в табличный документ
    ПолеТД.Вывести(ТекущаяОбласть);
КонецЦикла;

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

Важные нюансы оптимизации кода и производительности базы данных

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

  1. Получение константы вне цикла. Обращение к менеджеру констант и получение их значений (Константы.Банки.Получить()) — это операция чтения из базы данных. Если вы поместите эту строку внутрь цикла Для каждого эл из ТЗБанки Цикл, то при таблице в 10 000 строк система выполнит 10 000 дополнительных запросов к СУБД. Это приведет к колоссальным задержкам. Всегда считывайте константы в переменную до начала выполнения циклов.
  2. Сравнение ссылочных типов. Убедитесь, что тип данных в колонке Банк вашей таблицы значений совпадает с типом значения константы. Если в константе хранится тип СправочникСсылка.Банки, а в таблице значений — текстовая строка с названием банка (например, "ПАО Сбербанк"), то прямое сравнение эл.Банк = КБанки всегда будет возвращать значение Ложь. Сравнивать можно только одинаковые типы данных. Если в таблице значений лежит строка, приводите сравнение к наименованию: эл.Банк = КБанки.Наименование или эл.Банк.Наименование = КБанки.Наименование (при условии, что в ТЗ лежит ссылка другого справочника, имеющая аналогичный реквизит).

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

← На главную