В процессе разработки в среде 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда код успешно проходит синтаксическую проверку по Ctrl+F7, но в режиме «Тонкого клиента» при попытке выполнить действие система выдает критическую ошибку: «Метод объекта не обнаружен». Особенно часто это происходит при работе с расширениями и попытках вызвать серверную логику из модуля формы. Рассмотрим подробно, почему это происходит, разберем механизмы компиляции модулей и выясним, как правильно настраивать общие модули для корректной работы.
Для начала проанализируем ситуацию. Когда мы создаем общий модуль в конфигураторе, у него есть набор свойств (флажков), определяющих, где этот модуль будет «жить» во время работы программы. Основная путаница возникает из-за смешивания понятий «место исполнения» и «область видимости».
Если в свойствах общего модуля одновременно установлены флаги «Клиент (управляемое приложение)» и «Сервер», платформа ведет себя следующим образом: она создает две независимые копии этого модуля. Одна копия компилируется на стороне сервера, а другая — на стороне клиентского приложения (Тонкого клиента). Рассмотрим, что происходит при вызове метода:
Важный момент, который мы должны уяснить: в общих модулях нельзя использовать директивы типа &НаСервере или &НаКлиенте. Эти директивы предназначены исключительно для модулей форм и команд. В общих модулях используются инструкции препроцессора.
Посмотрим на типичный ошибочный пример кода в общем модуле:
&НаСервере // ОШИБКА: Так писать в общем модуле нельзя!
Функция ВыполнитьРасчет(Данные) Экспорт
// Логика расчета
Возврат Результат;
КонецФункции
Правильный подход заключается в управлении видимостью кода через свойства модуля или через инструкции препроцессора #Если. Если вы написали &НаСервере внутри общего модуля, платформа может просто проигнорировать эту функцию при компиляции клиентской части, что и приведет к ошибке «Метод объекта не обнаружен» при вызове с клиента.
Выясним, какая комбинация настроек является рабочей для вызова серверной функции с клиента. Рассмотрим пошагово процесс исправления.
Шаг 1. Настройка свойств модуля.
Если ваша задача — вызвать тяжелую серверную функцию или задействовать конвейер обработки задач из модуля формы, который выполняется на клиенте, настройки общего модуля должны быть следующими:
Шаг 2. Корректировка кода модуля.
Удалим все амперсанды (&) перед названиями функций. Функция должна быть просто объявлена как экспортная:
Функция МояОбщаяФункция(Параметры) Экспорт
// Здесь идет серверный код
Возврат Истина;
КонецФункции
Шаг 3. Логика вызова.
Теперь при вызове МойОбщийМодуль.МояОбщаяФункция() из модуля формы на клиенте платформа поймет: «На клиенте этого модуля нет, но есть серверный модуль с разрешенным вызовом сервера. Я выполню удаленный вызов процедуры (RPC)». Это именно то, чего мы добивались.
Проанализируем ситуацию: когда вы снимаете флаг «Клиент», вы убираете двусмысленность для платформы. Теперь у системы нет «локальной» клиентской копии модуля, в которой она могла бы искать метод. Платформа вынуждена обратиться к серверной копии. А наличие флага «Вызов сервера» дает ей на это легальное право.
Если же оставить оба флага («Клиент» и «Сервер»), то при вызове с клиента платформа обратится к клиентской версии модуля. Если в ней из-за условий препроцессора функция «не видна», вы получите ошибку, даже если на сервере эта функция существует и помечена как экспортная.
Чтобы избежать подобных проблем в будущем, рассмотрим стандарты разработки, рекомендованные фирмой «1С». Профессиональная архитектура подразумевает разделение общих модулей по типам контекста:
ИмяМодуляСервер.Рассмотрим пример правильной организации вызова через посредника:
Код в модуле ОбщийМодульВызовСервера:
Функция ПолучитьДанныеДляФормы(ID) Экспорт
// Перенаправляем вызов в чисто серверный модуль
Возврат ОбщийМодульСервер.РассчитатьНаСервере(ID);
КонецФункции
Код в модуле ОбщийМодульСервер:
Функция РассчитатьНаСервере(ID) Экспорт
// Сложные запросы к БД
Возврат Результат;
КонецФункции
Если настройки модулей верны, но ошибка сохраняется, проанализируем другие возможные причины:
/ClearCache или просто переоткройте конфигуратор и обновите конфигурацию базы данных (F7).Экспорт (или Export).Мы выяснили, что ошибка «Метод объекта не обнаружен» чаще всего является следствием конфликта контекстов. Чтобы ваш код работал стабильно, следуйте правилу: серверный код должен располагаться в серверном модуле, а для доступа к нему с клиента необходимо использовать флаг «Вызов сервера» и избегать дублирования этого модуля на клиенте. Помните, что грамотное разделение логики на клиентскую и серверную не только избавляет от ошибок, но и значительно повышает производительность системы, минимизируя лишние пересылки данных по сети.