При обновлении типовых конфигураций (таких как 1С:Комплексная автоматизация 2 или 1С:ERP) до актуальных релизов разработчики часто сталкиваются с ситуацией, когда стабильно работавший ранее код в расширениях начинает выдавать ошибку Метод объекта не обнаружен. Особенно часто это происходит при переходе на платформу 8.3.21 и установке соответствующего режима совместимости. В данной статье мы подробно разберем, почему экспортные процедуры модулей форм становятся «невидимыми» для вызывающего кода и как правильно адаптировать расширение под новые требования платформы.
Рассмотрим сценарий: в расширении для документа (например, ЗаказКлиента) добавлен экспортный серверный метод. Этот метод вызывается из общего модуля, куда передается объект формы в качестве параметра. До обновления (например, на режиме совместимости 8.3.17) такой вызов проходил успешно. Однако после обновления платформы до версии 8.3.21.1622 и выше, система перестает видеть серверные экспортные методы формы, если вызов инициирован из клиентского контекста общего модуля.
Это связано с ужесточением контроля вызовов и безопасности. Платформа в режиме совместимости 8.3.21 накладывает ограничения на прямой вызов серверных методов формы (даже помеченных как Экспорт) через точку от объекта формы, если этот вызов происходит «извне». Система безопасности платформы теперь требует явного разграничения между клиентскими и серверными вызовами при работе с контекстом формы.
Проанализируем пример кода из общего модуля, который вызывает процедуру в модуле формы. В типовых решениях, таких как проверка контрагентов через 1С:Контрагент, часто встречается подобная логика:
Процедура ЗапуститьПроверкуКонтрагентовВДокументе(Форма, ДополнительныеПараметры = Неопределено) Экспорт
// ... подготовка параметров ...
ПараметрыФоновогоЗадания = ПроверкаКонтрагентовКлиентСервер.ПараметрыФоновогоЗадания(ДополнительныеПараметры);
// ОШИБКА ЗДЕСЬ: Прямой вызов серверного метода формы
Форма.ПроверитьКонтрагентовФоновоеЗадание(ПараметрыФоновогоЗадания);
КонецПроцедуры
Если в модуле формы процедура ПроверитьКонтрагентовФоновоеЗадание объявлена с директивой &НаСервере, то при передаче Форма как объекта ФормаКлиентскогоПриложения, метод не будет найден. Платформа ожидает, что внешние вызовы к форме на клиенте будут адресованы только к клиентским методам.
Самый надежный и правильный способ решения данной проблемы — создание «клиентской прокладки». Мы должны изменить структуру вызовов таким образом, чтобы общий модуль обращался к клиентскому экспортному методу формы, который, в свою очередь, уже внутри формы вызовет серверный контекст. Рассмотрим пошагово, как это реализовать.
Шаг 1. Изменение модуля формы в расширении.
Вместо того чтобы оставлять только серверный метод, добавим клиентский экспортный метод ПроверитьКонтрагентовФоновоеЗадание, который будет служить входной точкой:
&НаКлиенте
Процедура ПроверитьКонтрагентовФоновоеЗадание(ПараметрыФоновогоЗадания) Экспорт
// Вызываем серверный метод этой же формы
ПроверитьКонтрагентовФоновоеЗаданиеНаСервере(ПараметрыФоновогоЗадания);
КонецПроцедуры
&НаСервере
Процедура ПроверитьКонтрагентовФоновоеЗаданиеНаСервере(ПараметрыФоновогоЗадания)
// Вызов основной логики проверки
ПроверкаКонтрагентов.ПроверитьКонтрагентовВДокументеФоновоеЗадание(ЭтотОбъект, ПараметрыФоновогоЗадания);
КонецПроцедуры
Шаг 2. Вызов из общего модуля.
Теперь, когда мы вызываем Форма.ПроверитьКонтрагентовФоновоеЗадание(Параметры) из клиентского общего модуля, платформа видит клиентский экспортный метод формы. Ошибки Метод объекта не обнаружен более не возникает, так как происходит обращение Клиент -> Клиент, а переход на сервер осуществляется уже внутри штатного механизма формы.
Выясним еще одну важную причину, по которой методы расширения могут быть недоступны. При работе в клиент-серверном варианте расширения часто подключаются в безопасном режиме. В этом режиме возможности расширения методов существенно ограничены:
ПриСозданииНаСервере). Прямые вызовы произвольных серверных Экспорт-процедур расширения из кода основной конфигурации могут блокироваться.Проанализируем настройки вашего расширения. Если вы столкнулись с подобной ошибкой, проверьте в свойствах расширения флаг Безопасный режим. Если логика работы требует вызова серверных методов формы из общих модулей основной конфигурации, попробуйте снять этот флаг (предварительно убедившись в безопасности вносимых изменений) или настроить соответствующие профили безопасности в кластере 1С.
Иногда проблема носит «фантомный» характер и связана с особенностями кэширования модулей платформой 8.3.21. Если вы добавили метод, но ошибка сохраняется, выполните следующие действия:
/ClearCache может быть недостаточно — требуется перезапуск службы rphost или удаление содержимого папки snaccfg на сервере.В исключительных случаях, если по каким-то причинам невозможно создать клиентскую обертку (например, при жестко заданной структуре вызовов в типовом коде, который вы не хотите менять), разработчики прибегают к использованию функций динамического исполнения кода. Однако мы рекомендуем использовать этот подход только в крайнем случае:
// Пример использования динамического вызова (не рекомендуется как основной способ)
Попытка
Выполнить("Форма.ПроверитьКонтрагентовФоновоеЗадание(ПараметрыФоновогоЗадания)");
Исключение
ЗаписьЖурналаРегистрации("ОшибкаВызоваМетода", УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
Использование Выполнить позволяет «обмануть» компилятор на этапе проверки типов, но может привести к трудноотлаживаемым ошибкам в будущем. Правильным стратегическим решением остается разделение вызовов на клиентскую и серверную части внутри модуля формы.
Подведем итог. Если после обновления конфигурации на КА 2.5.12 или ERP 2.5.12 вы получили ошибку отсутствия метода формы в расширении:
Соблюдение этих правил позволит сохранить работоспособность ваших доработок при переходе на новые версии платформы 1С:Предприятие.