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