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