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