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