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