Как скрыть пустые строки в отчете на базе макета 1С?

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

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

Постановка задачи и анализ исходного кода

Рассмотрим ситуацию: у нас есть отчет «Динамика аптек», который выводит данные о магазинах и их показателях за определенные периоды. Вывод осуществляется путем перебора результата запроса по группировкам. Основная проблема заключается в том, что в отчет попадают все аптеки, даже если по ним не было движения и остатков за выбранный период. Наша цель — добавить условие, которое будет проверять наличие данных перед выводом строки в ТабличныйДокумент.

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


Пока Аптека.Следующий Цикл
    // Код подготовки области макета
    фл = НЕ фл;
    Если фл Тогда 
        ОблСтрока = ОблСтрокаАптека0; 
    Иначе 
        ОблСтрока = ОблСтрокаАптека1; 
    КонецЕсли;
    
    // Вывод параметров аптеки
    пп = пп + 1;
    облСтрока.Параметры.пп = пп;
    облСтрока.Параметры.Аптека = Аптека.Магазин;
    
    // Здесь происходит непосредственный вывод строки в таблицу
    Таб.Вывести(облСтрока);
    
    // Далее идет вложенный цикл по периодам...
КонецЦикла;

Решение 1: Программная фильтрация в цикле обхода

Самый простой и быстрый способ убрать ненужные строки — использовать оператор Продолжить внутри основного цикла обхода результата запроса. Это позволит пропустить выполнение кода вывода для тех записей, которые не соответствуют нашим критериям.

Допустим, на форме отчета у нас есть реквизит СкрыватьПустые (тип Булево), который связан с флажком «Скрывать пустые строки». Реализуем проверку показателей Остаток и Оборот. Разберем по шагам, куда именно нужно вставить код:

  1. Найдем начало цикла Пока Аптека.Следующий() Цикл.
  2. Сразу после начала цикла добавим условие проверки.
  3. Если флажок установлен И значения равны нулю, используем Продолжить.

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


Пока Аптека.Следующий() Цикл
    // Проверяем условие фильтрации
    Если ЭлементыФормы.ФлажокСкрыватьПустые.Значение Тогда
        Если Аптека.Остаток = 0 И Аптека.Оборот = 0 Тогда
            Продолжить; // Пропускаем текущую итерацию цикла, строка не будет выведена
        КонецЕсли;
    КонецЕсли;

    // Далее стандартный код вывода строки
    фл = НЕ фл;
    Если фл Тогда 
        ОблСтрока = ОблСтрокаАптека0; 
    Иначе 
        ОблСтрока = ОблСтрокаАптека1; 
    КонецЕсли;
    
    // ... заполнение параметров и Таб.Вывести(облСтрока);
КонецЦикла;

Важный нюанс: Обратите внимание на вложенность условий. Если вы напишете проверку без учета значения флажка, пустые строки будут скрываться всегда, независимо от настроек пользователя. Также убедитесь, что в блоке ИТОГИ вашего запроса правильно суммируются поля Остаток и Оборот, иначе в переменной Аптека (которая является выборкой по группировке) эти значения могут быть неопределены.

Решение 2: Оптимизация на уровне запроса (HAVING)

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

Для этого в языке запросов 1С используется конструкция ИМЕЮЩИЕ. Мы можем добавить условие, чтобы запрос возвращал только те магазины, у которых сумма показателей за период не равна нулю. Рассмотрим пример модификации блока ИТОГИ:


// ... код текста запроса
|СГРУППИРОВАТЬ ПО
|   рТаб.Магазин,
|   рТаб.Период
|ИМЕЮЩИЕ
|   СУММА(рТаб.Оборот) <> 0 ИЛИ СУММА(рТаб.Остаток) <> 0
|УПОРЯДОЧИТЬ ПО
|   Магазин,
|   Период
|ИТОГИ
|   СУММА(Оборот),
|   СУММА(Остаток)
|ПО
|   Магазин,
|   Период

Такой подход значительно ускоряет формирование отчета, так как выборка Аптека = Запрос.Выполнить().Выбрать(...) уже не будет содержать «пустых» магазинов.

Решение 3: Динамическое скрытие строк в готовом табличном документе

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

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

  1. Сначала выводим строку как обычно.
  2. Запоминаем номер строки, в которую произведен вывод (используем Таб.ВысотаТаблицы).
  3. После вывода всех данных по аптеке проверяем, были ли заполнены показатели.
  4. Если данных нет, скрываем строку.

Пример кода для реализации этого метода:


// Выводим строку
Таб.Вывести(облСтрока);
НомерСтрокиАптеки = Таб.ВысотаТаблицы;

// ... код вывода детальных периодов ...

// Если после вывода периодов мы поняли, что данных нет
Если СкрыватьПустые И ИтогоПоАптеке = 0 Тогда
    Таб.Область(НомерСтрокиАптеки, , НомерСтрокиАптеки).Видимость = Ложь;
КонецЕсли;

Важно: Метод со свойством Видимость является наименее предпочтительным с точки зрения производительности и объема памяти, так как объект ТабличныйДокумент все равно хранит скрытые строки. Используйте его только в исключительных случаях.

Типичные ошибки при реализации

Разберем основные трудности, с которыми сталкиваются разработчики при попытке убрать строки из макета:

1. Ошибка «Не найден конец цикла»: Чаще всего возникает из-за нарушения структуры Если ... КонецЕсли внутри цикла Пока ... Цикл. Тщательно следите за тем, чтобы оператор Продолжить находился строго внутри условия, а само условие закрывалось до завершения цикла.

2. Проблема с NULL: В запросах 1С пустые значения числовых полей могут возвращать NULL. При сравнении в коде NULL = 0 даст Ложь. Чтобы избежать ошибок, используйте функцию ЕСТЬNULL(Поле, 0) прямо в тексте запроса или принудительное преобразование типа в коде: Число(Аптека.Остаток).

3. Сбитая нумерация: Если в вашем отчете есть колонка с порядковым номером (параметр пп), инкремент номера должен происходить после блока фильтрации. Если вы сначала увеличите пп = пп + 1, а потом вызовете Продолжить, в отчете возникнут «дыры» в нумерации (например, после 2-й строки сразу пойдет 4-я).

Выяснив причину появления пустых строк и выбрав подходящий метод (через запрос или через оператор Продолжить), вы сможете сделать свои отчеты максимально информативными и удобными для конечного пользователя. Мы рекомендуем отдавать предпочтение фильтрации в запросе (ИМЕЮЩИЕ), так как это наиболее правильный архитектурный подход в системе 1С:Предприятие.

← На главную