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