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