При разработке печатных форм в среде 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда код кажется абсолютно верным, но при формировании документа выводится только «шапка», а строки табличной части остаются пустыми или вовсе не отображаются. Разберем подробно, почему цикл Для Каждого может «проскакивать», и выясним, как правильно передавать данные из реквизитов объекта в параметры макета.
Если при пошаговой отладке выполнение кода перескакивает с инструкции Для Каждого сразу на КонецЦикла, это однозначно указывает на то, что коллекция, которую мы пытаемся обойти, пуста. Рассмотрим ситуацию, когда в отладчике переменная Объект.РеестрКонтрактов имеет тип ДанныеФормыКоллекция, но цикл не срабатывает. Это может происходить по нескольким причинам:
Ссылка.ПолучитьОбъект()), а пользователь еще не записал документ, то в базе табличная часть будет пустой, хотя на экране монитора строки заполнены.Объект, который на форме является лишь «отражением» данных. Если в процедуру формирования печати не переданы актуальные данные формы, сервер может не увидеть того, что ввел пользователь.Для диагностики этой проблемы первым делом проверим количество строк в таблице перед началом цикла. Добавим в код отладочное сообщение:
Сообщить("Количество строк в таблице: " + Объект.РеестрКонтрактов.Количество());
Для Каждого ТекущаяСтрока Из Объект.РеестрКонтрактов Цикл
// Код вывода
КонецЦикла;
Если в окне сообщений выводится «0», значит, проблема не в макете, а в получении данных. В управляемых формах важно убедиться, что вы работаете с текущими данными формы. Если печать вызывается из модуля команды, убедитесь, что в параметрах команды передается правильная ссылка или данные формы.
Бывают случаи, когда цикл отрабатывает (количество итераций соответствует количеству строк), но в печатной форме вместо данных мы видим пустоту или названия самих параметров. Проанализируем настройки самого табличного документа в конфигураторе.
Свойство ячейки «Заполнение». Это самая распространенная ошибка. Выделим в макете ячейку, куда должен выводиться, например, НомерКонтракта. Нажмем F4 (Свойства) и найдем пункт Заполнение. Там могут быть три варианта:
Область.Параметры.НомерКонтракта = ... в коде никак не повлияет на результат.Соответствие имен. 1С крайне чувствительна к написанию имен параметров. Проверим, нет ли в макете лишних пробелов в именах параметров. Например, если в макете параметр назван "ДатаЗаключения " (с пробелом на конце), а в коде мы пишем ОбластьСтрокаТЧ.Параметры.ДатаЗаключения, данные не будут выведены, так как это разные идентификаторы.
В исходном примере кода автор вручную присваивает каждый параметр. Это трудоемко и повышает риск опечаток. Разберем, как сделать это эффективнее с помощью метода ЗаполнитьЗначенияСвойств. Этот метод автоматически сопоставляет имена колонок табличной части и имена параметров в области макета.
Посмотрим на обновленный и оптимизированный алгоритм:
ТабДок = Новый ТабличныйДокумент;
Макет = Отчеты.РеестрКонтрактов.ПолучитьМакет("ПечатьОтчётаРеестрКонтрактов");
// Выводим шапку
Шапка = Макет.ПолучитьОбласть("Шапка");
ТабДок.Вывести(Шапка);
// Получаем область строки ОДИН РАЗ вне цикла
ОбластьСтрокаТЧ = Макет.ПолучитьОбласть("СтрокаТЧ");
Для Каждого ТекущаяСтрока Из Объект.РеестрКонтрактов Цикл
// Заполняем параметры области данными из текущей строки ТЧ
ЗаполнитьЗначенияСвойств(ОбластьСтрокаТЧ.Параметры, ТекущаяСтрока);
// Если есть специфические поля, которые нужно преобразовать, делаем это отдельно
// Например, формат даты или представление ссылки
// ОбластьСтрокаТЧ.Параметры.ДатаЗаключения = Формат(ТекущаяСтрока.ДатаЗаключения, "ДФ=dd.MM.yyyy");
// Выводим заполненную область в итоговый табличный документ
ТабДок.Вывести(ОбластьСтрокаТЧ);
КонецЦикла;
ТабДок.Показать();
Важный нюанс: Метод ЗаполнитьЗначенияСвойств работает только тогда, когда имена параметров в макете точно совпадают с именами реквизитов в табличной части. Это лучший способ избежать ошибок и сократить объем кода.
Если мы работаем на сервере в контексте управляемой формы и нам нужно выполнить сложные расчеты или запросы к данным табличной части, которые еще не записаны, может потребоваться преобразование данных формы в полноценный объект. Выясним ситуацию: если Объект.РеестрКонтрактов возвращает Неопределено, попробуем следующий подход:
&НаСервере
Процедура ПечатьНаСервере()
// Преобразуем данные формы в объект для полноценного доступа к метаданным
ДокОбъект = РеквизитФормыВЗначение("Объект");
ТабДок = Новый ТабличныйДокумент;
Макет = ДокОбъект.ПолучитьМакет("ПечатьОтчётаРеестрКонтрактов");
// Теперь работаем с ДокОбъект.РеестрКонтрактов
Для Каждого Стр Из ДокОбъект.РеестрКонтрактов Цикл
// ... вывод строк
КонецЦикла;
КонецПроцедуры
Этот метод гарантирует, что мы работаем с актуальной структурой объекта, даже если он еще не зафиксирован в базе данных. Однако помните, что РеквизитФормыВЗначение — ресурсоемкая операция, и для простого вывода печатной формы обычно достаточно прямого перебора Объект.РеестрКонтрактов, если процедура находится в модуле формы.
Подводя итог, если ваш цикл «игнорирует» строки табличной части, выполните следующие шаги:
Объект.РеестрКонтрактов.Количество(). Если оно равно 0, ищите проблему в передаче данных с клиента на сервер или в записи объекта.ЗаполнитьЗначенияСвойств для автоматизации заполнения строк, это минимизирует риск человеческой ошибки.&НаКлиенте, &НаСервере). Формирование макета и обращение к нему должно происходить исключительно на стороне сервера.Следуя этим правилам, вы сможете быстро локализовать причину пустой печати и обеспечить корректный вывод всех данных реестра контрактов в ваш отчет.