Почему в печатную форму 1С не попадают автоматически заполненные данные и как это исправить?

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

При разработке новых документов и создании печатных форм с помощью встроенного Конструктора печати разработчики часто сталкиваются с ситуацией: в экранной форме документа все реквизиты (например, марка, вес, габариты товара) отображаются корректно, однако при выводе на печать эти поля остаются пустыми. Разберем по шагам, почему так происходит и как правильно настроить получение всех необходимых данных.

Анализ причин проблемы

Для понимания сути проблемы выясним, как работает стандартный механизм формирования печатных форм и почему типовой конструктор упускает часть данных:

  1. Ограничения Конструктора печати: при генерации кода конструктор включает в текст запроса (Запрос.Текст) исключительно собственные реквизиты документа и его табличных частей. Если дополнительные характеристики (вес, марка) подтягиваются из справочника Номенклатура или связанного документа, конструктор не добавляет их в секцию ВЫБРАТЬ автоматически.
  2. Реквизиты формы вместо реквизитов объекта: если колонки созданы исключительно на управляемой форме как элементы интерфейса или пути к данным вида Элементы.Товары.ТекущиеДанные.Номенклатура.Вес, они существуют только в памяти клиента и не сохраняются в таблицах базы данных. Запрос печатной формы обращается к таблицам базы через ссылку (Ссылка) и не видит динамические поля формы.
  3. Несоответствие имен параметров макета и полей выборки: если в ячейке табличного документа установлен тип Параметр, но его наименование отличается от псевдонима в запросе, метод Область.Параметры.Заполнить(Выборка) пропустит заполнение ячейки без генерации системных ошибок.
  4. Печать несохраненного объекта: запрос к базе данных считывает только зафиксированные изменения. Если документ был изменен или только что создан, но не записан перед открытием печатной формы, выборка вернет пустые или устаревшие значения.

Способ 1. Корректировка текста запроса и макета печати

Рассмотрим основной и наиболее правильный способ решения — доработку текста запроса в процедуре печати (в модуле менеджера или модуле объекта). Разберем получение реквизитов через разыменование ссылочных полей.

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ДокументТаблица.НомерСтроки КАК НомерСтроки,
    |	ДокументТаблица.Номенклатура КАК Номенклатура,
    |	ДокументТаблица.Номенклатура.Марка КАК Марка,
    |	ДокументТаблица.Номенклатура.Вес КАК Вес,
    |	ДокументТаблица.Количество КАК Количество,
    |	ДокументТаблица.Цена КАК Цена,
    |	ДокументТаблица.Сумма КАК Сумма
    |ИЗ
    |	Документ.РасходнаяНакладная.Товары КАК ДокументТаблица
    |ГДЕ
    |	ДокументТаблица.Ссылка В(&МассивОбъектов)";

Запрос.УстановитьПараметр("МассивОбъектов", МассивОбъектов);
РезультатЗапроса = Запрос.Выполнить();

После изменения текста запроса настроим макет печатной формы:

  1. Откроем табличный документ (макет) печатной формы в конфигураторе.
  2. Выделим ячейки, куда должны выводиться дополнительные реквизиты (например, марка и вес).
  3. В палитре свойств для свойства Заполнение выберем значение Параметр.
  4. В свойстве Параметр укажем точные имена полей из запроса: Марка и Вес.

Если заполнение параметров макета выполняется вручную, а не методом Заполнить(), дополним код явным присвоением значений:


ВыборкаСтрок = РезультатЗапроса.Выбрать();
Пока ВыборкаСтрок.Следующий() Цикл
    ОбластьСтрока.Параметры.Заполнить(ВыборкаСтрок);
    // Или явное заполнение:
    ОбластьСтрока.Параметры.Марка = ВыборкаСтрок.Марка;
    ОбластьСтрока.Параметры.Вес   = ВыборкаСтрок.Вес;
    ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;

Способ 2. Добавление реквизитов в табличную часть документа

Проанализируем ситуацию, когда значения реквизитов (например, вес или цена на момент выписки) должны быть жестко зафиксированы в документе и не должны меняться в будущем, даже если изменится карточка номенклатуры:

  1. В дереве метаданных конфигуратора перейдем к нужному документу и добавим реквизиты Марка и Вес непосредственно в табличную часть Товары.
  2. В модуле формы документа в обработчике события ПриИзменении поля Номенклатура пропишем автоматическое заполнение добавленных колонок.

Рассмотрим пример заполнения строки на клиенте и сервере формы:


&НаКлиенте
Процедура ТоварыНоменклатураПриИзменении(Элемент)
    СтрокаТаблицы = Элементы.Товары.ТекущиеДанные;
    Если СтрокаТаблицы <> Неопределено Тогда
        ЗаполнитьПараметрыНоменклатурыНаСервере(СтрокаТаблицы.Номенклатура, СтрокаТаблицы);
    КонецЕсли;
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ЗаполнитьПараметрыНоменклатурыНаСервере(Знач СсылкаНоменклатура, СтрокаТаблицы)
    Если ЗначениеЗаполнено(СсылкаНоменклатура) Тогда
        СтрокаТаблицы.Марка = СсылкаНоменклатура.Марка;
        СтрокаТаблицы.Вес   = СсылкаНоменклатура.Вес;
    КонецЕсли;
КонецПроцедуры

При таком подходе данные станут собственными реквизитами табличной части документа, и стандартный запрос Конструктора печати сразу включит их в выборку.

Способ 3. Контроль записи документа перед формированием печати

Если печатная форма формируется из формы документа, убедимся, что все введенные и подтянутые пользователем данные сохранены в базе перед отправкой на печать. Для этого проверим признак модифицированности объекта:


&НаКлиенте
Процедура КомандаПечать(Команда)
    Если Модифицированность Тогда
        Если НЕ ЗаписатьВФорме() Тогда
            Возврат;
        КонецЕсли;
    КонецЕсли;
    
    // Вызов процедуры формирования печатной формы
    СформироватьПечатнуюФорму();
КонецПроцедуры

Способ 4. Формирование печатной формы напрямую из данных объекта

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


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

Использование разыменования полей в запросе или сохранение реквизитов непосредственно в табличной части документа гарантирует, что все подтягиваемые данные корректно попадут в печатную форму.

← На главную