Разработка и Конфигурация · 10 мин
Как с клиента вызвать серверную процедуру общего модуля в 1С
Как правильно вызвать серверную процедуру общего модуля из клиентского кода 1С: флаги компиляции, директива &НаСервере, вызовы в форме, типичные ошибки и ограничения.
В управляемом приложении 1С код выполняется в двух контекстах: на клиенте и на сервере. Клиентский код не имеет прямого доступа к базе данных, поэтому любые запросы, чтение справочников или запись объектов выполняются на сервере. Чтобы вызвать серверную процедуру общего модуля из клиентского кода, общий модуль должен быть правильно настроен, а вызов — оформлен с учётом контекста исполнения.
Основное требование: у общего модуля должен быть установлен флаг «Сервер», а у экспортируемой процедуры — контекст сервера. Если вызов идёт из клиентского кода формы, дополнительно потребуется флаг «Вызов сервера». Без него платформа выдаст ошибку компиляции: «Процедура или функция не определена» либо сообщение о недопустимом вызове с клиента.
Ниже разобраны настройки общего модуля, способы вызова из формы и из другого клиентского модуля, ограничения на параметры и типичные ошибки, которые встречаются при переносе логики на сервер.
Настройка общего модуля для серверного вызова
Откройте конфигуратор, найдите общий модуль в ветке «Общие → Общие модули» и откройте его свойства. Для серверного вызова с клиента критичны три флага:
- Сервер — модуль компилируется на сервере, процедуры доступны в серверном контексте;
- Вызов сервера — разрешает обращение к процедурам модуля из клиентского кода; без этого флага модуль виден только серверному коду;
- Привилегированный режим — опционально; код выполняется без проверки прав доступа, что нужно для служебных операций, но требует аккуратности.
Флаги «Клиент (управляемое приложение)» и «Клиент (обычное приложение)» для серверного модуля снимают — иначе модуль будет компилироваться в двух контекстах, а обращение к серверным объектам (запросам, менеджерам объектов) в клиентском контексте вызовет ошибку. Процедуры и функции, которые должны быть доступны извне, помечаются ключевым словом Экспорт.
Директива компиляции внутри общего модуля не пишется — контекст определяется флагами модуля. Это отличие от модулей формы, где директивы &НаСервере и &НаКлиенте обязательны.
Вызов из клиентского модуля и из формы
Если вызов выполняется из клиентского общего модуля или клиентской процедуры формы, синтаксис одинаковый — обращение по имени модуля:
&НаКлиенте
Процедура ПриНажатииКнопки(Команда)
Результат = ПолучитьДанныеНаСервере(Номенклатура);
ПоказатьОповещениеПользователя("Получено: " + Результат);
КонецПроцедуры
&НаСервере
Функция ПолучитьДанныеНаСервере(Ссылка)
Возврат ОбщегоНазначенияСервер.ПолучитьОстаток(Ссылка);
КонецФункции
Здесь ОбщегоНазначенияСервер — общий модуль с флагами «Сервер» и «Вызов сервера». Промежуточная серверная процедура формы с директивой &НаСервере нужна, потому что из клиентской процедуры формы нельзя напрямую обращаться к серверному контексту формы, а вот к серверному общему модулю — можно и напрямую:
&НаКлиенте
Процедура ПриНажатииКнопки(Команда)
Остаток = ОбщегоНазначенияСервер.ПолучитьОстаток(Номенклатура);
КонецПроцедуры
Такой прямой вызов допустим и работает, но через серверную процедуру формы удобнее, когда результат нужно поместить в реквизиты формы или данные объекта — серверный контекст формы даёт доступ к Объект, реквизитам и методам вроде РеквизитФормыВЗначение().
- 1Создайте общий модуль, установите флаги «Сервер» и «Вызов сервера», снимите клиентские флаги.
- 2Добавьте экспортную функцию или процедуру с нужной логикой (запрос, чтение данных).
- 3В клиентской процедуре формы добавьте серверную процедуру с директивой &НаСервере, вызывающую общий модуль.
- 4Вызовите серверную процедуру формы из клиентского кода.
- 5Обновите конфигурацию базы данных (F7) и проверьте вызов в режиме предприятия.
Ограничения на параметры и возвращаемые значения
При вызове с клиента на сервер данные сериализуются и передаются между процессами, поэтому не все типы можно передавать. Ссылки на объекты, примитивные типы, структуры, массивы и таблицы значений передаются свободно. Нельзя передавать объекты, существующие только в одном контексте: ДанныеФормы, элементы формы, объекты типа СправочникОбъект в открытом виде, результаты запроса.
Если нужно передать на сервер данные формы, используйте встроенные методы управляемой формы: РеквизитФормыВЗначение("Объект") на сервере или передавайте отдельные значения реквизитов параметрами. Обратно с сервера возвращайте сериализуемые типы — структуру с результатами, а не объект базы данных.
Каждый серверный вызов — это сетевой обмен в клиент-серверном режиме. Десять мелких вызовов в цикле работают заметно медленнее одного вызова, который получает массив параметров и возвращает массив результатов. Проектируйте серверные процедуры «пакетно»: один вызов — одна законченная операция.
Привилегированный режим и безопасность
Флаг «Привилегированный режим» у общего модуля отключает проверку прав доступа для всего кода модуля. Это удобно для служебных операций — например, запись системных настроек от имени пользователя без прав на соответствующий регистр. Но такой модуль становится точкой обхода ограничений: любой пользователь, способный вызвать процедуру, фактически получает повышенные права внутри неё.
Безопасная практика — не помещать в привилегированный модуль процедуры с «широким» функционалом, а вызывать из обычного серверного кода УстановитьПривилегированныйРежим(Истина) точечно, только на время нужной операции. Так границы повышения прав явно видны в коде и их проще контролировать при аудите.
Проверка результата и отладка
После обновления конфигурации базы данных проверьте вызов в режиме предприятия. Признак корректной настройки — процедура выполняется без ошибок компиляции, а результат возвращается на клиент. Если платформа сообщает «Процедура или функция с указанным именем не определена», проверьте три вещи: флаг «Вызов сервера», слово Экспорт и точное имя модуля.
Для отладки серверного кода включите в конфигураторе отладку по протоколу HTTP или TCP (в зависимости от режима работы) и убедитесь, что в настройках отладки разрешена отладка серверных процедур — иначе точки останова внутри общего модуля просто не сработают. В файловом режиме серверный код отлаживается в том же сеансе, в клиент-серверном — нужен запуск отладки на сервере 1С.
Как проверить результат
Процедура выполняется, результат возвращается без ошибок
Ошибка «Процедура не определена» — проверить флаги модуля и Экспорт
Ссылки, примитивы, структуры передаются корректно
Ошибка сериализации — в параметрах объект, живущий только в одном контексте
Один серверный вызов на одну операцию пользователя
Форма «подвисает» — серверные вызовы в цикле на клиенте
Альтернативы прямому вызову
Не всегда нужен именно серверный общий модуль. Если логика используется только в одной форме, достаточно серверной процедуры самой формы с директивой &НаСервере — это проще и не требует отдельного модуля. Если процедура не возвращает результат и может выполняться асинхронно, рассмотрите фоновые задания через ФоновыеЗадания.Выполнить() — длительная операция не будет блокировать интерфейс пользователя.
Для типовых конфигураций вместо создания своих модулей часто используют готовые модули библиотеки стандартных подсистем (ОбщегоНазначения, ОбщегоНазначенияКлиентСервер). Модуль ОбщегоНазначенияКлиентСервер компилируется в обоих контекстах и подходит для функций, не обращающихся к базе данных.
Сравнение вариантов
Универсально, код переиспользуется из любых форм; требует аккуратности с правами и сериализацией параметров.
Проще всего для логики одной формы, есть доступ к реквизитам формы; не переиспользуется в других объектах.
Подходит для длительных операций без блокировки интерфейса; сложнее вернуть результат и показать прогресс.
Для вспомогательных функций без обращения к базе; не подходит для запросов и записи данных.
Частые вопросы
Можно ли вызвать серверную процедуру с клиента без флага «Вызов сервера»?
Нет. Без этого флага модуль компилируется только в серверном контексте, и клиентский код его не видит. Попытка вызова приведёт к ошибке «Процедура или функция не определена». Флаг «Вызов сервера» специально создан для таких сценариев.
Чем отличается модуль с флагом «Сервер» от модуля «КлиентСервер»?
Модуль «КлиентСервер» компилируется и на клиенте, и на сервере — в нём нельзя использовать запросы, менеджеры объектов и другие серверные механизмы. Серверный модуль компилируется только на сервере и имеет полный доступ к базе данных, но доступен клиенту только при включённом «Вызове сервера».
Почему возникает ошибка при передаче параметра на сервер?
Скорее всего, передаётся тип, который нельзя сериализовать между контекстами: объект базы данных (СправочникОбъект, ДокументОбъект), ДанныеФормы, результат запроса. Замените параметр на ссылку, примитивное значение или структуру с простыми типами.
Нужно ли писать &НаСервере внутри общего модуля?
Нет. Директивы компиляции используются только в модулях форм и команд. Контекст общего модуля целиком определяется его флагами в свойствах: «Сервер», «Клиент», «Внешнее соединение» и другие.
Как вернуть с сервера сразу несколько значений?
Соберите результат в структуру или массив и верните их из функции одним значением. Например, функция формирует структуру с полями «Остаток», «Цена», «Резерв» и возвращает её — клиент получает все данные за один серверный вызов.
Что делать, если серверный вызов выполняется слишком долго?
Сначала оптимизируйте сам запрос или алгоритм на сервере. Если операция объективно длительная (загрузка файла, массовая обработка), перенесите её в фоновое задание, а на клиенте покажите индикатор и периодически проверяйте состояние задания.
Что важно запомнить
Серверная процедура общего модуля вызывается с клиента по имени модуля при трёх условиях: флаги «Сервер» и «Вызов сервера» установлены, процедура экспортная, параметры сериализуемы. Группируйте серверные вызовы, избегайте их в циклах и точечно контролируйте привилегированный режим.