Как программно запустить внешнюю обработку из справочника на обычных формах?

Программист 1С v8.3 (Обычные формы)
← На главную

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

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

Анализ ошибки: почему не работает ВнешниеОбработки.Подключить() с временным хранилищем

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

Посмотрим на пример кода, который приводит к ошибке:


// Находим нужную обработку в справочнике
ВО = Справочники.ВнешниеОбработки.НайтиПоНаименованию("МояОбработка");
// Получаем двоичные данные из хранилища
ДвоичныеДанные = ВО.ХранилищеВнешнейОбработки.Получить();
// Помещаем данные во временное хранилище и получаем адрес
АдресВоВременномХранилище = ПоместитьВоВременноеХранилище(ДвоичныеДанные);
// Пытаемся подключить обработку по адресу - ЭТОТ КОД ВЫЗОВЕТ ОШИБКУ!
ИмяОбработки = ВнешниеОбработки.Подключить(АдресВоВременномХранилище, , Ложь);

При выполнении последней строки система выдаст ошибку "Ошибка при вызове метода контекста "Подключить"". Выясним причину. Дело в том, что метод ВнешниеОбработки.Подключить() в качестве первого параметра ожидает не адрес данных в памяти (которым является адрес во временном хранилище), а полный путь к файлу на диске (например, "C:\Temp\my_processing.epf"). Платформа должна иметь возможность прочитать файл с диска для его регистрации в системе. Попытка передать ему что-то иное приводит к ошибке.

Правильное решение: запуск через временный файл

Наиболее надежный и универсальный способ для конфигураций на обычных формах — это эмуляция стандартного поведения, то есть временное сохранение обработки на диск. Алгоритм действий будет следующим:

  1. Получить двоичные данные обработки из справочника.
  2. Сгенерировать уникальное имя для временного файла с расширением .epf.
  3. Записать двоичные данные в этот временный файл.
  4. Выполнить необходимое действие с файлом: открыть его форму или создать экземпляр обработки.
  5. Удалить временный файл, чтобы не засорять дисковое пространство.

Разберем этот процесс по шагам на основе рабочего примера кода.

Этот код является комплексным решением: он находит обработку, проверяет её вид, сохраняет во временный файл и открывает основную форму.


// 1. Находим нужный элемент справочника, где хранится обработка
ВнешняяОбработкаСсылка = Справочники.ВнешниеОбработки.НайтиПоНаименованию("Имя вашей обработки");

// 2. Проверяем, что это действительно обработка (а не, например, отчет)
// В вашей конфигурации перечисление и реквизит могут называться иначе
Если ВнешняяОбработкаСсылка.ВидОбработки = Перечисления.ВидыДополнительныхВнешнихОбработок.Обработка Тогда

    // 3. Получаем имя для временного файла. Система сама подберет для него место
    ИмяФайла = ПолучитьИмяВременногоФайла("epf");

    // 4. Извлекаем двоичные данные из хранилища
    ДвоичныеДанные = ВнешняяОбработкаСсылка.ХранилищеВнешнейОбработки.Получить();

    // 5. Записываем данные в созданный временный файл
    ДвоичныеДанные.Записать(ИмяФайла);

    // 6. Получаем объект формы из файла и открываем его
    // Имя формы можно не указывать, тогда откроется основная форма
    Форма = ВнешниеОбработки.ПолучитьФорму(ИмяФайла);
    Форма.Открыть();
    
    // 7. (Необязательно, но рекомендуется) Удаляем временный файл после использования
    // Этот шаг стоит выполнять, когда форма обработки будет закрыта,
    // либо если дальнейшая работа с файлом не требуется.
    // Для простоты примера, удаление показано сразу.
    // В реальной задаче может потребоваться более сложная логика.
    УдалитьФайлы(ИмяФайла);

КонецЕсли;

Этот метод абсолютно надежен и будет работать на любой версии платформы 1С, поддерживающей обычные формы.

Дополнительный сценарий: вызов экспортных методов без открытия формы

Иногда требуется не открывать интерфейс обработки, а выполнить какую-либо её экспортную процедуру или функцию. Для этого используется связка методов Подключить() и Создать(). Алгоритм будет очень похож, но вместо открытия формы мы будем создавать объект обработки.

Рассмотрим на примере:


ИмяПодключеннойОбработки = "";
ИмяФайла = "";

Попытка
    // Шаги 1-5: получение данных и сохранение во временный файл (аналогично предыдущему примеру)
    ВнешняяОбработкаСсылка = Справочники.ВнешниеОбработки.НайтиПоНаименованию("ОбработкаСЭкспортнойПроцедурой");
    ДвоичныеДанные = ВнешняяОбработкаСсылка.ХранилищеВнешнейОбработки.Получить();
    ИмяФайла = ПолучитьИмяВременногоФайла("epf");
    ДвоичныеДанные.Записать(ИмяФайла);

    // Шаг 6: Подключаем обработку, используя путь к файлу. 
    // Метод возвращает уникальное имя, под которым обработка зарегистрирована в системе.
    ИмяПодключеннойОбработки = ВнешниеОбработки.Подключить(ИмяФайла);

    // Шаг 7: Создаем экземпляр объекта обработки
    ОбъектОбработки = ВнешниеОбработки.Создать(ИмяПодключеннойОбработки);

    // Шаг 8: Вызываем экспортный метод
    ОбъектОбработки.МояЭкспортнаяПроцедура("Параметр1", 123);
    
    // Получаем результат из экспортной функции
    Результат = ОбъектОбработки.МояЭкспортнаяФункция();
    Сообщить("Результат выполнения: " + Результат);

Исключение
    Сообщить("Не удалось выполнить внешнюю обработку: " + ОписаниеОшибки());
КонецПопытки;

// Шаг 9: Отключаем обработку и удаляем временный файл
Если ЗначениеЗаполнено(ИмяПодключеннойОбработки) Тогда
    ВнешниеОбработки.Отключить(ИмяПодключеннойОбработки);
КонецЕсли;

Если ЗначениеЗаполнено(ИмяФайла) Тогда
    УдалитьФайлы(ИмяФайла);
КонецЕсли;

Важный момент: использование блока Попытка...Исключение и последующая обязательная очистка (отключение обработки и удаление файла) являются хорошей практикой. Это гарантирует, что даже в случае ошибки в коде обработки ваша система не останется с "мусором" в виде временных файлов и подключенных, но неиспользуемых обработок.

Таким образом, мы рассмотрели два надежных способа программной работы с внешними обработками, хранящимися в базе данных. Главный вывод — для взаимодействия с методами менеджера ВнешниеОбработки необходимо сначала материализовать двоичные данные в виде файла на диске.

← На главную