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