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