При переходе на управляемые формы многие разработчики сталкиваются с тем, что привычные методы работы с внешними файлами обработок (.epf) и отчетов (.erf) перестают работать. В обычном приложении мы могли просто создать объект обработки и открыть его форму. В управляемом приложении, работающем в архитектуре клиент-сервер, этот процесс требует иного подхода, связанного с передачей данных между клиентом и сервером и использованием безопасного режима.
Разберем подробно, как правильно реализовать программное открытие формы внешней обработки, расположенной на диске или в макете, чтобы это работало стабильно и безопасно.
В управляемом приложении непосредственная работа с объектами обработок происходит на сервере. Однако, команду на открытие формы мы отдаем на клиенте. Главная сложность заключается в том, что клиент не имеет прямого доступа к файловой системе сервера (в общем случае), а сервер не умеет открывать визуальные формы.
Поэтому алгоритм наших действий всегда будет сводиться к следующей схеме:
Рассмотрим реализацию этого алгоритма по шагам.
Для работы с внешними файлами в 1С 8.3 существует менеджер ВнешниеОбработки. Перед их использованием полезно провести анализ кода через статический анализатор. Ключевым методом здесь является функция Подключить.
Давайте проанализируем, как правильно написать серверную функцию, которая подготовит нашу обработку к открытию. Нам необходимо передать путь к файлу (адрес во временном хранилище или путь на диске) и получить имя подключенной обработки.
Рассмотрим пример функции, которую следует разместить в модуле формы или общем серверном модуле:
&НаСервере
Функция ПодключитьВнешнююОбработку(АдресХранилищаИлиПуть)
// Параметр Истина указывает на использование безопасного режима.
// Если обработка делает "опасные" действия (запись файлов, COM-объекты),
// возможно, потребуется передать Ложь.
ИмяОбработки = ВнешниеОбработки.Подключить(АдресХранилищаИлиПуть, , Ложь);
Возврат ИмяОбработки;
КонецФункции
Обратите внимание на параметры метода Подключить (для правильной интеграции в БСП часто удобнее использовать расширенный шаблон):
C:\Exchange\MyProcess.epf) или навигационная ссылка на временное хранилище, куда мы предварительно поместили файл.Истина (по умолчанию), то во внешней обработке могут быть заблокированы попытки работы с файловой системой или внешними компонентами. Для доверенных обработок часто приходится ставить Ложь.Теперь, когда у нас есть серверная функция, давайте посмотрим, как вызвать открытие формы с клиента. Предположим, файл обработки лежит на сервере по фиксированному пути (например, после того как мы выполнили выгрузку обработок в папку).
Мы будем использовать метод ОткрытьФорму. Особенность в том, как мы формируем строку с именем формы. Для подключенных внешних обработок формат такой: ВнешняяОбработка.ИмяПодключеннойОбработки.Форма.ИмяФормы.
Рассмотрим код команды на клиенте:
&НаКлиенте
Процедура ОткрытьОбработкуПоКнопке(Команда)
ПутьКФайлуНаСервере = "C:\Data\Report.epf";
// 1. Подключаем обработку и получаем ее временное имя
ИмяПодключенной = ПодключитьВнешнююОбработку(ПутьКФайлуНаСервере);
// 2. Формируем путь к форме
// "Форма" - это имя основной формы обработки. Если нужно открыть конкретную,
// укажите её имя, например "ФормаНастройки".
ПутьКФорме = "ВнешняяОбработка." + ИмяПодключенной + ".Форма";
// 3. Открываем форму
ОткрытьФорму(ПутьКФорме);
КонецПроцедуры
Часто бывает ситуация, когда внешняя обработка хранится внутри конфигурации как макет (тип ДвоичныеДанные) или внутри другой обработки. В этом случае у нас нет пути к файлу на диске. Как быть?
Нам необходимо "материализовать" этот файл во временном хранилище. Разберем этот процесс.
Сначала извлечем макет и поместим его во временное хранилище. Это делается на сервере:
&НаСервере
Функция ПодготовитьОбработкуИзМакета()
// Получаем макет из текущей обработки или справочника
// Предположим, этот код в модуле формы обработки, где есть макет "МояВнешняяОбработка"
ДвоичныеДанные = РеквизитФормыВЗначение("Объект").ПолучитьМакет("МояВнешняяОбработка");
// Помещаем во временное хранилище.
// УникальныйИдентификатор формы передаем, чтобы данные жили, пока жива форма.
Адрес = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
// Подключаем, используя АДРЕС, а не путь к файлу
ИмяОбработки = ВнешниеОбработки.Подключить(Адрес, , Ложь);
Возврат ИмяОбработки;
КонецФункции
Код на клиенте останется практически таким же, только мы будем вызывать новую функцию:
&НаКлиенте
Процедура ОткрытьВложеннуюОбработку(Команда)
Имя = ПодготовитьОбработкуИзМакета();
ОткрытьФорму("ВнешняяОбработка." + Имя + ".Форма");
КонецПроцедуры
Очень часто нам нужно не просто открыть обработку, но и передать в нее какие-то данные (например, ссылку на документ или дату). Для этого используем второй параметр метода ОткрытьФорму — структуру параметров.
Рассмотрим пример, где мы передаем ссылку на контрагента во внешнюю обработку:
&НаКлиенте
Процедура ОткрытьСПараметрами(КонтрагентСсылка)
ИмяОбработки = ПодключитьВнешнююОбработку("D:\PrintForms\Invoice.epf");
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Контрагент", КонтрагентСсылка);
ПараметрыФормы.Вставить("ДатаФормирования", ТекущаяДата());
// Передаем структуру параметров при открытии
ОткрытьФорму("ВнешняяОбработка." + ИмяОбработки + ".Форма", ПараметрыФормы);
КонецПроцедуры
В самой внешней обработке, в модуле формы в процедуре ПриСозданииНаСервере, вы сможете перехватить эти данные:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("Контрагент") Тогда
// Логика обработки переданного параметра
Объект.Контрагент = Параметры.Контрагент;
КонецЕсли;
КонецПроцедуры
При реализации данного механизма стоит обратить внимание на несколько моментов, которые часто вызывают ошибки:
Подключить, виден именно серверу 1С. Если вы укажете путь C:\Users\User\Desktop\..., сервер 1С (запущенный под служебной учетной записью) скорее всего не увидит этот путь. Лучше использовать общие сетевые папки или временное хранилище.БезопасныйРежим = Истина (или не указали его вовсе), вы получите ошибку нарушения прав доступа. Всегда анализируйте, что делает подключаемая обработка."ВнешняяОбработка." + Имя + ".Форма.ФормаУправляемая".Таким образом, использование метода ВнешниеОбработки.Подключить является стандартом для работы в управляемых формах. Этот подход универсален как для файлов на диске, так и для макетов, хранящихся внутри конфигурации.