При разработке и доработке конфигураций 1С в режиме обычного или управляемого приложения иногда возникает неожиданное поведение: в файловой базе код отбатывает безошибочно, однако при переходе в клиент-серверный режим платформа выдает исключение вида «Метод объекта не обнаружен». Проанализируем, почему возникает эта ошибка и как её исправить на примере вызова экспортируемой функции из модуля менеджера регистра сведений.
Рассмотрим конкретную ситуацию. Из модуля формы справочника Номенклатура выполняется вызов метода регистра сведений ТоварыСПониженнойСтавкойПошлин:
СписокТНВЭДПереченьИзъятий = РегистрыСведений.ТоварыСПониженнойСтавкойПошлин.ЗаполнитьСписокПереченьИзъятий();
При этом в модуле менеджера регистра метод описан как экспортный и обернут в инструкции препроцессора и директивы компиляции:
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
&НаСервере
Функция ЗаполнитьСписокПереченьИзъятий() Экспорт
СписокТНВЭДПереченьИзъятий = Новый СписокЗначений;
ПереченьИзъятий = ПолучитьАктуальныйПереченьИзъятий();
СписокТНВЭДПереченьИзъятий.ЗагрузитьЗначения(ПереченьИзъятий);
Возврат СписокТНВЭДПереченьИзъятий;
КонецФункции
#КонецЕсли
В файловом варианте работы данные команды выполняются корректно, а в клиент-серверном варианте платформа выдает исключение о том, что метод ЗаполнитьСписокПереченьИзъятий не обнаружен.
Проанализируем контексты компиляции и разницу между инструкциями препроцессора и директивами компиляции в платформе «1С:Предприятие».
&НаСервере, &НаКлиенте, &НаСервереБезКонтекста) предназначены исключительно для использования в модулях управляемых форм и модулях команд. Они определяют, в каком именно контексте компилируется конкретная процедура или функция формы.#Если Сервер, #Если ТолстыйКлиентОбычноеПриложение, #КонецЕсли) используются во всех остальных типах модулей (модули объектов, модули менеджеров, общие модули) для управления включением кода в ту или иную область сборки.&НаСервере над процедурой в модуле менеджера исключает этот метод из клиентской области видимости, что приводит к ошибке «Метод объекта не обнаружен».Разберем по шагам, как исправить код в модуле менеджера для стабильной работы как в файловом, так и в клиент-серверном режиме.
Основное решение — удалить все директивы компиляции (&НаСервере) из модуля менеджера. Контроль доступа к коду должен осуществляться только через инструкции препроцессора.
Посмотрим на исправленный вариант модуля менеджера регистра сведений:
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
Функция ЗаполнитьСписокПереченьИзъятий() Экспорт
СписокТНВЭДПереченьИзъятий = Новый СписокЗначений;
ПереченьИзъятий = ПолучитьАктуальныйПереченьИзъятий();
СписокТНВЭДПереченьИзъятий.ЗагрузитьЗначения(ПереченьИзъятий);
Возврат СписокТНВЭДПереченьИзъятий;
КонецФункции
Функция ПолучитьАктуальныйПереченьИзъятий()
Результат = Новый Массив;
Макет = Неопределено;
Попытка
Макет = ЭСФСерверПовтИсп.ОбработкаОбменЭСФ().ПолучитьМакет("ПереченьИзъятий");
Исключение
КонецПопытки;
Если Макет = Неопределено Тогда
Возврат Результат;
КонецЕсли;
Возврат ОбщегоНазначения.ЗначениеИзСтрокиXML(Макет.ПолучитьТекст()).ВыгрузитьКолонку("КодТНВЭД");
КонецФункции
#КонецЕсли
Если метод выполняет ресурсоемкие серверные операции или обращается к серверным объектам, которые недоступны на клиенте, разберем рекомендации по правильной организации кода:
Сервер и Вызов сервера. Тогда метод модуля формы сможет напрямую обращаться к серверной функции общего модуля.&НаСервере или &НаСервереБезКонтекста.Резюме: Никогда не используйте директивы компиляции (начинающиеся со знака &) внутри модулей объектов и менеджеров. Для управления контекстом в них служат исключительно инструкции препроцессора (начинающиеся со знака #).