При формировании печатных форм в среде «1С:Предприятие» разработчики часто сталкиваются с ситуацией, когда в макете подготовлена большая область с множеством строк, но при выводе конкретного документа часть из этих строк оказывается незаполненной. Вывод пустых строк портит внешний вид печатной формы, увеличивает расход бумаги и делает документ нечитаемым. Наша задача — сделать так, чтобы пустые строки автоматически скрывались.
В этой статье мы подробно проанализируем различные способы решения этой задачи: от простого управления видимостью до профессиональных методик динамического формирования табличного документа.
Разберем решение, к которому пришел автор темы на форуме. Оно заключается в непосредственном обращении к конкретной строке табличного документа по ее адресу и отключении ее отображения.
Посмотрим на пример кода, предложенный автором:
ОбластьСтрока = ТабДок.Область("R2");
ОбластьСтрока.Видимость = Ложь;
Этот способ действительно работает в простейших случаях. Мы получаем область, соответствующую второй строке результирующего табличного документа (параметр "R2" указывает на Row 2), и устанавливаем свойство Видимость в значение Ложь. Строка визуально скрывается от пользователя.
Почему этот подход опасен и крайне не рекомендуется в реальной разработке?
Выделим ключевые недостатки использования жестко прописанных («захардкоженных») координат строк:
ТабДок.Выяснив причину неэффективности простого подхода, рассмотрим более гибкие, надежные и профессиональные альтернативы.
Вместо того чтобы рисовать в макете одну большую неделимую область из 10 строк, в профессиональной разработке принято разбивать макет на небольшие логические части (строки) и выводить их последовательно в коде только при выполнении условий.
Давайте по шагам разберем реализацию этого механизма:
СтрокаПараметра1, СтрокаПараметра2, СтрокаПараметра3.Вывести().Проанализируем пример кода, реализующий данный подход:
// Создаем результирующий табличный документ
ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("МакетПечатнойФормы");
// Сначала выводим статичную шапку документа
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ТабДок.Вывести(ОбластьШапка);
// Проверяем заполненность первого реквизита и выводим строку при наличии данных
Если ЗначениеЗаполнено(ДанныеПечати.Поле1) Тогда
ОбластьСтроки = Макет.ПолучитьОбласть("СтрокаПараметра1");
ОбластьСтроки.Параметры.Поле1 = ДанныеПечати.Поле1;
ТабДок.Вывести(ОбластьСтроки);
КонецЕсли;
// Проверяем заполненность второго реквизита
Если ЗначениеЗаполнено(ДанныеПечати.Поле2) Тогда
ОбластьСтроки = Макет.ПолучитьОбласть("СтрокаПараметра2");
ОбластьСтроки.Параметры.Поле2 = ДанныеПечати.Поле2;
ТабДок.Вывести(ОбластьСтроки);
КонецЕсли;
// Выводим подвал документа
ОбластьПодвал = Макет.ПолучитьОбласть("Подвал");
ТабДок.Вывести(ОбластьПодвал);
Преимущества метода: результирующий документ вообще не содержит скрытых или «нулевых» элементов. Это экономит оперативную память компьютера, предотвращает появление нежелательных пустых страниц при печати и гарантирует корректный экспорт документа в форматы PDF, Excel или Word.
Что делать, если макет является внешним, его структура строго зафиксирована, и переделывать его на множество мелких областей нельзя? В этом случае нам придется программно отключать видимость строк в уже сформированном табличном документе, но делать это мы будем без использования жесткого кодирования индексов.
Для реализации этого метода мы будем использовать свойство табличного документа ВысотаТаблицы. Оно позволяет нам в любой момент времени узнать, сколько строк уже фактически выведено в документ.
Рассмотрим по шагам логику решения:
СтартоваяСтрока.Посмотрим на пример кода:
ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("МакетПечатнойФормы");
// Запоминаем текущую высоту таблицы до момента вывода области
СтартоваяСтрока = ТабДок.ВысотаТаблицы;
// Получаем общую область с 10 строками и выводим ее
Область10Строк = Макет.ПолучитьОбласть("ОбластьСДесятьюСтроками");
Область10Строк.Параметры.Заполнить(ДанныеПечати);
ТабДок.Вывести(Область10Строк);
// Скрываем вторую строку нашей выведенной области, если параметр пуст.
// Вторая строка области будет иметь индекс: СтартоваяСтрока + 2
Если Не ЗначениеЗаполнено(ДанныеПечати.ПолеДляВторойСтроки) Тогда
НомерСтрокиДляСкрытия = СтартоваяСтрока + 2;
// Формируем адрес области динамически, избегая "хардкода"
АдресОбласти = "R" + Формат(НомерСтрокиДляСкрытия, "ЧГ=0");
ТабДок.Область(АдресОбласти).Видимость = Ложь;
КонецЕсли;
Преимущества метода: этот алгоритм продолжит работать абсолютно корректно, даже если выше по коду будут добавлены новые динамические секции, строки или таблицы. Мы всегда привязываемся к фактической точке вывода в реальном времени.
Иногда простое скрытие строк через свойство Видимость = Ложь может вызывать визуальные артефакты при сохранении табличного документа в сторонние форматы (например, при конвертации в PDF или XLS на некоторых старых версиях платформы могут оставаться «сплющенные» пустые строчки или нарушаться границы рамок ячеек). В таких сценариях надежнее физически удалять ненужные строки из итогового документа.
Для физического удаления строк используется метод табличного документа УдалитьОбласть() с указанием типа смещения.
Важное правило: при удалении или изменении строк в цикле обход табличной части документа всегда необходимо выполнять с конца к началу (в обратном порядке). Если обходить таблицу сверху вниз, то при удалении текущей строки все последующие строки сместятся вверх, их индексы изменятся, и цикл пропустит следующую за удаленной строку.
Рассмотрим пример кода, в котором выполняется обход выведенных строк снизу вверх с последующим удалением пустых элементов:
// Запоминаем границы выведенной области
НачалоДиапазона = СтартоваяСтрока + 1;
КонецДиапазона = ТабДок.ВысотаТаблицы;
// Начинаем обратный цикл (от большего индекса к меньшему)
Для Счетчик = -КонецДиапазона По -НачалоДиапазона Цикл
ТекущийНомерСтроки = -Счетчик;
// Проверяем значение в ключевой колонке (например, во второй колонке)
ЗначениеЯчейки = ТабДок.Область("R" + Формат(ТекущийНомерСтроки, "ЧГ=0") + "C2").Текст;
// Если ячейка пустая — физически удаляем всю строку со смещением вверх
Если ПустаяСтрока(СокрЛП(ЗначениеЯчейки)) Тогда
ОбластьСтроки = ТабДок.Область("R" + Формат(ТекущийНомерСтроки, "ЧГ=0"));
ТабДок.УдалитьОбласть(ОбластьСтроки, ТипСмещенияТабличногоДокумента.ПоВертикали);
КонецЕсли;
КонецЦикла;
Преимущества метода: полная физическая чистота результирующего файла. Документ гарантированно корректно отобразится в любом внешнем просмотрщике файлов офисных форматов.
Бывают ситуации, когда незаполненные строки не должны исчезать бесследно. Иногда требуется предоставить пользователю возможность самостоятельно решать — показывать пустые строки или скрыть их обратно кликом по значку «плюс/минус» слева от формы.
Для реализации этого сценария мы можем использовать механизм группировки строк платформы 1С. Метод СгруппироватьСтроки() позволяет объединить диапазон строк в структуру, которой можно управлять как программно, так и интерактивно.
Посмотрим на пример практической реализации группировки:
// Определяем диапазон строк для группировки
НачалоГруппировки = СтартоваяСтрока + 3;
КонецГруппировки = СтартоваяСтрока + 8;
// Группируем строки. Третий параметр "Истина" указывает платформе,
// что группа строк должна быть изначально свернута (скрыта от глаз).
ТабДок.СгруппироватьСтроки(НачалоГруппировки, КонецГруппировки, Истина);
// Включаем отображение панели группировок (плюсиков слева от документа)
ТабДок.ПоказыватьУровниГруппировок = Истина;
Преимущества метода: гибкость интерфейса. Пользователь видит аккуратный сжатый документ, но при необходимости может в один клик развернуть скрытую секцию и ознакомиться с ее пустой или дополнительной структурой.
Мы детально проанализировали задачу скрытия пустых строк в макетах 1С и пришли к следующим выводам:
"R2" в реальных проектах, так как это приводит к нестабильности работы программы при малейших изменениях макетов.ВысотаТаблицы.