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