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