К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как из клиентского общего модуля вызвать серверную функцию в 1С

Как вызвать серверную функцию из клиентского общего модуля в 1С: флаги модуля, вызов сервера, передача параметров, типичные ошибки и проверка результата.

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

Ключевое условие: серверный общий модуль должен иметь установленный флаг «Вызов сервера», а вызываемая функция — ключевое слово «Экспорт». Если хотя бы одно из условий не выполнено, на клиенте возникнет ошибка «Процедура или функция с указанным именем не определена» либо модуль просто будет недоступен для вызова.

Ниже разобраны настройка модулей, синтаксис вызова, передача параметров, особенности тонкого и веб-клиента, а также типичные ошибки, из-за которых вызов «не работает», хотя код написан правильно.

Какие флаги должны быть у серверного общего модуля

В конфигураторе откройте свойства общего модуля (правый клик по модулю → «Свойства»). Для модуля, функции которого вызываются с клиента, нужны следующие установки:

  • Сервер — установлен. Модуль компилируется в серверном контексте.
  • Вызов сервера — установлен. Именно этот флаг разрешает обращение к экспортным методам модуля из клиентского кода.
  • Клиент (обычное приложение) и Клиент (управляемое приложение) — сняты. Если их оставить, модуль скомпилируется и на клиенте, что может привести к ошибкам компиляции при использовании серверных типов (запросов, менеджеров объектов).
  • Привилегированный режим — по необходимости. Устанавливайте, только если функция должна обращаться к данным, на которые у пользователя нет прав. Это важное решение с точки зрения безопасности.

Клиентский общий модуль, из которого выполняется вызов, должен иметь флаг «Клиент (управляемое приложение)» (и «Клиент (обычное приложение)», если поддерживается обычное приложение). Флаг «Сервер» у него снимается, если модуль не нужен в серверном контексте.

Минимальный пример вызова

Создайте общий модуль, например РаботаСДаннымиСервер, с флагами «Сервер» и «Вызов сервера». В нём объявите экспортную функцию:

Функция ПолучитьЦенуНоменклатуры(Номенклатура) Экспорт

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Цены.Цена КАК Цена

|ИЗ

| РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, Номенклатура = &Номенклатура) КАК Цены";

Запрос.УстановитьПараметр("Номенклатура", Номенклатура);

РезультатЗапроса = Запрос.Выполнить();

Если РезультатЗапроса.Пустой() Тогда

Возврат 0;

КонецЕсли;

Выборка = РезультатЗапроса.Выбрать();

Выборка.Следующий();

Возврат Выборка.Цена;

КонецФункции

В клиентском общем модуле вызов выглядит как обычное обращение к функции по имени модуля:

Функция ПолучитьЦенуДляФормы(Номенклатура) Экспорт

Возврат РаботаСДаннымиСервер.ПолучитьЦенуНоменклатуры(Номенклатура);

КонецФункции

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

Какие параметры можно передавать между клиентом и сервером

Между клиентом и сервером данные передаются сериализацией, поэтому не любой тип допустим. Безопасно передавать примитивные типы (число, строка, дата, булево), ссылки на объекты базы данных, структуры, массивы, соответствия — при условии, что вложенные значения тоже сериализуемы.

Нельзя передавать объекты, существующие только в одном контексте: наборы записей, объекты типа «СправочникОбъект», построители запросов, элементы форм. Если нужно изменить объект на сервере, передайте его ссылку, а на сервере получите объект методом ПолучитьОбъект().

Особый случай — объекты СКД и табличные документы: они сериализуются, но передача больших объёмов данных между клиентом и сервером замедляет работу. Если функция возвращает, например, таблицу значений, учитывайте, что на тонком и веб-клиенте тип «ТаблицаЗначений» недоступен напрямую — возвращайте массив структур.

Типичные ошибки
01
Передача объекта (СправочникОбъект) вместо ссылки — ошибка сериализации или непредсказуемое поведение; передавайте ссылку и получайте объект на сервере
02
Возврат ТаблицаЗначений на тонкий клиент — тип недоступен в клиентском контексте; возвращайте массив структур
03
Забытое слово «Экспорт» у функции — клиент получает ошибку «метод не обнаружен», хотя модуль настроен верно
04
Снятый флаг «Вызов сервера» — модуль компилируется, но клиентский вызов невозможен

