Работа с Системой компоновки данных (СКД) часто преподносит сюрпризы, особенно когда используется расширенная Пользовательская СКД для построения кросс-таблиц (таблиц с измерениями и в строках, и в колонках). Типичная ситуация: программисту необходимо вывести отчет, где по строкам идет Номенклатура, а по колонкам — Период. При этом в ячейках, где не было движений, должны стоять нули, а сама строка должна окрашиваться в определенный цвет в зависимости от итогового значения ресурса в конце строки.
Основная сложность здесь заключается в том, что СКД генерирует сетку отчета динамически. Если в исходных данных нет записи для конкретной номенклатуры за конкретную дату, то в наборе данных такой записи просто не существует. Это «виртуальная» ячейка, к которой не так просто применить ЕСТЬNULL или условия оформления. В данной статье мы разберем несколько проверенных способов решения этой задачи, применяя стандартный функционал и специализированные инструменты разработчика для тонкого клиента.
Рассмотрим ситуацию: вы пишете запрос к регистру накопления и используете ЕСТЬNULL(СуммаОборот, 0). В консоли запросов вы видите нули, но в отчете СКД (в режиме таблицы) ячейки все равно остаются пустыми. Почему так происходит? Проанализируем механизм работы СКД. Когда система строит таблицу, она берет все уникальные значения строк и все уникальные значения колонок, создавая на их пересечении сетку. Если данных в выборке для конкретного пересечения нет, СКД не применяет к этой пустоте ваш запрос — она просто выводит пустую ячейку.
Самый простой и эффективный способ заставить СКД видеть «ноль» вместо пустоты — это правильно настроить закладку «Ресурсы». Вместо простого выбора поля, укажите агрегатную функцию с проверкой на NULL.
Выполним следующие действия:
Количество) пропишем конструкцию:
ЕстьNULL(Сумма(Количество), 0)
Это заставит систему принудительно возвращать число 0 даже в те ячейки, для которых в базе данных нет соответствующих записей. Теперь, когда в ячейке физически находится число 0, к нему можно применять стандартное Условное оформление.
Если ваша кросс-таблица строится по датам, и пропуски возникают из-за отсутствия данных в конкретные дни, мы можем заставить СКД генерировать записи для каждой даты периода. Это сделает ячейки «реальными».
Разберем по шагам:
День) и настройте Дополнение периодов, указав начало и конец периода (обычно это параметры отчета).После этой настройки СКД сама добавит в выборку недостающие даты, и функция ЕСТЬNULL в запросе или ресурсах начнет отрабатывать предсказуемо.
Часто задача звучит сложнее: «Если итог по строке (ресурс Уход) больше нуля, то вся строка должна быть красной, включая пустые ячейки с нулями». Проблема в том, что ячейка в колонке Дата1 «не знает», какое значение получилось в колонке Итого. Для более тонкой настройки внешнего вида может потребоваться даже программное изменение заголовка группировки отчета.
Для решения этой задачи воспользуемся функцией ВычислитьВыражение. В настройках Условного оформления мы можем задать условие не по значению текущего поля, а по выражению.
Рассмотрим пример настройки:
ВычислитьВыражение("Сумма(Уход)", "Номенклатура") > 0
Проанализируем ситуацию: второй параметр функции "Номенклатура" указывает системе, что нужно взять агрегат Сумма(Уход) в контексте текущей строки номенклатуры, игнорируя колонки-даты. Теперь каждая ячейка в строке будет знать значение общего итога и окрасится корректно.
Если вышеперечисленные методы не помогают (например, при сложной структуре отчета), можно подготовить данные в самом запросе. Мы можем создать полную матрицу всех возможных комбинаций номенклатуры и периодов. При этом здесь критически важна оптимизация отчетов с набором данных, чтобы сохранить приемлемую скорость работы.
Посмотрим на пример логики запроса:
ВЫБРАТЬ
Номенклатура.Ссылка КАК Номенклатура,
Календарь.Дата КАК Период
ПОМЕСТИТЬ ПолнаяМатрица
ИЗ
Справочник.Номенклатура КАК Номенклатура
СОЕДИНЕНИЕ РегистрСведений.ПроизводственныйКалендарь КАК Календарь
ПО (Календарь.Дата МЕЖДУ &НачалоПериода И &КонецПериода);
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Матрица.Номенклатура,
Матрица.Период,
ЕСТЬNULL(Обороты.СуммаОборот, 0) КАК Сумма
ИЗ
ПолнаяМатрица КАК Матрица
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи.Обороты(&Начало, &Конец, День, ) КАК Обороты
ПО Матрица.Номенклатура = Обороты.Номенклатура
И Матрица.Период = Обороты.Период
Этот метод гарантирует, что для каждой ячейки отчета в СКД придет физическая запись с числом 0. Это самый «тяжелый» для производительности способ, но он абсолютно надежен для решения любых проблем с оформлением.
Если ваша задача — только показать нули вместо пустоты (без сложной логики раскраски), можно воспользоваться свойством Оформление самого поля или настройки отчета.
Выясним, как это работает:
ЧН=0.Важно помнить: ЧН=0 меняет только визуальное представление. Если вы пытаетесь использовать условие оформления Значение = 0, оно может не сработать для пустых ячеек, так как формат применяется после вычисления условий оформления. Поэтому для раскраски лучше комбинировать формат с ЕСТЬNULL в ресурсах.
Мы рассмотрели различные подходы к «победе» над оформлением СКД. Для большинства задач достаточно использовать ЕСТЬNULL(Сумма(Поле), 0) на закладке Ресурсы и функцию ВычислитьВыражение в Условном оформлении. В исключительных случаях можно рассмотреть такие подходы, как две разных схемы в одном отчете СКД. Это позволяет сохранить гибкость отчета и высокую скорость его формирования без избыточного усложнения запросов.