Разработка и Конфигурация · 12 мин
1С: как обратиться к процедуре внешней обработки
Как вызвать процедуру или функцию внешней обработки в 1С: методы Создать(), ПолучитьФорму(), вызов клиентских и серверных процедур, типичные ошибки и безопасный подход.
Обращение к процедуре внешней обработки — частая задача при доработке конфигураций 1С без изменения типового кода. Внешняя обработка (файл .epf) содержит собственный модуль объекта, модули форм и экспортные процедуры, которые можно вызвать из другой обработки, отчёта или из кода конфигурации. Ключевая сложность в том, что обращаться к процедурам напрямую «по имени файла» нельзя — сначала нужно создать объект обработки или получить её форму.
Способ вызова зависит от того, где лежит процедура: в модуле объекта обработки, в модуле формы или в общем модуле, а также от контекста исполнения — на клиенте или на сервере. Неправильный выбор контекста приводит к ошибкам вида «Процедура или функция с указанным именем не определена» или «Метод объекта не обнаружен», даже если сам код процедуры написан верно.
Ниже разобраны рабочие способы вызова: через ВнешниеОбработки.Создать(), через ПолучитьФорму(), вызов серверных процедур из клиентского кода, а также ограничения управляемого приложения и типичные ошибки с диагностикой.
Как устроена внешняя обработка и где могут лежать процедуры
Внешняя обработка состоит из нескольких модулей, и место размещения процедуры определяет способ обращения к ней. Модуль объекта — аналог модуля объекта справочника или документа: его экспортные процедуры вызываются через созданный объект обработки. Модуль формы содержит обработчики событий формы и экспортные процедуры, доступные только после получения формы. Реквизиты формы и данные объекта — разные сущности, путать их нельзя.
Процедура становится доступной извне только если в её заголовке указано ключевое слово Экспорт и (в управляемом приложении) директива компиляции, соответствующая нужному контексту: &НаСервере, &НаКлиенте или &НаСервереБезКонтекста. Процедура без Экспорт видна только внутри своего модуля.
Вызов процедуры модуля объекта через ВнешниеОбработки.Создать()
Основной способ обратиться к процедуре модуля объекта — создать объект обработки методом ВнешниеОбработки.Создать(), передав полный путь к файлу .epf. После этого экспортные процедуры вызываются как методы полученного объекта.
&НаСервере
Процедура ВыполнитьОбработкуНаСервере()
ОбъектОбработки = ВнешниеОбработки.Создать("C:\Обработки\МояОбработка.epf");
Результат = ОбъектОбработки.РассчитатьДанные(Параметр1, Параметр2);
КонецПроцедуры
В модуле объекта самой внешней обработки вызываемая процедура должна выглядеть так:
Функция РассчитатьДанные(Парам1, Парам2) Экспорт
// логика
Возврат Результат;
КонецФункции
Обратите внимание: метод ВнешниеОбработки.Создать() доступен только на сервере. Если вызвать его в клиентской процедуре, получите ошибку компиляции или выполнения. Поэтому из клиентского кода вызов оформляется через серверную процедуру-обёртку (см. раздел про клиент-серверное взаимодействие).
Обращение к процедуре модуля формы через ПолучитьФорму()
Если нужная процедура находится в модуле формы внешней обработки, создавать объект не нужно — вместо этого получают форму методом ПолучитьФорму(). В управляемом приложении путь к форме строится от файла обработки:
&НаКлиенте
Процедура ВызватьПроцедуруФормы(Команда)
ФормаОбработки = ПолучитьФорму("ВнешняяОбработка.МояОбработка.Форма.ФормаОбработки");
ФормаОбработки.ЗаполнитьТаблицу(Параметр);
КонецПроцедуры
Такой вызов работает, если обработка подключена к информационной базе (например, через справочник «Дополнительные отчеты и обработки») и известна под именем «МояОбработка». Для файловой обработки, не зарегистрированной в базе, путь формируется иначе — через ВнешняяОбработка с указанием, как она была открыта, поэтому надёжнее передавать в форму параметры при открытии через ОткрытьФорму() и выполнять логику в обработчике ПриСозданииНаСервере или ПриОткрытии.
Важное ограничение: обращение к форме возможно только на клиенте. Серверные процедуры формы вызываются из её же клиентских процедур, но не извне — чужой модуль не может вызвать серверную процедуру чужой формы напрямую.
Вызов серверной процедуры из клиентского кода
Самый частый практический сценарий: пользователь нажимает кнопку в форме, а логика должна выполниться на сервере — например, обратиться к данным информационной базы или создать объект внешней обработки. Прямой вызов невозможен, поэтому используется цепочка: клиентская процедура вызывает серверную процедуру той же формы, а та уже работает с внешней обработкой.
- 1В форме создайте серверную процедуру с директивой &НаСервере или &НаСервереБезКонтекста
- 2Внутри неё вызовите ВнешниеОбработки.Создать(Путь) и нужную экспортную процедуру
- 3В клиентском обработчике команды вызовите эту серверную процедуру по имени
- 4Проверьте, что все передаваемые параметры сериализуемы (примитивы, структуры, таблицы значений — не COM-объекты и не элементы формы)
- 5Запустите и убедитесь, что результат возвращается на клиент без ошибок
&НаКлиенте
Процедура Выполнить(Команда)
Результат = ВыполнитьНаСервере(ПутьКФайлу);
Сообщить(Результат);
КонецПроцедуры
&НаСервереБезКонтекста
Функция ВыполнитьНаСервере(Путь)
ОбъектОбработки = ВнешниеОбработки.Создать(Путь);
Возврат ОбъектОбработки.ПолучитьСводку();
КонецФункции
Если серверной процедуре нужны реквизиты текущей формы, используйте &НаСервере (с контекстом) — тогда внутри доступны реквизиты формы. Если контекст не нужен, предпочтительнее &НаСервереБезКонтекста: вызов выполняется быстрее, потому что состояние формы не передаётся на сервер и обратно.
Подключение обработки через дополнительные отчеты и обработки
Когда обработка зарегистрирована в подсистеме «Дополнительные отчеты и обработки» (БСП), обращаться к ней по файловому пути не нужно и небезопасно — путь может меняться. Вместо этого используется программный интерфейс подсистемы: обработка подключается по имени, а команды вызываются через её форму или через экспортные процедуры модуля объекта после подключения.
Типовой приём — получить ссылку на элемент справочника дополнительных обработок и через методы БСП (например, ДополнительныеОтчетыИОбработки.ПодключитьВнешнююОбработку() в версиях БСП, где он доступен) получить имя подключённой обработки, после чего работать с ней через ВнешниеОбработки.Создать(ИмяПодключеннойОбработки). Точный состав методов зависит от версии библиотеки стандартных подсистем, поэтому сверяйтесь с документацией вашей версии БСП.
Способы вызова процедур внешней обработки
Подходит для процедур модуля объекта; только на сервере; требует известного пути к файлу
Для процедур модуля формы; только на клиенте; форма должна быть доступна по имени
Для обработок, зарегистрированных в базе; устойчиво к смене пути; зависит от версии БСП
Когда нужно передать данные и выполнить логику при открытии; не возвращает значение напрямую
Передача параметров и возврат результата
Параметры в экспортные процедуры передаются как в обычные процедуры встроенного языка — позиционно, с возможностью значений по умолчанию. При вызове между клиентом и сервером действует ограничение: передаваться могут только сериализуемые типы — примитивы, структуры, массивы, таблицы и деревья значений, ссылки на объекты базы. Нельзя передать элемент формы, COM-объект, запрос с открытым результатом или сам объект внешней обработки.
Если процедура внешней обработки должна вернуть сложный результат, оформляйте его как структуру с понятными ключами и проверяйте наличие ключей на стороне вызова. Это защитит от ошибок при доработке обработки, когда состав возвращаемых данных меняется.
Результат = ОбъектОбработки.СформироватьОтчет(ДатаНачала, ДатаОкончания);
Если ТипЗнч(Результат) = Тип("Структура") И Результат.Свойство("ТаблицаДанных") Тогда
// работаем с результатом
КонецЕсли;
Храните путь к внешней обработке не константой в коде, а в константе, регистре сведений или параметре сеанса. Иначе при переносе файла обработки придётся искать и править все места вызова.
Типичные ошибки и их диагностика
Ошибка «Процедура или функция с указанным именем не определена» почти всегда означает одно из трёх: у процедуры нет ключевого слова Экспорт, неверная директива компиляции (клиент пытается вызвать серверную процедуру напрямую) или вызов идёт не к тому модулю — например, процедура лежит в модуле формы, а обращение идёт к объекту. Проверяйте заголовок процедуры в первую очередь.
Ошибка «Метод объекта не обнаружен» при вызове через ВнешниеОбработки.Создать() указывает, что в модуле объекта обработки процедуры с таким именем нет либо она не экспортная. Ошибка «Операции с внешними обработками запрещены в безопасном режиме» возникает при работе в безопасном режиме — например, при вызове из регламентного задания с установленным безопасным режимом.
Как проверить результат
Есть Экспорт и подходящая директива (&НаСервере / &НаКлиенте)
Экспорт отсутствует или директива не соответствует контексту вызова
Файл существует по указанному пути, открывается в конфигураторе
Файл не найден или повреждён
Процедура выполняется, результат возвращается ожидаемого типа
Ошибка о неопределённой процедуре или о безопасном режиме
FAQ
Можно ли вызвать процедуру внешней обработки из модуля документа конфигурации?
Да, если код выполняется на сервере. В модуле объекта документа вызовите ВнешниеОбработки.Создать(Путь) и далее экспортную процедуру. Учтите, что это создаёт зависимость конфигурации от внешнего файла: при его отсутствии проведение документа будет падать, поэтому оборачивайте вызов в попытку-исключение.
Как вызвать процедуру внешней обработки из другой внешней обработки?
Точно так же: в модуле объекта первой обработки на сервере создайте объект второй через ВнешниеОбработки.Создать() и вызовите её экспортную процедуру. Если обе обработки открыты интерактивно, программное создание объекта всё равно выполняется на сервере.
Почему ВнешниеОбработки.Создать() недоступен в тонком клиенте?
Менеджер внешних обработок работает только на сервере — это ограничение платформы, а не ошибка в коде. Решение стандартное: вызывайте создание объекта внутри серверной процедуры формы или общего модуля с признаком «Сервер».
Как передать таблицу значений в процедуру внешней обработки?
Таблица значений сериализуема, поэтому её можно передать параметром между клиентом и сервером и далее в процедуру обработки. Если таблица лежит в реквизите формы типа «ДанныеФормыКоллекция», сначала преобразуйте её в таблицу значений через РеквизитФормыВЗначение() на сервере.
Что делать, если обработка должна работать и в обычном, и в управляемом приложении?
Разделяйте код по директивам компиляции и инструкциям препроцессора #Если ТолстыйКлиентОбычноеПриложение. В обычном приложении ВнешниеОбработки.Создать() доступен и на клиенте, в управляемом — только на сервере, поэтому единый код без разделения контекстов работать не будет.
Можно ли вызвать процедуру обработки, открытой интерактивно пользователем?
Напрямую — нет: у открытой обработки нет глобально доступного имени. Если нужно взаимодействие между открытыми формами, используйте оповещения (Оповестить / ОбработкаОповещения) или передавайте в форму при открытии уникальный ключ, по которому её можно найти.
Что важно запомнить
Процедуры модуля объекта вызываются через ВнешниеОбработки.Создать(путь) — только на сервере; процедуры формы — через ПолучитьФорму() на клиенте. Процедура должна быть экспортной и иметь правильную директиву компиляции. Путь к файлу лучше хранить в настройках, а вызовы оборачивать в обработку ошибок.