Особенности тонкого и веб-клиента

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

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

Если серверная операция длительная (загрузка данных, массовая обработка), синхронный вызов заблокирует интерфейс пользователя. В таких случаях вместо прямого вызова серверной функции используют фоновые задания с длительными операциями БСП или механизм ДлительныеОперации, а клиент периодически проверяет готовность результата.

Проверка результата и отладка вызова

После настройки модулей проверьте вызов по шагам. Сначала убедитесь, что конфигурация обновлена без ошибок компиляции: синтаксическая ошибка в серверном модуле может проявиться именно как недоступность метода на клиенте. Затем поставьте точку останова внутри серверной функции и запустите отладку — отладчик должен остановиться на серверном коде при вызове с клиента.

Если точка останова не срабатывает, проверьте: включён ли в отладке серверный контекст (в конфигураторе есть отдельная настройка отладки по протоколу HTTP/TCP и предметов отладки «Сервер»), обновлена ли база после изменения флагов модуля, не вызывается ли на самом деле одноимённая функция из другого модуля.

Контрольные точки

Как проверить результат

Вызов функции с клиента
Норма

Функция выполняется, возвращается ожидаемое значение

Тревожный признак

Ошибка «Процедура или функция с указанным именем не определена» — проверьте флаг «Вызов сервера» и слово «Экспорт»

Передача параметров
Норма

На сервер приходят те же значения, что отправлены с клиента

Тревожный признак

Ошибка преобразования данных — в параметрах несериализуемый тип

Права доступа
Норма

Функция возвращает данные в рамках прав пользователя

Тревожный признак

Пустой результат или ошибка доступа — проверьте роли либо осознанно включите привилегированный режим

Альтернативы: когда прямой вызов не лучший вариант

Прямой вызов серверного общего модуля — не единственный способ выполнить серверную логику с клиента. Если код относится к конкретной форме, логичнее разместить серверную функцию в модуле этой формы с директивой &НаСервере или &НаСервереБезКонтекста и вызывать её из клиентской процедуры той же формы. Вариант «без контекста» предпочтительнее: он не тянет за собой сериализацию данных формы.

Для логики, привязанной к объекту (например, специфическое чтение данных документа), подходит модуль менеджера объекта: Документы.РеализацияТоваров.ПолучитьДанные(Ссылка). Менеджеры всегда исполняются на сервере, и отдельный серверный общий модуль не нужен.

Сравнение вариантов

Серверный общий модуль с «Вызов сервера»

Универсальный вариант для переиспользуемой логики; требует аккуратной настройки флагов

&НаСервереБезКонтекста в модуле формы

Подходит, если логика нужна только одной форме; не работает из общих клиентских модулей

Модуль менеджера объекта

Правильное место для логики конкретного вида документов или справочников; вызывается через имя менеджера

Фоновое задание / длительная операция

Для тяжёлых операций, чтобы не блокировать интерфейс; сложнее в реализации

Частые вопросы

Почему клиент пишет «Процедура или функция не определена», хотя функция есть?

Чаще всего не установлен флаг «Вызов сервера» у серверного модуля или пропущено слово «Экспорт» у функции. Реже — конфигурация базы данных не обновлена после изменений, либо есть синтаксическая ошибка в самом серверном модуле, из-за которой он не компилируется.

Можно ли вызвать серверную функцию асинхронно?

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

Работает ли вызов сервера из модуля команды?

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

Что вернуть с сервера вместо таблицы значений для тонкого клиента?

Обычно возвращают массив структур: каждая строка таблицы преобразуется в структуру с одинаковыми ключами. На клиенте массив обходится циклом. Это сериализуемый и безопасный для всех видов клиентов вариант.

Нужно ли ставить флаг «Клиент» у серверного модуля?

Нет. Если модуль предназначен только для серверных вызовов, флаги клиентских контекстов следует снять — иначе модуль будет компилироваться и на клиенте, а серверные типы (запросы, менеджеры объектов) вызовут ошибки компиляции в клиентском контексте.

Безопасно ли вызывать серверные функции с клиента?

Сам механизм безопасен, но разработчик отвечает за проверку прав и входных данных: серверная функция, доступная с клиента, потенциально доступна любому пользователю. Валидируйте параметры на сервере и не используйте привилегированный режим без необходимости.

Итог

Что важно запомнить

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