При формировании печатных форм или простых отчетов на базе макетов часто возникает задача визуально выделить данные — для этого подойдёт конструктор печатных форм и табличных документов без программирования. Например, подсветить отрицательные остатки красным цветом или выделить жирным шрифтом важные показатели. В отличие от Системы Компоновки Данных (СКД), где это настраивается декларативно, в обычном макете нам необходимо управлять оформлением программно. Рассмотрим подробнее, как это реализовать правильно и каких ошибок стоит избегать.
Прежде чем писать код, проанализируем стандартные возможности платформы 1С. Если ваша задача заключается только в том, чтобы выделить отрицательные числа красным цветом, это можно сделать в самом макете без единой строчки кода. Разберем по шагам:
В этом случае платформа сама применит форматную строку, например, ЧДЦ=2; ЧО=1, и будет отрисовывать отрицательные значения красным цветом автоматически при заполнении параметра.
Если условие оформления сложнее (например, нужно менять цвет фона в зависимости от диапазона значений), нам придется использовать встроенный язык. Рассмотрим типовую ошибку, которую часто совершают разработчики: попытка изменить ячейку в уже выведенном документе по фиксированным координатам.
Выясним причину, почему код ОбластьДанные.Область(5,6).ЦветТекста = WebЦвета.Красный может не работать или работать некорректно. Во-первых, использование жестких координат (5, 6) делает ваш код крайне хрупким — при добавлении любой строки или колонки в макет логика сломается. Во-вторых, крайне важно соблюдать последовательность: Получить область — Заполнить параметры — Изменить оформление — Вывести область.
Проанализируем правильный пример кода:
// 1. Получаем область из макета
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
Пока Выборка.Следующий() Цикл
// 2. Заполняем параметры данными
ОбластьСтрока.Параметры.Топливо = Выборка.Топливо;
ОбластьСтрока.Параметры.Скорость = Выборка.Скорость;
// 3. Проверяем условие и меняем оформление ДО вывода
Если Выборка.Топливо < 0 Тогда
// Обращаемся к конкретной ячейке области по имени или индексу внутри области
ОбластьСтрока.Область("Топливо").ЦветТекста = WebЦвета.Красный;
Иначе
// Не забываем сбрасывать цвет, так как область используется повторно в цикле!
ОбластьСтрока.Область("Топливо").ЦветТекста = WebЦвета.Авто;
КонецЕсли;
// 4. Выводим уже раскрашенную область в итоговый табличный документ
ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;
Чтобы не гадать с индексами колонок (например, Область(1, 2)), мы рекомендуем назначать ячейкам в макете Имена. Обратите внимание: имя ячейки — это не то же самое, что имя параметра. Имя задается в палитре свойств в самом верху.
Посмотрим на пример, как это упрощает разработку:
// Вместо ОбластьДанные.Область(5, 7)
Если ОбластьДанные.Параметры.Скорость < 0 Тогда
ОбластьДанные.Область("ЯчейкаСкорость").ЦветТекста = WebЦвета.Красный;
ОбластьДанные.Область("ЯчейкаСкорость").Шрифт = Новый Шрифт(,,Истина); // Делаем жирным
КонецЕсли;
Использование метода Область("ИмяЯчейки") позволяет вам свободно перемещать колонки в макете, не меняя ни строчки в программном коде.
Иногда возникают ситуации, когда решение об оформлении нужно принять уже после того, как часть документа сформирована. В этом случае программисты используют ТабДок.Область(). Однако, как было замечено в обсуждении, это может привести к появлению пустых строк. Это происходит, если указанные координаты выходят за текущие границы таблицы ТабличныйДокумент.
Рассмотрим, как правильно определить текущую строку для оформления:
// Выводим данные
ТабДок.Вывести(ОбластьСтрока);
// Определяем номер только что выведенной строки
НомерСтроки = ТабДок.ВысотаТаблицы;
// Если нужно оформить конкретную колонку (например, №3) в этой строке
Если Выборка.Значение < 0 Тогда
ТабДок.Область(НомерСтроки, 3, НомерСтроки, 3).ЦветФона = WebЦвета.СветлоЖелтый;
КонецЕсли;
Использование свойства ВысотаТаблицы гарантирует, что вы обращаетесь к последней добавленной строке и не создаете лишних пустых областей в конце документа.
Если вам нужно менять не один параметр (цвет), а сразу целый набор (шрифт, рамки, цвет фона, выравнивание), создавать все эти объекты программно (через Новый Шрифт или Новый Цвет) может быть трудозатратно. В таком случае разберем эффективный прием:
Оформление).Загрузить() или просто копируйте оформление.Проанализируем ситуацию на примере:
ОбластьОбразец = Макет.ПолучитьОбласть("Оформление|Критично");
ТекущаяЯчейка = ОбластьСтрока.Область("Показатель");
Если Значение < Порог Тогда
// Копируем оформление из образца в рабочую область
ТекущаяЯчейка.ЦветТекста = ОбластьОбразец.Область(1,1).ЦветТекста;
ТекущаяЯчейка.Шрифт = ОбластьОбразец.Область(1,1).Шрифт;
ТекущаяЯчейка.ЦветФона = ОбластьОбразец.Область(1,1).ЦветФона;
КонецЕсли;
Подведем итог. Для реализации условного оформления в обычном макете 1С лучше всего использовать либо свойства формата в самом конфигураторе (для простых случаев), либо изменять свойства ячеек в полученной области до того, как она будет выведена методом Вывести(). Это обеспечит максимальную производительность и чистоту кода. При необходимости можно воспользоваться инструментом для формирования шаблонов печатных форм на лету.