Как скрыть строки с нулевыми или пустыми ресурсами в группировках отчета СКД?

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

Разберем типичную и крайне неприятную ситуацию, с которой часто сталкиваются разработчики при проектировании отчетов на Системе компоновки данных (СКД). Представим отчет по остаткам и резервам товаров на складах. В базе данных хранятся детальные записи, которые сами по себе не являются нулевыми (например, по одному документу зафиксирован приход 10 единиц товара, а по другому — расход -10 единиц). В сумме по группировке «Номенклатура» мы получаем чистый ноль (0).

Если мы просто наложим глобальный отбор на уровне отчета с условием Ресурс <> 0, СКД транслирует это условие в секцию ГДЕ (WHERE) SQL-запроса. Детальные записи 10 и -10 вообще не попадут в выборку. Это приведет к искажению итогов по другим группировкам или общих итогов отчета. Если же не накладывать отбор, то отчет заполнится десятками тысяч «пустых» строк с нулевыми итогами, которые сильно усложняют чтение данных пользователем.

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

---

Способ 1. Отбор на уровне конкретной группировки (Аналог HAVING в SQL)

Это самый правильный, гибкий и стандартный механизм СКД. Нам нужно наложить отбор по ресурсу не на весь отчет сразу, а внутри настроек конкретной группировки (например, группировки Номенклатура или Характеристика).

Проанализируем этот метод по шагам:

  1. Откроем схему компоновки данных и перейдем на вкладку Настройки.
  2. В структуре настроек отчета выберем ту группировку, строки которой мы хотим скрыть при равенстве ресурса нулю.
  3. В нижней части экрана перейдем на вкладку Отбор (это будут индивидуальные настройки выбранной группировки, а не общие настройки отчета).
  4. Добавим новое поле отбора, например: Ресурс1 Не равно 0 (или Заполнено).
  5. Если у нас несколько ресурсов, и строка должна скрываться только тогда, когда все они равны нулю, сгруппируем условия по типу ИЛИ. Например: Ресурс1 Не равно 0 ИЛИ Ресурс2 Не равно 0.

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

---

Способ 2. Группировка и фильтрация на уровне запроса

Если структура отчета фиксированная, и пользователю не требуется динамически менять состав группировок или делать расшифровку до документов-регистраторов, мы можем отсечь пустые строки непосредственно в тексте запроса с помощью конструкции ИМЕЮЩИЕ (HAVING).

Посмотрим на пример такого запроса:


ВЫБРАТЬ
    ВложенныйЗапрос.Измерение1 КАК Измерение1,
    ВложенныйЗапрос.Измерение2 КАК Измерение2,
    СУММА(ВложенныйЗапрос.Ресурс1) КАК Ресурс1,
    СУММА(ВложенныйЗапрос.Ресурс2) КАК Ресурс2
ИЗ
    (ВЫБРАТЬ
        "Т1" КАК Измерение1,
        "С1" КАК Измерение2,
        10 КАК Ресурс1,
        -25 КАК Ресурс2
    ОБЪЕДИНИТЬ ALL
    ВЫБРАТЬ
        "Т1",
        "С2",
        -10,
        25) КАК ВложенныйЗапрос
СГРУППИРОВАТЬ ПО
    ВложенныйЗапрос.Измерение1,
    ВложенныйЗапрос.Измерение2
ИМЕЮЩИЕ
    СУММА(ВложенныйЗапрос.Ресурс1) <> 0
    ИЛИ СУММА(ВложенныйЗапрос.Ресурс2) <> 0

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

---

Способ 3. Игнорирование значений NULL в ролях полей

Часто пустые строки в отчетах возникают не из-за взаимного исключения чисел, а из-за левых соединений (ЛЕВОЕ СОЕДИНЕНИЕ) таблиц в запросе. При этом измерения подчиненных таблиц принимают значения NULL, под которые СКД выделяет отдельные некрасивые пустые строки.

Чтобы решить эту проблему, выполним следующие настройки:

  1. Перейдем на вкладку Наборы данных в конструкторе СКД.
  2. В списке полей найдем то измерение, которое порождает пустые строки (например, СерияНоменклатуры).
  3. Кликнем по ячейке в колонке Роли для этого поля.
  4. В открывшемся окне редактирования роли установим флажок Игнорировать значения NULL.

После этого система компоновки данных перестанет создавать отдельные ветки группировок под пустые значения NULL, а просто пропустит их или свернет на уровень выше.

---

Способ 4. Программное удаление строк через «метод маркеров»

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

Рассмотрим алгоритм реализации этого метода по шагам:

  1. В СКД настроим Условное оформление.
  2. Зададим условие: если Ресурс1 = 0, то в качестве текста ячейки выведем специальный маркер, например, строку <УдалитьСтроку>.
  3. В модуле объекта отчета переопределим предопределенную процедуру ПриКомпоновкеРезультата.

Ниже представлен пример программного кода для реализации этого подхода:


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

Преимущество метода: гарантируется 100% точное удаление ненужных визуальных строк без какого-либо влияния на математику расчета итогов в СКД. Общие итоги будут посчитаны абсолютно корректно.

---

Способ 5. Сжатие высоты строк через условное оформление

Если мы не хотим писать программный код удаления строк, но нам нужно визуально скрыть строки с нулевыми итогами, можно воспользоваться «хитростью» условного оформления:

  1. В настройках отчета на вкладке Условное оформление добавим новое правило.
  2. В качестве оформляемых полей укажем все поля нашей группировки.
  3. Зададим условие оформления: Ресурс1 Равно 0.
  4. В параметрах оформления установим значение Максимальная высота равным 0.1 (или минимально возможному значению платформы), а также сделаем цвет текста и цвет границ совпадающими с цветом фона.

Строки визуально «схлопнутся» и станут незаметными для глаза. Однако помните, что при копировании данных в Excel или при печати эти строки все равно могут отображаться в виде очень тонких полос, поэтому данный способ рекомендуется использовать только как крайнюю альтернативу.

← На главную