При разработке отчетов в системе 1С:Предприятие, особенно на платформе с использованием обычных форм, программисты часто сталкиваются с необходимостью визуального выделения данных. Одной из самых распространенных задач является раскрашивание ячеек в зависимости от их содержимого — например, выделение пустых полей, отрицательных остатков или критических показателей. В этой статье мы подробно разберем, как реализовать этот механизм программно при ручном выводе макета, учитывая, как устроена объектная модель печатной формы.
Рассмотрим стандартную ситуацию: у нас есть макет и код в модуле объекта или обработки, который в цикле обходит выборку данных и выводит их в табличный документ. Начинающие разработчики часто пытаются использовать свойство АвтоОтметкаЗаполненного или обращаться к ТекущаяОбласть табличного документа. Однако такой подход не дает нужной гибкости, а ТекущаяОбласть не всегда указывает на ту ячейку, которая была только что выведена.
Проанализируем типичную ошибку в коде:
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
ОбластьДетальныхЗаписей.Параметры.Заполнить(ВыборкаДетальныеЗаписи);
Если ЗначениеЗаполнено(ВыборкаДетальныеЗаписи.Стеллаж2) Тогда
ТабДок.ТекущаяОбласть.ЦветФона = WebЦвета.Черный;
КонецЕсли;
ТабДок.Вывести(ОбластьДетальныхЗаписей);
КонецЦикла;
В данном примере свойство ТекущаяОбласть может сработать некорректно, так как оно относится к выделенной области в окне редактора, а не к конкретной строке, которая только что была добавлена в отчет. Для правильного решения нам нужно получить доступ именно к тому объекту области, который «приземлился» в итоговый табличный документ. Если вы разрабатываете расширение для типовой конфигурации, изучите корректный пример внешней печатной формы на БСП, чтобы правильно встроить свой алгоритм в общую логику печати.
Выясним причину, почему метод Вывести() (и его собрат Присоединить()) являются ключевыми. Согласно синтакс-помощнику 1С, эти методы не просто копируют данные из макета в документ, они возвращают объект типа ОбластьЯчеекТабличногоДокумента. Именно с этим объектом нам и нужно работать.
Рассмотрим правильный алгоритм действий по шагам:
Посмотрим на пример реализации этой логики:
ЧерныйЦвет = WebЦвета.Черный;
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// Подготавливаем область из макета
ОбластьДетали = Макет.ПолучитьОбласть("Детали");
ОбластьДетали.Параметры.Заполнить(ВыборкаДетальныеЗаписи);
// Выводим область и получаем ссылку на нее в итоговом документе
ТекОбласть = ТабДок.Вывести(ОбластьДетали);
// Проверяем условие: если поле "Стеллаж2" не заполнено
Если Не ЗначениеЗаполнено(ВыборкаДетальныеЗаписи.Стеллаж2) Тогда
// Красим именно ту область, которую только что вывели
ТекОбласть.ЦветФона = ЧерныйЦвет;
КонецЕсли;
КонецЦикла;
Если в вашем отчете тысячи строк, программное изменение свойств каждой ячейки через ЦветФона может привести к замедлению формирования документа. Разберем более производительный способ. Мы можем заранее создать в макете два варианта одной и той же строки: одну обычную, а другую — с уже настроенным цветом фона (например, серым или красным).
В таком случае код будет выглядеть следующим образом:
ОбластьОбычная = Макет.ПолучитьОбласть("Строка");
ОбластьЦветная = Макет.ПолучитьОбласть("Строка_Цветная");
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Если УсловиеТогда
ВыводимаяОбласть = ОбластьЦветная;
Иначе
ВыводимаяОбласть = ОбластьОбычная;
КонецЕсли;
ВыводимаяОбласть.Параметры.Заполнить(ВыборкаДетальныеЗаписи);
ТабДок.Вывести(ВыводимаяОбласть);
КонецЦикла;
Этот метод работает быстрее, так как 1С не приходится генерировать новые свойства объектов в памяти на каждой итерации цикла; она просто копирует уже готовый шаблон с заданным оформлением.
Использование WebЦвета.Черный или конструктора Новый Цвет(R, G, B) — это рабочие варианты, но не всегда лучшие с точки зрения дизайна. Для того чтобы отчет выглядел нативно в интерфейсе 1С, рекомендуется использовать Цвета стиля. Например, ЦветаСтиля.ПолеВыбораЦветФона или ЦветаСтиля.ТекстОшибки. Это позволит оформлению отчета автоматически подстраиваться под цветовую схему, выбранную пользователем в операционной системе или настройках платформы.
Иногда возникают ситуации, когда решение о покраске ячейки можно принять только после того, как весь отчет уже сформирован (например, если условие зависит от итоговой суммы в подвале). В этом случае мы можем использовать обращение к ячейкам по их координатам через метод Область().
Рассмотрим подробнее, как это сделать:
// Предположим, мы знаем, что нужные данные находятся в 5-й колонке
Для НомерСтроки = НачальнаяСтрока По ТабДок.ВысотаТаблицы Цикл
ТекущаяЯчейка = ТабДок.Область(НомерСтроки, 5, НомерСтроки, 5);
Если ТекущаяЯчейка.Текст = "" Тогда
ТекущаяЯчейка.ЦветФона = Новый Цвет(255, 0, 0); // Красный
КонецЕсли;
КонецЦикла;
Этот метод позволяет гибко управлять оформлением уже готового документа, однако стоит помнить, что ТабДок.ВысотаТаблицы возвращает общее количество строк, включая заголовки и подвалы, поэтому важно правильно определить диапазон строк для обхода.
Несмотря на то что обсуждаемая тема касается ручного вывода макета, важно упомянуть, что современным стандартом разработки в 1С является использование Системы компоновки данных (СКД). Даже на обычных формах можно запустить отчет на базе СКД. В ней существует вкладка Условное оформление, где все вышеописанные задачи решаются без единой строки кода.
Для тех, кому необходимо программно управлять структурой отчетов, существует специальный инструмент СКДБилдер, который значительно упрощает и сокращает код создания схем. Если стандартных возможностей не хватает, можно применить пользовательскую СКД для расширения функций на стороне клиента. Также СКД позволяет решать более сложные задачи оформления, например, когда требуется склейка нескольких картинок в одну ячейку или специфическое изменение заголовка группировки. Платформа сама позаботится о максимально быстром и корректном выводе данных.
При интенсивном раскрашивании больших объемов данных (десятки тысяч строк) графический движок 1С может начать «подтормаживать». Чтобы избежать этого, воспользуйтесь следующими рекомендациями:
ТабДок.Обновление(Ложь), а после завершения — ТабДок.Обновление(Истина). Это запретит программе перерисовывать таблицу при добавлении каждой новой строки.ТабДок.Область(НомерСтроки, , НомерСтроки, ), чтобы получить всю строку как один объект и присвоить ей цвет одним действием.ЗначениеЗаполнено() или сравнение с Неопределено/Null, так как прямая проверка на пустую строку не всегда корректна для ссылочных типов.Проанализировав все способы, мы видим, что наиболее надежным и простым для ручного вывода является метод захвата области через возвращаемое значение Вывести(). Это дает полный контроль над каждой ячейкой в процессе формирования отчета и позволяет создавать профессиональные, информативные документы для пользователей.