При разработке печатных форм в программах на платформе 1С разработчики часто сталкиваются с ситуацией, когда вместо всех строк табличной части документа в итоговый табличный документ выводится только самая последняя строка. Проанализируем причину этой ошибки и рассмотрим правильный алгоритм обхода выборки запроса.
Выясним, почему возникает данная проблема. В исходном коде заполнение параметров области макета выполняется внутри цикла, а сам вывод области в табличный документ происходит уже после завершения работы цикла:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ЗаказПокупателяСводныйТовары.Номенклатура,
| ЗаказПокупателяСводныйТовары.КоличествоЗаказано
|ИЗ
| Документ.ЗаказПокупателяСводный.Товары КАК ЗаказПокупателяСводныйТовары
|ГДЕ
| ЗаказПокупателяСводныйТовары.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", Ссылка);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ЗаполнитьЗначенияСвойств(ОбластьСтрокаТЧ.Параметры, Выборка);
КонецЦикла;
// Ошибка: метод Вывести вызывается после завершения цикла
ТабДок.Вывести(ОбластьСтрокаТЧ);
При такой структуре кода на каждой итерации цикла параметры области ОбластьСтрокаТЧ.Параметры перезаписываются новыми значениями текущей строки выборки. Когда цикл завершается, в параметрах области остаются данные из самой последней записи. Затем вызов ТабДок.Вывести(ОбластьСтрокаТЧ) срабатывает ровно один раз, отправляя в результат только последнюю строку.
Чтобы вывести абсолютно все строки табличной части, вызов метода Вывести() объекта ТабличныйДокумент необходимо поместить внутри цикла обхода выборки запроса. Рассмотрим правильный вариант реализации:
Пока Выборка.Следующий() Цикл
ЗаполнитьЗначенияСвойств(ОбластьСтрокаТЧ.Параметры, Выборка);
ТабДок.Вывести(ОбластьСтрокаТЧ);
КонецЦикла;
Альтернативно для заполнения параметров области можно использовать метод Заполнить() непосредственно у объекта параметров области:
Пока Выборка.Следующий() Цикл
ОбластьСтрокаТЧ.Параметры.Заполнить(Выборка);
ТабДок.Вывести(ОбластьСтрокаТЧ);
КонецЦикла;
Разберем по шагам, что происходит на каждой итерации исправленного цикла:
Выборка.Следующий() осуществляет переход к очередной строке результата запроса.ОбластьСтрокаТЧ.Параметры.ТабДок.Вывести(ОбластьСтрокаТЧ) мгновенно добавляет сформированную строку в итоговый табличный документ.Для повышения производительности и правильного формирования внешнего вида печатной формы обратите внимание на следующие важные моменты:
1. Получение области макета до начала цикла: Получать область с помощью метода Макет.ПолучитьОбласть("СтрокаТЧ") нужно строго перед циклом, а не внутри него. Повторный вызов получения области в цикле создает ненужную нагрузку на память.
2. Разделение данных по условиям и именованным областям: Если требуется выводить данные в две разные печатные формы или в разграниченные блоки макета (например, по видам доставки), создайте в макете отдельные именованные области и проверяйте условие вывода в цикле или используйте пакетные запросы.
3. Контроль переноса страниц: Для предотвращения разрыва табличной части при переносе на новый лист перед выводом строки или группы строк используйте метод ТабДок.ПроверитьВывод(). Если строка не помещается, вызывайте метод ТабДок.ВывестиГоризонтальныйРазделительСтраниц().
4. Автоматический масштаб: Чтобы сформированный документ корректно помещался по ширине листа при печати, задайте свойство ТабДок.АвтоМасштаб = Истина.