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

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

Часто при разработке в 1С возникает задача: пользователь выбирает какое-то значение (например, сотрудника) в специальном поле на форме документа, и это значение нужно вывести в печатную форму. Проблема в том, что печатная форма формируется на сервере в модуле менеджера, а наше поле является лишь программным реквизитом, созданным на форме. Из-за этого модуль менеджера его "не видит". Проанализируем эту ситуацию и разберем по шагам, как правильно решить данную задачу.

Понимание архитектуры: где хранятся данные?

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

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

Решение 1: Превращение реквизита формы в реквизит объекта (Рекомендуемое)

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

Рассмотрим порядок действий:

  1. Откроем конфигуратор и добавим новый реквизит непосредственно в метаданные самого документа (например, Сотрудник с типом СправочникСсылка.Сотрудники).
  2. Вынесем этот реквизит на форму. Теперь он является частью данных объекта, а не просто "виртуальным" полем.
  3. При записи документа выбранный сотрудник сохранится в базу данных.
  4. В модуле менеджера в процедуре печати мы просто получим это значение стандартным запросом к таблице документа по переданной Ссылка.

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

Решение 2: Передача через параметры печати (для конфигураций на БСП)

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

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


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

Затем перейдем в модуль менеджера документа. Там располагается серверная процедура печати, в которую мы передали структуру:


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

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

Решение 3: Использование временного хранилища (для нетиповых задач)

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

Перед тем как обратиться к серверу для формирования печатной формы, мы помещаем значение сотрудника во временное хранилище с помощью метода ПоместитьВоВременноеХранилище. Метод вернет нам строковый адрес в памяти.

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

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

← На главную