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

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

Как работает серверный вызов в 1С

Разбираем, как работает серверный вызов в 1С: директивы компиляции, передача данных между клиентом и сервером, типичные ошибки и способы оптимизации обмена.

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

Главная причина, по которой серверные вызовы требуют внимания, — их стоимость. Один вызов занимает миллисекунды в локальной сети, но сотни вызовов подряд превращаются в заметную задержку, особенно при работе через интернет или в веб-клиенте. Поэтому грамотная разработка под управляемые формы строится на минимизации количества обращений к серверу и передаче данных пакетами.

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

Как платформа организует взаимодействие клиента и сервера

В клиент-серверной архитектуре 1С исполнение кода разделено минимум на два уровня: клиентское приложение (тонкий, толстый или веб-клиент) и сервер 1С:Предприятия. Клиент отвечает за интерфейс, ввод данных и простую логику, не требующую обращения к базе. Сервер выполняет запросы к СУБД, проведение документов, расчёты и любые операции с данными информационной базы.

Когда клиентский код вызывает серверную процедуру, платформа выполняет несколько шагов: упаковывает параметры во внутренний формат, передаёт их по сети на сервер, исполняет код в контексте серверного сеанса, упаковывает результат и возвращает его клиенту. Всё это время клиентская форма ожидает ответа, если вызов синхронный.

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

Директивы компиляции: где будет исполняться код

Место исполнения метода определяется директивой компиляции, которую разработчик ставит перед процедурой или функцией. В модулях форм и общих модулях доступны четыре основные директивы, и выбор между ними — ключевое проектное решение.

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

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

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

Не все типы 1С пересекают границу клиент–сервер. Платформа накладывает ограничения, и попытка передать неподдерживаемый тип завершится ошибкой ещё на этапе вызова. Разработчику нужно заранее понимать, что именно поедет по сети.

Тип данныхПередача клиент ↔ серверКомментарий
Примитивные типы (число, строка, дата, булево)ДаПередаются без ограничений
Ссылки на объекты базыДаНа сервере по ссылке можно получить объект
Структура, массив, соответствиеДаПри условии, что вложенные значения передаваемы
Таблица значенийОграниченноДоступна на тонком клиенте, но передача больших таблиц дорога
Объекты (ДокументОбъект и т.п.)НетОбъектная модель доступна только на сервере
Запрос, результат запроса, выборкаНетИсполняются и обрабатываются только на сервере
ДанныеФормы, реквизиты формыЧерез контекстПередаются только при вызове &НаСервере с контекстом

Практическое следствие: если на клиенте нужно показать результат сложной выборки, на сервере её преобразуют в массив структур или таблицу значений и передают уже в таком виде. Передавать на клиент сам запрос или объектную ссылку на несериализуемый объект невозможно.

Отдельный случай — временное хранилище. Большие данные (например, макет печатной формы или файл) сервер помещает во временное хранилище и возвращает клиенту только адрес. Клиент по этому адресу забирает данные отдельным обращением. Это стандартный приём для передачи объёмных результатов.

Как выполнить серверный вызов из формы: порядок действий

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

Порядок действий
  1. 1
    Определите, какие данные нужны серверному методу, и соберите их в структуру на клиенте
  2. 2
    Создайте в модуле формы серверную процедуру с директивой &НаСервереБезКонтекста, если контекст формы не нужен
  3. 3
    Вынесите тяжёлую логику в общий серверный модуль — из формы вызывайте именно его
  4. 4
    Из клиентского обработчика вызовите серверный метод, передав параметры одной структурой
  5. 5
    На клиенте обработайте результат: обновите реквизиты формы, перерисуйте таблицу, покажите сообщение
  6. 6
    Проверьте в замере производительности, что на одно действие пользователя приходится один серверный вызов
&НаКлиенте

Процедура РассчитатьСкидку(Команда)

ПараметрыРасчета = Новый Структура;

ПараметрыРасчета.Вставить("Контрагент", Объект.Контрагент);

ПараметрыРасчета.Вставить("СуммаДокумента", Объект.СуммаДокумента);

Результат = РассчитатьСкидкуНаСервере(ПараметрыРасчета);

Объект.ПроцентСкидки = Результат.ПроцентСкидки;

КонецПроцедуры

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

Функция РассчитатьСкидкуНаСервере(ПараметрыРасчета)

Возврат Обработки.РасчетСкидок.ВыполнитьРасчет(ПараметрыРасчета);

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

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

Контекстный и бесконтекстный вызов: что выбрать

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

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

&НаСервере (с контекстом)

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

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

Подходит для расчётов, запросов и проверок, результат которых возвращается значением. Дешевле и предсказуемее, но требует явной передачи всех входных данных параметрами.

Вызов общего серверного модуля

Оптимален для переиспользуемой логики. Не зависит от формы, легко тестируется, но общий модуль должен иметь флаг «Сервер» и, при вызове с клиента, — «Вызов сервера».

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

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

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

Рабочие приёмы сокращения вызовов:

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

Ограничения, права и типичные проблемы

Серверный вызов исполняется с правами текущего пользователя. Если роль не даёт доступа к объекту, серверный код получит ошибку нарушения прав так же, как и интерактивное действие. Обход — привилегированный режим (УстановитьПривилегированныйРежим) или общий модуль с флагом «Привилегированный», но применять его нужно осознанно: привилегированный код, доступный с клиента, — потенциальная дыра в безопасности.

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

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

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

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

Один-два вызова на операцию пользователя

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

Вызовы в цикле, десятки обращений на одно действие

Объём передаваемых данных
Норма

Передаются только нужные поля и строки

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

На сервер уходит вся форма с большими табличными частями

Права и безопасность
Норма

Серверные методы проверяют входные параметры и права

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

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

Компиляция в разных клиентах
Норма

Проверка конфигурации проходит для тонкого и веб-клиента

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

Ошибки компиляции модулей в веб-клиенте

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

Итог

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

Серверный вызов — это сетевое взаимодействие с сериализацией данных, поэтому вызовов должно быть мало, а данные — компактными. Используйте &НаСервереБезКонтекста и общие серверные модули, передавайте параметры структурами, выносите циклы на сервер и контролируйте права в привилегированном коде.

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

Почему с клиента не виден серверный общий модуль?

В свойствах общего модуля должен быть установлен флаг «Сервер», а для вызова с клиента — дополнительно флаг «Вызов сервера». Без второго флага модуль компилируется на сервере, но обращение к нему из клиентского кода вызовет ошибку «Метод объекта не обнаружен» или недоступность процедуры.

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

Контекстный вызов передаёт на сервер все данные формы и возвращает их обратно, поэтому при больших табличных частях разница ощутима. Бесконтекстный передаёт только явные параметры. Точный выигрыш зависит от объёма данных формы и качества сети, но на формах с сотнями строк разница заметна невооружённым глазом.

Можно ли вызвать серверную процедуру асинхронно, чтобы форма не ждала?

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

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

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

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

Нет, и это невозможно: диалоги и предупреждения доступны только на клиенте. Если по результатам серверной операции нужно спросить пользователя, серверный метод возвращает признак или текст, а клиентский код уже показывает вопрос или предупреждение и при необходимости инициирует следующий вызов.

Как найти лишние серверные вызовы в готовой форме?

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