Почему не работает условное оформление в таблице СКД и как настроить подсветку ячеек?

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

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

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

Выясняем причину: почему обычное поле игнорируется в условном оформлении кросс-таблицы

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

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

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

---

Решение 1: Преобразование вспомогательного поля в ресурс СКД

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

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

  1. Откроем схему компоновки данных нашего отчета и перейдем на вкладку «Ресурсы».
  2. Перенесем наше поле Понижение в список ресурсов.
  3. В колонке «Выражение» зададим агрегатную функцию. Поскольку наше поле имеет булев тип (Истина/Ложь), для него идеально подойдет функция Максимум(Понижение). Если хотя бы в одной детальной записи за месяц было зафиксировано падение продаж, ресурс вернет значение Истина.
  4. Перейдем на вкладку «Настройки» и выберем элемент структуры «Таблица» (или настроим это на уровне всего отчета).
  5. Перейдем в свойства условного оформления и добавим новое правило:
    • Оформление: Цвет фона — Красный.
    • Условие: Понижение равняется Истина.
    • Оформляемые поля: Выбираем только то поле, которое мы хотим визуально выделить, например, ОбъемПродаж.

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

---

Решение 2: Использование встроенной функции СКД «ВычислитьВыражение»

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

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

Рассмотрим, как настроить такое оформление динамически, без добавления лишних полей в запрос:

  1. Наш SQL-запрос должен быть максимально простым: он должен возвращать только контрагента, месяц и сумму продаж. Никаких проверок на понижение в запросе делать не нужно.
  2. В настройках СКД перейдем в раздел «Условное оформление» и создадим новое правило.
  3. Зададим красный цвет фона в свойствах оформления.
  4. В поле «Условие» добавим условие не по значению поля, а по выражению. Для этого выберем тип условия «Выражение» и запишем формулу сравнения текущего значения с предыдущей колонкой:

Сумма(ОбъемПродаж) < ВычислитьВыражение("Сумма(ОбъемПродаж)", "Месяц", "Группировка", "Предыдущая")

Разберем параметры функции ВычислитьВыражение, которые мы использовали в этой формуле:

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

---

Важные нюансы и подводные камни при работе с условным оформлением

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

Обработка значений NULL: Если за прошлый месяц у контрагента не было продаж вообще, или текущий месяц является самым первым в отчете, функция сравнения вернет значение NULL. Из-за этого логика сравнения может нарушиться. Чтобы этого избежать, всегда оборачивайте числовые показатели в функцию ЕстьNull. Наше выражение для условного оформления примет следующий вид:


ЕстьNull(Сумма(ОбъемПродаж), 0) < ЕстьNull(ВычислитьВыражение("Сумма(ОбъемПродаж)", "Месяц", "Группировка", "Предыдущая"), 0)

Кэширование пользовательских настроек: Часто разработчики вносят изменения в схему компоновки в конфигураторе, запускают отчет в режиме «1С:Предприятие», но визуально ничего не меняется. Это происходит потому, что система кэширует настройки отчета для конкретного пользователя. Чтобы применить новые правила оформления, обязательно выполните сброс настроек в пользовательском режиме, выбрав команду «Еще» -> «Установить стандартные настройки».

---

Альтернативный вариант: Программная раскраска ячеек

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

Для реализации этого метода переопределим процедуру ПриКомпоновкеРезультата в модуле объекта нашего отчета:


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

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

← На главную