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