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