Как прочитать реквизит формы из модуля менеджера документа в 1С

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

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

Анализ архитектурного ограничения

Для начала проанализируем ситуацию с точки зрения архитектуры платформы. Модуль менеджера — это серверный объект, который отвечает за логику, общую для всех экземпляров данного типа документа. Он ничего не знает о конкретном окне (форме), открытом у пользователя на компьютере. В то же время форма — это программный объект интерфейса, существующий в контексте конкретного сеанса пользователя.

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

Вариант 1. Получение данных через запрос к базе данных

Рассмотрим наиболее правильный и универсальный метод. Большинство реквизитов, которые мы видим на форме, либо хранятся в самом объекте (в базе), либо вычисляются на основе других данных. В случае с документом ПоступлениеТоваровИУслуг, поля "Номер счета-фактуры" и "Дата счета-фактуры" обычно не являются реквизитами самого поступления. Они хранятся в связанном документе СчетФактураПолученный.

Разберем по шагам, как получить эти данные в модуле менеджера с помощью запроса:

  1. Определим ссылку на текущий документ (она всегда передается в процедуру печати).
  2. Напишем запрос к таблице связанных счетов-фактур.
  3. Выполним запрос и передадим результат в макет печати.

Посмотрим на пример кода, который можно использовать в функции печати:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 1
    |	СчетФактураПолученный.НомерВходящегоДокумента КАК НомерСФ,
    |	СчетФактураПолученный.ДатаВходящегоДокумента КАК ДатаСФ
    |ИЗ
    |	Документ.СчетФактураПолученный КАК СчетФактураПолученный
    |ГДЕ
    |	СчетФактураПолученный.ДокументОснование = &Ссылка
    |	И НЕ СчетФактураПолученный.ПометкаУдаления";

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

Если Не РезультатЗапроса.Пустой() Тогда
    Выборка = РезультатЗапроса.Выбрать();
    Выборка.Следующий();
    // Теперь у нас есть данные: Выборка.НомерСФ и Выборка.ДатаСФ
КонецЕсли;

Важный момент: всегда проверяйте поле ПутьКДанным у реквизита на форме в конфигураторе. Если путь начинается с Объект..., значит, данные есть в самом документе. Если нет — ищите связанный регистр или документ.

Вариант 2. Использование параметров печати (БСП)

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

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

В модуле формы (клиент):


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

Затем в модуле менеджера в процедуре Печать мы просто извлекаем это значение из структуры:


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

Вариант 3. Временное хранилище (для сложных данных)

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

Рассмотрим этот алгоритм:

  1. В форме документа (на сервере) помещаем данные в хранилище: Адрес = ПоместитьВоВременноеХранилище(ДанныеФормы, ЭтаФорма.УникальныйИдентификатор);.
  2. Передаем полученный Адрес в параметры печати.
  3. В модуле менеджера извлекаем данные: Данные = ПолучитьИзВременногоХранилища(ПараметрыПечати.АдресДанных);.

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

Выясним причину частых ошибок

Основная причина неудач при попытке "дотянуться" до формы из менеджера — игнорирование клиент-серверного взаимодействия. Программисту важно помнить:

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

← На главную