Как заставить работать условное оформление в СКД при использовании собственного макета?

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

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

В этой статье мы подробно разберем, почему возникает эта проблема, проанализируем внутренние механизмы платформы «1С:Предприятие 8.3» и рассмотрим несколько эффективных способов решения — от простых декларативных настроек в конфигураторе до гибкого программного перехвата данных в модуле объекта отчета.


Причина проблемы: потеря связи между макетом и полями СКД

Для начала выясним причину, по которой условное оформление «игнорирует» наши собственные макеты. В СКД механизм условного оформления жестко завязан на системные имена полей компоновки данных. Когда отчет формируется автоматически, платформа сама связывает выводимые ячейки с метаданными полей.

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

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


Решение 1. Синхронизация имен параметров макета и полей СКД (Золотое правило)

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

Чтобы восстановить автоматическое сопоставление, нам необходимо придерживаться жесткого правила:

  1. Перейдем в настройки нашего предопределенного макета на вкладке «Макеты».
  2. Найдем параметр соответствующей ячейки.
  3. Переименуем его таким образом, чтобы его имя параметра символ в символ (включая регистр) совпадало с именем поля (или ресурса) в СКД. Например, переименуем параметр Дни в ОтработаноДней.

После этой несложной манипуляции СКД сможет сопоставить ячейку макета с правилом условного оформления, и визуальное отображение заработает автоматически.


Решение 2. Обходной декларативный путь (для составных ячеек-шаблонов)

Часто в табелях учета рабочего времени или шахматках в одной физической ячейке макета выводится сразу несколько показателей через шаблон (например, вид явки и количество часов через косую черту: [ВидЯвки] / [КоличествоЧасов]). В таких случаях сопоставить параметр ячейки с конкретным полем СКД напрямую не удается, так как параметров в ячейке несколько.

В этой ситуации мы можем применить следующий обходной прием:

  1. Откроем настройки условного оформления в СКД (на уровне отчета или конкретной группировки).
  2. В правиле оформления найдем свойство «Оформляемые поля» и полностью очистим его (оставим список пустым). Когда этот список пуст, условное оформление применяется ко всей строке группировки целиком.
  3. Чтобы оформление не окрасило лишние элементы (например, заголовки или соседние колонки), применим это оформление не ко всему отчету, а настроим его внутри конкретной группировки строк или колонок таблицы.
  4. Для возврата некорректно перекрашенных соседних элементов к исходному стилю, создадим дополнительное оформление с противоположным условием для этих конкретных колонок.

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


Решение 3. Сброс пользовательских настроек (Важный нюанс)

Иногда разработчик настраивает макет и условное оформление абсолютно правильно, но при запуске отчета в режиме «1С:Предприятие» изменения не отображаются. Дело в том, что платформа кэширует настройки отчетов для каждого пользователя.

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

В режиме пользователя в форме отчета нажмите кнопку Еще -> Установить стандартные настройки.


Решение 4. Программная постобработка табличного документа

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

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


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // 1. Позволяем системе штатно скомпоновать и вывести результат в ТабличныйДокумент
    КомпоноватьРезультат(ДокументРезультат, ДанныеРасшифровки);
    
    // Отключаем стандартный вывод, так как мы его уже выполнили вручную строкой выше
    СтандартнаяОбработка = Ложь;
    
    // 2. Получаем границы получившейся таблицы
    КоличествоСтрок = ДокументРезультат.ВысотаТаблицы;
    КоличествоКолонок = ДокументРезультат.ШиринаТаблицы;
    
    // 3. Обходим ячейки в цикле для анализа и ручной раскраски
    Для ТекущаяСтрока = 1 По КоличествоСтрок Цикл
        Для ТекущаяКолонка = 1 По КоличествоКолонок Цикл
            
            ОбластьЯчейки = ДокументРезультат.Область(ТекущаяСтрока, ТекущаяКолонка);
            
            // Анализируем текст ячейки (например, ищем заполненные рабочие часы)
            Если ЗначениеЗаполнено(ОбластьЯчейки.Текст) Тогда
                Попытка
                    ЗначениеЧислом = Число(ОбластьЯчейки.Текст);
                    Если ЗначениеЧислом > 0 Тогда
                        // Окрашиваем ячейку с отработанными часами в мягкий зеленый цвет
                        ОбластьЯчейки.ЦветФона = WebЦвета.СветлоЗеленый;
                    КонецЕсли;
                Исключение
                    // Сюда попадем, если в ячейке текст (например, "ОТ" или "В")
                    Если ОбластьЯчейки.Текст = "Я" Тогда
                        ОбластьЯчейки.ЦветФона = WebЦвета.СветлоЖелтый;
                    КонецЕсли;
                КонецПопытки;
            КонецЕсли;
            
        КонецЦикла;
    КонецЦикла;
    
КонецПроцедуры

Преимущества: Абсолютная гибкость, возможность использовать любые сложные алгоритмы анализа содержимого.

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


Решение 5. Программный перехват элементов в процессе компоновки

Более производительный программный метод — вмешательство непосредственно в процесс генерации элементов компоновки до момента их отрисовки в табличном документе. Для этого мы инициализируем процессоры СКД вручную.

Рассмотрим этот профессиональный метод на примере:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    // Инициализируем схему компоновки и настройки
    СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
    НастройкиКомпоновки = КомпоновщикНастроек.ПолучитьНастройки();
    
    // Создаем макет компоновки
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, НастройкиКомпоновки, ДанныеРасшифровки);
    
    // Инициализируем процессор компоновки
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
    
    // Инициализируем процессор вывода
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    
    ПроцессорВывода.НачатьВывод();
    
    Пока Истина Цикл
        
        ЭлементРезультата = ПроцессорКомпоновки.Следующий();
        Если ЭлементРезультата = Неопределено Тогда
            Прервать;
        КонецЕсли;
        
        // Анализируем параметры выводимого элемента
        Если ЭлементРезультата.ЗначенияПараметров.Количество() > 0 Тогда
            Для Каждого ТекущийПараметр Из ЭлементРезультата.ЗначенияПараметров Цикл
                
                // Ищем наш параметр макета
                Если ТекущийПараметр.Имя = "ОтработаноЧасов" И ТипЗнч(ТекущийПараметр.Значение) = Тип("Число") Тогда
                    Если ТекущийПараметр.Значение > 8 Тогда
                        // Если переработка — красим фон элемента оформления в красный цвет
                        ЭлементРезультата.Оформление.УстановитьЗначениеПараметра("ЦветФона", WebЦвета.СветлоКрасный);
                    КонецЕсли;
                КонецЕсли;
                
            КонецЦикла;
        КонецЕсли;
        
        // Выводим элемент в результирующий документ
        ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);
        
    КонецЦикла;
    
    ПроцессорВывода.ЗакончитьВывод();
    
КонецПроцедуры

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


Резюме

Мы подробно разобрали особенности работы условного оформления при наложении собственных макетов в СКД. В большинстве случаев для решения проблемы достаточно соблюдать строгое соответствие имен параметров макета именам полей СКД или правильно распределить настройки по группировкам. Для самых неординарных задач автоматизации всегда можно прибегнуть к программному выводу через ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент.

← На главную