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

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

Вызов сервера в 1С: что это и как правильно использовать

Что означает вызов сервера в 1С, как работают директивы &НаСервере и &НаКлиенте, чем отличается серверный вызов от клиентского и как избежать лишних обращений к серверу.

Вызов сервера в 1С — это обращение клиентского приложения (тонкого, толстого или веб-клиента) к серверу «1С:Предприятия» для выполнения кода, который нельзя или невыгодно выполнять на стороне клиента. В файловом режиме роль сервера выполняет само клиентское приложение, но логика разделения сохраняется: платформа всё равно различает контекст клиента и контекст сервера.

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

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

Что такое вызов сервера и зачем он нужен

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

Когда пользователь, например, нажимает кнопку «Заполнить» в документе, обработчик нажатия сначала выполняется на клиенте. Если для заполнения нужно прочитать остатки или цены из базы, клиент не может сделать это напрямую — он вызывает серверную процедуру, та обращается к СУБД и возвращает результат. Этот переход «клиент → сервер → клиент» и есть вызов сервера.

Разделение существует не только ради производительности, но и ради безопасности: вся логика доступа к данным сосредоточена на сервере, а клиент получает только то, что ему разрешено видеть.

Директивы компиляции: как платформа понимает, где выполнять код

В модулях управляемых форм и общих модулях место выполнения кода задаётся директивами компиляции. Именно они определяют, будет ли процедура доступна на клиенте, на сервере или в обоих контекстах.

  • &НаКлиенте — код выполняется только на клиенте. Здесь доступны элементы формы, диалоги, оповещения, но недоступны запросы и объекты базы данных.
  • &НаСервере — код выполняется только на сервере. Доступны запросы, объекты, привилегированный режим, но недоступен интерактивный интерфейс.
  • &НаСервереБезКонтекста — серверный код без доступа к данным формы. Выполняется быстрее, так как не требует передачи состояния формы между клиентом и сервером.
  • &НаКлиентеНаСервереБезКонтекста — код, который может выполняться в обоих контекстах; используется для универсальных алгоритмов без обращения к базе и форме.

Если процедура помечена &НаСервере, а её вызывают из клиентской процедуры — происходит серверный вызов. Если директива не указана в модуле формы, платформа по умолчанию считает код серверным.

Чем серверный вызов с контекстом отличается от вызова без контекста

Это ключевое различие для производительности форм. При вызове &НаСервере платформа передаёт на сервер всё состояние формы: реквизиты, табличные части, данные объекта. При больших табличных частях это заметный объём трафика на каждый вызов.

При вызове &НаСервереБезКонтекста состояние формы не передаётся — на сервер уходят только явно указанные параметры. Такой вызов дешевле, но внутри процедуры недоступны реквизиты формы и объект: всё нужное придётся передавать параметрами и возвращать результатом.

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

&НаСервере

Подходит, когда нужно читать и менять данные формы и объекта. Ограничение: передача всего контекста формы, дороже при больших табличных частях.

&НаСервереБезКонтекста

Подходит для запросов, расчётов и выборок, не привязанных к форме. Ограничение: нет доступа к реквизитам формы, данные передаются только через параметры.

&НаКлиенте

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

Когда вызов сервера обязателен

Есть операции, которые физически невозможно выполнить на клиенте. Попытка обойтись без серверного вызова в этих случаях закончится ошибкой компиляции или выполнения.

  • выполнение запроса к базе данных (объект «Запрос»);
  • создание, чтение и запись объектов: справочников, документов, записей регистров;
  • обращение к менеджерам объектов (Справочники.Номенклатура, Документы.РеализацияТоваровУслуг);
  • выполнение кода в привилегированном режиме (УстановитьПривилегированныйРежим);
  • вызов процедур серверных общих модулей;
  • работа с СКД и формирование отчётов на сервере.

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

Как сократить количество серверных вызовов

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

Практические приёмы оптимизации:

  1. Передавайте на сервер всю таблицу или массив данных одним параметром вместо вызова процедуры для каждой строки.
  2. Кэшируйте редко меняющиеся данные (настройки, константы) в переменных модуля формы на клиенте, а не запрашивайте их повторно.
  3. Используйте общие модули с флагом «Вызов сервера» для серверных функций — тогда их можно вызывать из клиентского кода напрямую.
  4. Выносите вычисления, не требующие данных базы, на клиент: проверки заполнения, арифметику, форматирование.
  5. Для длительных операций рассмотрите фоновые задания (ДлительныеОперации), чтобы не блокировать интерфейс.
Порядок действий при оптимизации формы
  1. 1
    Найдите обработчики, которые вызывают сервер в цикле или при каждом изменении поля
  2. 2
    Соберите данные в массив или структуру на клиенте
  3. 3
    Перенесите обработку в одну серверную процедуру без контекста
  4. 4
    Верните результат одним значением и обновите форму
  5. 5
    Проверьте время выполнения до и после — замерьте через ЗамерПроизводительности или отладчик

Типичные ошибки при работе с серверными вызовами

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

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

Типичные ошибки
01
Вызов сервера в цикле по строкам таблицы — форма зависает при большом объёме данных
02
Попытка вернуть на клиент объект базы (СправочникОбъект) — ошибка сериализации, нужно возвращать ссылку или структуру
03
Забытый флаг «Вызов сервера» у общего модуля — клиентский код не видит его процедуры
04
Использование &НаСервере там, где достаточно &НаСервереБезКонтекста — лишняя передача всего контекста формы
05
Выполнение на клиенте запроса «в лоб» через сервер при каждом изменении поля без задержки или кэширования
Быстрый способ найти лишние вызовы — включить в конфигураторе замер производительности и посмотреть, сколько раз и какие серверные процедуры вызываются при одном действии пользователя. Часто оказывается, что простое изменение поля порождает несколько скрытых вызовов через цепочки обработчиков.
ПЗ
Практическое замечание

Как проверить, что вызовы организованы правильно

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

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

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

Реакция формы на ввод данных
Норма

Изменение поля обрабатывается мгновенно, без задержек

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

Видимая пауза при каждом изменении — вероятен серверный вызов в обработчике

Количество вызовов в замере производительности
Норма

Одно действие — один-два серверных вызова

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

Десятки вызовов одной процедуры — признак вызова в цикле

Типы передаваемых данных
Норма

Передаются ссылки, структуры, таблицы значений

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

Попытка передать объект базы или запрос — ошибка сериализации

Частые вопросы о вызове сервера в 1С

Почему возникает ошибка «Процедура или функция не определена» при вызове сервера?

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

Что лучше: &НаСервере или &НаСервереБезКонтекста?

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

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

Напрямую — нет. Сервер не имеет доступа к интерфейсу пользователя. Результат серверной процедуры возвращается в клиентский код, который уже решает, что показать пользователю. Для длительных операций используются фоновые задания с оповещением клиента о завершении.

Работает ли вызов сервера в файловой базе?

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

Как передать таблицу значений с клиента на сервер?

Таблица значений сериализуется платформой, поэтому её можно передать параметром в серверную процедуру. В модуле формы удобнее использовать реквизит формы типа «ТаблицаЗначений» и работать с ним в серверном контексте формы.

Итог

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

Вызов сервера — это выполнение кода на сервере по запросу клиента, необходимое для работы с базой данных. Каждый вызов стоит ресурсов: объединяйте их, выбирайте вариант без контекста, где возможно, и не передавайте между контекстами несериализуемые объекты.