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

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

1С: как запустить процедуру на сервере

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

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

Платформа предлагает несколько механизмов: директивы компиляции &НаСервере, вызов серверных процедур из клиентского кода, серверные общие модули и фоновые задания через ФоновыеЗадания.Выполнить. Выбор зависит от того, откуда инициируется вызов, нужно ли возвращать результат и допустимо ли блокировать интерфейс пользователя.

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

Где физически размещается серверный код

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

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

Запуск процедуры в модуле формы с директивой &НаСервере

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

&НаКлиенте

Процедура ЗаполнитьЦены(Команда)

ЗаполнитьЦеныНаСервере();

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

&НаСервере

Процедура ЗаполнитьЦеныНаСервере()

Запрос = Новый Запрос("ВЫБРАТЬ ...");

// работа с данными

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

Клиентская процедура просто вызывает серверную по имени — платформа сама выполняет серверный вызов. Если серверной процедуре не нужен контекст формы (реквизиты, данные формы), объявляйте её с директивой &НаСервереБезКонтекста — это ускоряет вызов, так как на сервер не передаётся вся форма.

Вызов через серверный общий модуль

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

// Общий модуль РаботаСЦенами, флаги: Сервер, Вызов сервера

Функция ПолучитьЦену(Номенклатура, Дата) Экспорт

Запрос = Новый Запрос;

// ...

Возврат Цена;

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

Из клиентского кода вызов выглядит обычно: Цена = РаботаСЦенами.ПолучитьЦену(Товар, ТекущаяДата());. Платформа автоматически выполняет обращение к серверу. Учитывайте, что каждый такой вызов — это сетевой обмен, поэтому в циклах клиентского кода множественные вызовы сервера сильно замедляют работу. Правильнее собрать данные в массив или структуру и передать их одним вызовом.

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

Фоновое выполнение на сервере через фоновые задания

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

&НаСервере

Процедура ЗапуститьОбработкуНаСервере()

ПараметрыПроцедуры = Новый Массив;

ПараметрыПроцедуры.Добавить(Организация);

ФоновыеЗадания.Выполнить("ОбработкаДанных.ВыполнитьЗагрузку",

ПараметрыПроцедуры, , "Загрузка данных");

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

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

Порядок запуска фонового задания
  1. 1
    Создайте общий серверный модуль с экспортной процедурой, принимающей параметры
  2. 2
    В модуле формы добавьте серверную процедуру, вызывающую ФоновыеЗадания.Выполнить с именем процедуры строкой
  3. 3
    Передайте входные данные массивом параметров — контекст формы в фоне недоступен
  4. 4
    Сохраните результат в базу или временное хранилище
  5. 5
    На клиенте проверьте состояние задания или обработайте оповещение о завершении

Запуск процедуры на сервере вне клиентского сеанса

Иногда процедуру нужно запустить вообще без интерактивного пользователя. Для этого есть три штатных механизма.

Регламентные задания

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

Внешнее соединение и COM

Через COM-коннектор (V83.COMConnector) внешнее приложение подключается к базе и вызывает методы серверного контекста. Этот способ подходит для интеграций, но требует наличия COM-компонента и лицензий.

HTTP-сервисы

Публикация HTTP-сервиса на веб-сервере позволяет запускать серверный код по HTTP-запросу. Код в модуле HTTP-сервиса всегда выполняется на сервере. Это предпочтительный способ для интеграций с внешними системами.

Сравнение способов запуска

Директива &НаСервере в форме

Подходит для логики конкретной формы; простой вызов, но код не переиспользуется

Серверный общий модуль

Универсальный вариант для общей логики; требует флага «Вызов сервера» для доступа с клиента

Фоновое задание

Для длительных операций без блокировки интерфейса; сложнее передать результат

Регламентное задание

Для выполнения по расписанию без пользователя; в файловой базе работает иначе, чем в клиент-серверной

Проверка, что код выполнился на сервере

Убедиться в месте выполнения можно через функцию ИнформацияОбОкружении — нет, точнее через вычисление выражения в отладчике: тип Вычислить("ПолучитьСерверныеДанные") не нужен. Практичные способы такие. В отладчике в настройках (Параметры отладки) включите «Отладка на сервере» — если точка останова в серверной процедуре не срабатывает, чаще всего отладка сервера не настроена или служба агента сервера запущена без ключа -debug.

Программно можно проверить окружение через структуру, возвращаемую функцией ВычислитьВыражение — нет, надёжный метод: в серверном коде вызвать ИмяКомпьютера() и сравнить с именем машины пользователя, либо записать в журнал регистрации сообщение с указанием сеанса. Также полезно помнить: в клиент-серверной базе файловые операции в серверном коде обращаются к дискам сервера, а не клиентского компьютера — это частый источник путаницы при отладке.

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

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

Срабатывание точки останова в серверной процедуре
Норма

Отладчик останавливается, видны серверные переменные

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

Точка не срабатывает — не включена серверная отладка или код не вызывается

Журнал регистрации после выполнения
Норма

Есть запись от серверного сеанса с ожидаемым сообщением

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

Записи нет — процедура не вызвана или завершилась с ошибкой раньше

Фоновое задание в консоли заданий
Норма

Состояние «Завершено» без ошибок

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

Состояние «Ошибка» — смотрите текст в свойствах задания

Ограничения и безопасность

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

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

Часто задаваемые вопросы

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

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

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

Да, через объект СообщениеПользователю — сообщения накапливаются на сервере и выводятся в клиентском сеансе после завершения вызова. А вот модальные диалоги (Вопрос, Предупреждение) на сервере недоступны, так как там нет пользовательского интерфейса.

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

Процедура &НаСервере имеет доступ к данным и реквизитам формы, но при вызове вся форма сериализуется и передаётся на сервер. Вариант «БезКонтекста» быстрее и безопаснее для производительности, но работает только с переданными параметрами.

Как передать результат из фонового задания обратно в форму?

Штатный путь — поместить результат во временное хранилище (ПоместитьВоВременноеХранилище) и вернуть адрес хранилища, либо записать данные в базу и перечитать их. В конфигурациях на БСП используйте подсистему «Длительные операции», которая автоматизирует этот обмен.

Выполняется ли серверный код иначе в файловой базе?

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

Итог

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

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