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

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

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

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


// Такой код НЕ БУДЕТ работать
Область.Параметры.МойПараметр.ЦветФона = WebЦвета.Красный;

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

Решение 1: Изменение цвета ячейки по координатам после вывода

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

Выясним причину, по которой первоначальный подход не работает. Когда вы получаете область из макета с помощью метода ПолучитьОбласть(), вы работаете с шаблоном, а не с конкретной ячейкой в итоговом документе. Свойства этого шаблона можно менять, но это затронет все последующие выводы этой области. Нам же нужно менять цвет конкретной ячейки, уже размещенной на "холсте" табличного документа.

Рассмотрим по шагам, как это реализовать:

  1. Подготовка макета. В макете должна быть одна именованная область для ячейки, которую мы будем выводить в цикле. Не нужно создавать 31 ячейку для каждого дня месяца. Достаточно одной, например, с именем "День".
  2. Организация цикла вывода. В коде мы организуем цикл (например, по дням месяца). На каждой итерации мы будем заполнять и выводить нашу область "День".
  3. Отслеживание координат. Внутри цикла нам нужно знать, в какую строку и колонку была выведена ячейка. Для этого можно использовать переменные-счетчики.
  4. Вывод области. Используем метод ТабДок.Вывести(Область) или ТабДок.Присоединить(Область).
  5. Получение ячейки по координатам. Сразу после вывода получаем объект ячейки из табличного документа: ЯчейкаДляРаскраски = ТабДок.Область(НомерСтроки, НомерКолонки);.
  6. Проверка условия и установка цвета. Проверяем наше условие (например, день недели — суббота или воскресенье) и, если оно истинно, устанавливаем свойство ЦветФона.

Посмотрим на пример. Допустим, нам нужно вывести календарь на месяц и раскрасить выходные дни (субботу и воскресенье) серым цветом.

В макете есть область "Шапка" и область "День" (состоящая из одной ячейки).


ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("МойМакет");

// Получаем области-шаблоны из макета
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьДень = Макет.ПолучитьОбласть("День");

// Заполняем и выводим шапку
// ... код заполнения шапки ...
ТабДок.Вывести(ОбластьШапка);

// Запоминаем номер текущей строки в табличном документе
// ТабДок.ВысотаТаблицы возвращает количество строк
НомерТекущейСтроки = ТабДок.ВысотаТаблицы + 1;
НомерТекущейКолонки = 1;

ДатаНачала = НачалоМесяца(ТекущаяДата());
ДатаОкончания = КонецМесяца(ТекущаяДата());

Для Сч = 1 По День(ДатаОкончания) Цикл
    
    ТекущаяДатаДня = ДатаНачала + (Сч - 1) * 86400; // 86400 секунд в дне
    ДеньНеделиЧисло = ДеньНедели(ТекущаяДатаДня);

    // Заполняем параметр нашей ячейки
    ОбластьДень.Параметры.НомерДня = Формат(Сч, "ЧЦ=2; ЧВН=");
    
    // Выводим область с днем. Используем Присоединить, чтобы ячейки шли в ряд
    ТабДок.Присоединить(ОбластьДень);
    
    // Проверяем условие для раскраски
    Если ДеньНеделиЧисло = 6 Или ДеньНеделиЧисло = 7 Тогда // 6 - Суббота, 7 - Воскресенье
    
        // Получаем только что выведенную область по координатам
        // Номер строки у нас фиксирован, а колонка увеличивается
        ОбластьДляРаскраски = ТабДок.Область(НомерТекущейСтроки, НомерТекущейКолонки);
        
        // Устанавливаем цвет фона
        ОбластьДляРаскраски.ЦветФона = WebЦвета.СветлоСерый;
        
        // Для наглядности можно и цвет текста поменять
        ОбластьДляРаскраски.ЦветТекста = WebЦвета.Красный;
        
    КонецЕсли;
    
    // Увеличиваем счетчик колонок для следующей ячейки
    НомерТекущейКолонки = НомерТекущейКолонки + 1;
    
КонецЦикла;

ТабДок.Показать();

В этом примере ключевой момент — это получение области через ТабДок.Область(R, C) уже после того, как она была добавлена в итоговый документ методами Вывести или Присоединить. У этой, уже выведенной, области свойство ЦветФона доступно для записи.

Для установки цвета можно использовать объект Новый Цвет(R, G, B) или предопределенные цвета из коллекций WebЦвета и ЦветаСтиля.

Решение 2: Использование условного оформления

Это более современный, гибкий и "правильный" способ, особенно при работе со сложными отчетами или при формировании печатных форм на основе Системы Компоновки Данных (СКД). Суть метода в том, что мы не раскрашиваем ячейки вручную в цикле, а задаем правила оформления для всего табличного документа. Система сама применит эти правила к нужным ячейкам при отображении документа.

Преимущества условного оформления:

Как это работает на программном уровне:

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


// Создаем табличный документ
ТабДок = Новый ТабличныйДокумент;
// ...здесь идет код по заполнению и выводу областей в ТабДок...

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

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

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

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

ТабДок.Показать();

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

Важный совет по архитектуре макета: "Одна ячейка, Карл!"

В ходе обсуждения на форуме был поднят важный архитектурный вопрос. Часто разработчики создают в макете избыточное количество ячеек: 31 ячейку для дней, 12 для месяцев и так далее. Это плохая практика.

Правильный подход: макет должен содержать минимальное количество атомарных, переиспользуемых областей. Для календаря достаточно одной области "День". В коде вы организуете цикл от 1 до 31 (или до нужного числа дней в месяце) и на каждой итерации выводите эту одну и ту же область с разными параметрами. Это делает макет чистым, а логику вывода — гибкой и легко управляемой. В качестве готового примера реализации календаря и смен можно использовать печатную форму графика работы.

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

← На главную