Почему не выводятся параметры в макет при обходе табличной части в цикле?

Программист 1С v8.3 (Управляемые формы)
← На главную

При разработке печатных форм в среде 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда код кажется абсолютно верным, но при формировании документа выводится только «шапка», а строки табличной части остаются пустыми или вовсе не отображаются. Разберем подробно, почему цикл Для Каждого может «проскакивать», и выясним, как правильно передавать данные из реквизитов объекта в параметры макета.

Анализ первой причины: Пустая коллекция данных

Если при пошаговой отладке выполнение кода перескакивает с инструкции Для Каждого сразу на КонецЦикла, это однозначно указывает на то, что коллекция, которую мы пытаемся обойти, пуста. Рассмотрим ситуацию, когда в отладчике переменная Объект.РеестрКонтрактов имеет тип ДанныеФормыКоллекция, но цикл не срабатывает. Это может происходить по нескольким причинам:

  1. Данные не сохранены в базе: Если формирование печатной формы происходит на сервере с получением объекта из базы данных (например, через Ссылка.ПолучитьОбъект()), а пользователь еще не записал документ, то в базе табличная часть будет пустой, хотя на экране монитора строки заполнены.
  2. Неправильный контекст: Мы можем обращаться к реквизиту Объект, который на форме является лишь «отражением» данных. Если в процедуру формирования печати не переданы актуальные данные формы, сервер может не увидеть того, что ввел пользователь.

Для диагностики этой проблемы первым делом проверим количество строк в таблице перед началом цикла. Добавим в код отладочное сообщение:


Сообщить("Количество строк в таблице: " + Объект.РеестрКонтрактов.Количество());
Для Каждого ТекущаяСтрока Из Объект.РеестрКонтрактов Цикл
    // Код вывода
КонецЦикла;

Если в окне сообщений выводится «0», значит, проблема не в макете, а в получении данных. В управляемых формах важно убедиться, что вы работаете с текущими данными формы. Если печать вызывается из модуля команды, убедитесь, что в параметрах команды передается правильная ссылка или данные формы.

Анализ второй причины: Ошибки в настройках макета

Бывают случаи, когда цикл отрабатывает (количество итераций соответствует количеству строк), но в печатной форме вместо данных мы видим пустоту или названия самих параметров. Проанализируем настройки самого табличного документа в конфигураторе.

Свойство ячейки «Заполнение». Это самая распространенная ошибка. Выделим в макете ячейку, куда должен выводиться, например, НомерКонтракта. Нажмем F4 (Свойства) и найдем пункт Заполнение. Там могут быть три варианта:

Соответствие имен. 1С крайне чувствительна к написанию имен параметров. Проверим, нет ли в макете лишних пробелов в именах параметров. Например, если в макете параметр назван "ДатаЗаключения " (с пробелом на конце), а в коде мы пишем ОбластьСтрокаТЧ.Параметры.ДатаЗаключения, данные не будут выведены, так как это разные идентификаторы.

Оптимизация кода вывода строк

В исходном примере кода автор вручную присваивает каждый параметр. Это трудоемко и повышает риск опечаток. Разберем, как сделать это эффективнее с помощью метода ЗаполнитьЗначенияСвойств. Этот метод автоматически сопоставляет имена колонок табличной части и имена параметров в области макета.

Посмотрим на обновленный и оптимизированный алгоритм:


ТабДок = Новый ТабличныйДокумент;
Макет = Отчеты.РеестрКонтрактов.ПолучитьМакет("ПечатьОтчётаРеестрКонтрактов");

// Выводим шапку
Шапка = Макет.ПолучитьОбласть("Шапка");
ТабДок.Вывести(Шапка);

// Получаем область строки ОДИН РАЗ вне цикла
ОбластьСтрокаТЧ = Макет.ПолучитьОбласть("СтрокаТЧ");

Для Каждого ТекущаяСтрока Из Объект.РеестрКонтрактов Цикл
    // Заполняем параметры области данными из текущей строки ТЧ
    ЗаполнитьЗначенияСвойств(ОбластьСтрокаТЧ.Параметры, ТекущаяСтрока);
    
    // Если есть специфические поля, которые нужно преобразовать, делаем это отдельно
    // Например, формат даты или представление ссылки
    // ОбластьСтрокаТЧ.Параметры.ДатаЗаключения = Формат(ТекущаяСтрока.ДатаЗаключения, "ДФ=dd.MM.yyyy");
    
    // Выводим заполненную область в итоговый табличный документ
    ТабДок.Вывести(ОбластьСтрокаТЧ);
КонецЦикла;

ТабДок.Показать();

Важный нюанс: Метод ЗаполнитьЗначенияСвойств работает только тогда, когда имена параметров в макете точно совпадают с именами реквизитов в табличной части. Это лучший способ избежать ошибок и сократить объем кода.

Проблема использования «РеквизитФормыВЗначение»

Если мы работаем на сервере в контексте управляемой формы и нам нужно выполнить сложные расчеты или запросы к данным табличной части, которые еще не записаны, может потребоваться преобразование данных формы в полноценный объект. Выясним ситуацию: если Объект.РеестрКонтрактов возвращает Неопределено, попробуем следующий подход:


&НаСервере
Процедура ПечатьНаСервере()
    // Преобразуем данные формы в объект для полноценного доступа к метаданным
    ДокОбъект = РеквизитФормыВЗначение("Объект");
    
    ТабДок = Новый ТабличныйДокумент;
    Макет = ДокОбъект.ПолучитьМакет("ПечатьОтчётаРеестрКонтрактов");
    
    // Теперь работаем с ДокОбъект.РеестрКонтрактов
    Для Каждого Стр Из ДокОбъект.РеестрКонтрактов Цикл
        // ... вывод строк
    КонецЦикла;
КонецПроцедуры

Этот метод гарантирует, что мы работаем с актуальной структурой объекта, даже если он еще не зафиксирован в базе данных. Однако помните, что РеквизитФормыВЗначение — ресурсоемкая операция, и для простого вывода печатной формы обычно достаточно прямого перебора Объект.РеестрКонтрактов, если процедура находится в модуле формы.

Итоги и рекомендации

Подводя итог, если ваш цикл «игнорирует» строки табличной части, выполните следующие шаги:

  1. Проверьте в отладчике значение Объект.РеестрКонтрактов.Количество(). Если оно равно 0, ищите проблему в передаче данных с клиента на сервер или в записи объекта.
  2. Убедитесь, что в макете для всех ячеек параметров установлено свойство Заполнение = Параметр.
  3. Проверьте написание имен параметров — они должны совпадать с именами в коде до последнего знака.
  4. Используйте ЗаполнитьЗначенияСвойств для автоматизации заполнения строк, это минимизирует риск человеческой ошибки.
  5. Проверьте директивы компиляции (&НаКлиенте, &НаСервере). Формирование макета и обращение к нему должно происходить исключительно на стороне сервера.

Следуя этим правилам, вы сможете быстро локализовать причину пустой печати и обеспечить корректный вывод всех данных реестра контрактов в ваш отчет.

← На главную