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