Как изменить шрифт ячейки после вывода области в Табличный Документ 1С?

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

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

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

Почему прямое изменение макета не работает?

Для начала выясним причину проблемы. Когда мы пишем следующий код:


ТабличныйДокумент.Вывести(ОбластьМакета);
ОбластьМакета.ТекущаяОбласть.Шрифт = Новый Шрифт(..., Истина); // Попытка сделать жирным

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

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

Способ 1. Использование возвращаемого значения метода Вывести()

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

Рассмотрим по шагам, как применить этот способ на практике:


// 1. Выводим область и сразу запоминаем ее положение в результирующем документе
ВыведеннаяОбласть = ТабличныйДокумент.Вывести(ОбластьМакета);

// 2. Проверяем условие, при котором нужно изменить шрифт
Если НужноВыделитьЖирным Тогда
    
    // Вариант А: Изменяем шрифт абсолютно у всех ячеек выведенной строки
    ТекущийШрифт = ВыведеннаяОбласть.Шрифт;
    ВыведеннаяОбласть.Шрифт = Новый Шрифт(ТекущийШрифт, , , Истина);
    
    // Вариант Б: Изменяем шрифт только у конкретной колонки в выведенной строке
    // Допустим, нам нужно выделить только Код Номенклатуры во 2-й колонке
    НомерСтроки = ВыведеннаяОбласть.Верх; // Получаем индекс добавленной строки
    ЯчейкаКода = ТабличныйДокумент.Область(НомерСтроки, 2); // Строка, Колонка
    ЯчейкаКода.Шрифт = Новый Шрифт(ЯчейкаКода.Шрифт, , , Истина);
    
КонецЕсли;

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

Способ 2. Определение строки через свойство ВысотаТаблицы

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

Проанализируем пример реализации данного подхода:


// 1. Стандартно выводим область макета в документ
ТабличныйДокумент.Вывести(ОбластьМакета);

// 2. Если условие выполняется, находим только что добавленную строку
Если НужноВыделитьЖирным Тогда
    
    // ВысотаТаблицы возвращает номер последней заполненной строки
    НомерПоследнейСтроки = ТабличныйДокумент.ВысотаТаблицы;
    
    // Получаем область ячеек нужной строки. Например, с 1-й по 5-ю колонку
    ОбластьСтроки = ТабличныйДокумент.Область(НомерПоследнейСтроки, 1, НомерПоследнейСтроки, 5);
    
    // Устанавливаем новое оформление шрифта
    ОбластьСтроки.Шрифт = Новый Шрифт(ОбластьСтроки.Шрифт, , , Истина);
    
КонецЕсли;

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

Способ 3. Оформление ячеек в макете ДО вывода (Best Practice)

С точки зрения производительности системы 1С:Предприятие, изменение свойств ячеек в уже сформированном табличном документе — операция достаточно ресурсоемкая. Если ваш отчет содержит тысячи строк, постоянное переопределение шрифтов "на лету" после вывода может замедлить формирование печатной формы.

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

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

Прием А. Получение чистой области на каждой итерации цикла

Метод ПолучитьОбласть() каждый раз возвращает новый, чистый экземпляр области из исходного макета с первоначальным оформлением:


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

Прием Б. Принудительный сброс оформления в цикле (для высокой производительности)

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


// Получаем шаблон один раз вне цикла
ОбластьСтроки = Макет.ПолучитьОбласть("Строка1");

Пока Выборка.Следующий() Цикл
    ОбластьСтроки.Параметры.Заполнить(Выборка);
    
    // Определяем, нужен ли жирный шрифт (Истина или Ложь)
    ШрифтЖирный = ?(НоменклатураНайдинаВДругомДокументе, Истина, Ложь);
    
    // Принудительно устанавливаем нужное состояние для каждой строки
    ШрифтЯчейки = ОбластьСтроки.Область("Код").Шрифт;
    ОбластьСтроки.Область("Код").Шрифт = Новый Шрифт(ШрифтЯчейки, , , ШрифтЖирный);
    
    ТабличныйДокумент.Вывести(ОбластьСтроки);
КонецЦикла;

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

← На главную