Почему в тонком клиенте 1С возникает ошибка «Метод объекта не обнаружен» при вызове процедуры общего модуля?

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

При разработке и кастомизации конфигураций на платформе «1С:Предприятие 8.3» разработчики часто сталкиваются с ситуацией, когда код, успешно прошедший тесты в толстом клиенте или в файловом режиме, внезапно выдает ошибку Метод объекта не обнаружен при переходе в тонкий клиент. Особенно часто это происходит при попытке вызвать экспортную процедуру или функцию из одного общего модуля в другом.

В этой статье мы подробно разберем, почему возникает эта ошибка, как работает механизм компиляции общих модулей в системе 1С, и рассмотрим правильные архитектурные решения для исправления данной проблемы.

Анализ исходной ситуации

Рассмотрим конкретный сценарий. Из клиентского общего модуля УправлениеПечатьюУТКлиент (компилируется на клиенте) вызывается экспортная процедура ПараметрБезУслуг, расположенная в общем модуле ДоговораДействия (который должен выполняться на сервере). Код вызова выглядит следующим образом:

ДоговораДействия.ПараметрБезУслуг(ОписаниеКоманды.Идентификатор);

В толстом клиенте данный вызов отрабатывает штатно, но в тонком клиенте система выдает ошибку: Метод объекта не обнаружен (ПараметрБезУслуг). Проанализируем, какие механизмы платформы приводят к такому поведению.

Причина 1: Механизм двойной компиляции и «Правило ближнего вызова»

Если у общего модуля (в нашем примере — ДоговораДействия) одновременно установлены флаги свойств «Клиент (управляемое приложение)» и «Сервер», платформа 1С компилирует два независимых экземпляра этого модуля:

  1. Клиентский экземпляр модуля — компилируется локально на компьютере пользователя внутри процесса тонкого клиента.
  2. Серверный экземпляр модуля — компилируется на стороне сервера «1С:Предприятия».

Когда вызов метода происходит из клиентского контекста (из модуля УправлениеПечатьюУТКлиент), платформа руководствуется так называемым «правилом ближнего вызова» (приоритетом локального контекста). Видя, что у вызываемого модуля ДоговораДействия установлен флаг «Клиент», платформа обращается к его локальной клиентской копии на компьютере пользователя, даже не пытаясь отправить запрос на сервер.

Если при этом тело процедуры ПараметрБезУслуг внутри модуля ограничено инструкциями препроцессора для сервера, то на клиенте эта процедура просто отсутствует:


#Если Сервер Тогда
Процедура ПараметрБезУслуг(Идентификатор) Экспорт
    // Данный код физически не компилируется на клиенте
КонецПроцедуры
#КонецЕсли

В результате клиентский экземпляр модуля компилируется без этого метода, что и приводит к ошибке Метод объекта не обнаружен.

Причина 2: Использование директив компиляции вместо инструкций препроцессора

Иногда разработчики ошибочно используют директивы компиляции (такие как &НаСервере) внутри общих модулей. Важно помнить следующее правило: директивы компиляции со знаком амперсанда (&) предназначены для модулей форм и команд, а в общих модулях они не работают или ведут себя непредсказуемо. Для управления компиляцией в общих модулях должны использоваться исключительно инструкции препроцессора, начинающиеся со знака решетки (#Если... #КонецЕсли).

Причина 3: Почему в Толстом клиенте всё работало?

В толстом клиенте (особенно при работе в файловом режиме базы данных) границы между клиентским и серверным окружением практически стёрты. Весь код выполняется в рамках одного общего процесса на локальном компьютере. Платформа маскирует ошибки контекстной видимости, позволяя клиентскому коду напрямую «дотягиваться» до серверных методов без явного вызова сервера. При переходе в реальную клиент-серверную архитектуру и тонкий клиент эти ошибки проектирования мгновенно проявляются.

Решение проблемы по шагам

Для устранения ошибки нам необходимо скорректировать настройки свойств общего модуля и структуру вызовов. Рассмотрим два основных способа решения.

Способ 1. Настройка свойств модуля через «Вызов сервера» (Быстрое исправление)

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

  1. Откройте свойства общего модуля ДоговораДействия.
  2. Снимите флаг Клиент (управляемое приложение).
  3. Установите флаг Сервер (если он не был установлен).
  4. Установите флаг Вызов сервера (Server Call). Это критически важно: именно данный флаг разрешает тонкому клиенту выполнять удаленный вызов серверных процедур этого модуля.
  5. Убедитесь, что вызываемая процедура определена с ключевым словом Экспорт и не скрыта под инструкциями препроцессора, исключающими компиляцию на сервере.

При такой настройке платформа поймет, что локальной клиентской копии модуля ДоговораДействия не существует, и автоматически перенаправит вызов ДоговораДействия.ПараметрБезУслуг(...) на сервер 1С.

Способ 2. Разделение модулей по ролям согласно стандартам разработки 1С (Рекомендуемый вариант)

Фирма «1С» в своих стандартах разработки (1С:ИТС) крайне не рекомендует смешивать клиентский и серверный контексты в одном общем модуле. Идеальным решением является разделение функционала на несколько специализированных модулей:

Рассмотрим пример правильной организации вызова через транзитный модуль:

В модуле ДоговораДействияВызовСервера (свойства: Сервер = Истина, Вызов сервера = Истина):


Процедура ПараметрБезУслуг(Идентификатор) Экспорт
    // Перенаправляем вызов в основной серверный модуль
    ДоговораДействияСервер.ПараметрБезУслуг(Идентификатор);
КонецПроцедуры

В модуле ДоговораДействияСервер (свойства: Сервер = Истина, Вызов сервера = Ложь):


Процедура ПараметрБезУслуг(Идентификатор) Экспорт
    // Непосредственное выполнение бизнес-логики на сервере
    // Здесь выполняются запросы к базе данных, работа со справочниками и т.д.
КонецПроцедуры

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

Очистка кэша после изменений

После изменения свойств общих модулей в конфигураторе и обновления конфигурации базы данных тонкий клиент может продолжать выдавать старую ошибку. Это связано с тем, что платформа агрессивно кэширует метаданные (включая структуру и доступность общих модулей) на стороне пользователя.

Для гарантированного применения изменений выполните одно из следующих действий:

  1. Запустите сеанс «1С:Предприятия» с параметром командной строки /ClearCache.
  2. Очистите каталог кэша локального пользователя вручную (папки %userprofile%\AppData\Local\1C\1cv8 и %userprofile%\AppData\Roaming\1C\1cv8).
  3. Удалите и заново добавьте информационную базу в списке запуска 1С (при этом GUID базы изменится, и кэш будет создан заново).
← На главную