Как вызвать экспортную функцию модуля документа на сервере и почему возникает ошибка «Метод объекта не обнаружен»?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке управляемых форм или интеграционных механизмов часто возникает задача получить список печатных форм либо вызвать другую экспортную логику документа. На этапе тестирования в файловой информационной базе код вида Документы[ИмяДокумента].СоздатьДокумент().ПолучитьСтруктуруПечатныхФорм() успешно выполняется, однако после переноса конфигурации в клиент-серверную базу (на сервер 1С) система выдает ошибку времени выполнения: «Метод объекта не обнаружен».

Разберем детально, почему возникает такое поведение платформы 1С:Предприятие, и рассмотрим правильные варианты реализации подобной логики.

Выясним причину ошибки: контекст исполнения и директивы препроцессора

Проанализируем механизм компиляции модулей объектов в различных режимах работы 1С:

  1. Директивы препроцессора в типовых модулях. В конфигурациях на обычных формах или гибридных решениях (УПП 1.3, УТ 10.3, КА 1.1) экспортные функции печати и формирования списков макетов в модулях документов традиционно заключены в инструкции препроцессора #Если Клиент Тогда (или #Если ТолстыйКлиентОбычноеПриложение Тогда).
  2. Поведение в файловой базе. При запуске толстого клиента в файловом режиме клиентский и серверный код исполняются в едином процессе. Условие директивы #Если Клиент Тогда выполняется, поэтому экспортный метод компилируется и доступен в объекте даже при обращении из серверных процедур формы.
  3. Поведение в клиент-серверной базе. На сервере 1С при выполнении процедуры с директивой &НаСервере модуль документа компилируется строго в серверном контексте. Препроцессор полностью исключает весь программный код, находящийся внутри блоков #Если Клиент.... В скомпилированном серверном экземпляре ДокументОбъект метод физически отсутствует, что и приводит к ошибке «Метод объекта не обнаружен».

Способ 1. Перенос логики в модуль менеджера документа (рекомендуемый подход)

В соответствии со стандартами разработки 1С методы, возвращающие общую информацию о документе (состав макетов, команды печати, правила проведения), не должны требовать создания тяжеловесного объекта ДокументОбъект. Их следует размещать в модуле менеджера документа.

Посмотрим на пример вызова экспортной функции модуля менеджера на сервере:


&НаСервере
Функция ПолучитьПечатныеФормыНаСервере(ИмяДокумента)
    // Обращаемся напрямую к менеджеру документа по его имени
    МенеджерДокумента = Документы[ИмяДокумента];
    
    // Вызываем экспортную функцию модуля менеджера
    Возврат МенеджерДокумента.ПолучитьСтруктуруПечатныхФорм();
КонецФункции

Если конфигурация типовая и находится на поддержке, переопределить модуль менеджера или добавить в него нужные функции можно с помощью расширения конфигурации.

Способ 2. Корректировка директив препроцессора в модуле документа

Если перенос логики в модуль менеджера невозможен и модуль документа доступен для изменения, скорректируем директивы препроцессора, чтобы процедура была доступна серверному коду.

Разберем по шагам:

  1. Откроем модуль объекта нужного документа.
  2. Найдем определение функции (например, Функция ПолучитьСтруктуруПечатныхФорм() Экспорт).
  3. Убедимся, что внутри функции отсутствуют вызовы интерактивных клиентских методов (например, Предупреждение(), Вопрос(), работа с интерфейсными окнами).
  4. Вынесем функцию за пределы блока #Если Клиент Тогда либо укажем явную директиву компиляции для всех контекстов:

#Если Клиент Или Сервер Или ВнешнееСоединение Тогда

Функция ПолучитьСтруктуруПечатныхФорм() Экспорт
    СтруктураФорм = Новый Структура;
    СтруктураФорм.Вставить("Накладная", "Товарная накладная");
    СтруктураФорм.Вставить("Счет", "Счет на оплату");
    Возврат СтруктураФорм;
КонецФункции

#КонецЕсли

После этого создание объекта через Документы[ИмяДокумента].СоздатьДокумент() на сервере будет успешно предоставлять доступ к экспортному методу.

Способ 3. Получение состава макетов напрямую из метаданных

Если экспортная функция модуля использовалась исключительно для получения списка доступных макетов печатных форм документа, мы можем избежать вызова процедур документа и прочитать данные напрямую через дерево метаданных конфигурации на сервере:


&НаСервере
Функция ПолучитьСписокМакетовДокумента(ИмяДокумента)
    СписокМакетов = Новый СписокЗначений;
    
    ОбъектМетаданных = Метаданные.Документы.Найти(ИмяДокумента);
    Если ОбъектМетаданных <> Неопределено Тогда
        Для Каждого Макет Из ОбъектМетаданных.Макеты Цикл
            СписокМакетов.Добавить(Макет.Имя, Макет.Синоним);
        КонецЦикла;
    КонецЕсли;
    
    Возврат СписокМакетов;
КонецФункции

Данный подход работает полностью универсально, не требует создания экземпляров объектов в памяти и гарантированно выполняется одинаково как в файловом, так и в клиент-серверном режиме.

← На главную