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

В этой статье мы разберём 5 основных способов вызова серверных процедур из клиента, их особенности, ограничения и типичные ошибки. Вы узнаете, когда лучше использовать ПрямойВызовСервера(), а когда — фоновые задания или HTTP-сервисы, как избежать блокировки интерфейса и почему некоторые методы работают только в управляемых формах. Материал актуален для платформы 1С:Предприятие 8.3 (включая последние релизы) и подходит для конфигураций на основе БСП (Библиотека Стандартных Подсистем).

1. Прямой вызов сервера (DirectCall): простейший, но не всегда безопасный способ

Метод ПрямойВызовСервера() — самый очевидный способ выполнить серверную процедуру из клиента. Он подходит для простых операций, когда нужно быстро получить результат без сложной логики. Однако у этого подхода есть критические ограничения:

  • 🔴 Блокирует клиентский интерфейс до завершения выполнения на сервере.
  • 🔴 Не работает в тонком клиенте и веб-клиенте без дополнительных настроек.
  • 🟢 Поддерживает передачу параметров и возвращаемого значения.
  • 🟢 Прост в реализации — не требует сложной конфигурации.

Пример кода для вызова серверной процедуры ОбновитьЦеныНоменклатуры():

Процедура ОбновитьЦеныНаКлиенте()

Результат = ПрямойВызовСервера("ОбновитьЦеныНоменклатуры", Параметр1, Параметр2);

Сообщить(Результат);

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

&НаСервере

Функция ОбновитьЦеныНоменклатуры(Параметр1, Параметр2)

// Логика обновления цен

Возврат "Цены обновлены";

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

⚠️ Внимание: В управляемых формах прямой вызов сервера через ПрямойВызовСервера() может привести к ошибке "Операция не разрешена в данном контексте" если процедура не помечена директивой &НаСервере или вызывается из неверного контекста (например, из модуля формы, где серверные процедуры не доступны).
📊 Какой клиент 1С вы используете чаще всего?
Толстый клиент
Тонкий клиент
Веб-клиент
Мобильное приложение

2. Использование фоновых заданий: асинхронный вызов без блокировки интерфейса

Если серверная процедура выполняет длительные операции (например, обработку больших массивов данных или интеграцию с внешними системами), фоновые задания становятся оптимальным решением. Они позволяют:

  • ⚡ Выполнять код на сервере без блокировки клиентского интерфейса.
  • 📊 Отслеживать прогресс выполнения через механизм Оповещение.
  • 🔄 Повторно запускать задание при сбоях (с настройкой количества попыток).
  • 🚫 Ограничены по времени выполнения (по умолчанию — 60 минут).

Пример создания фонового задания для экспорта данных в Excel:

Процедура ЭкспортироватьДанныеВExcelНаКлиенте()

ПараметрыЗадания = Новый Структура();

ПараметрыЗадания.Вставить("ТипЗадания", "ЭкспортВExcel");

ПараметрыЗадания.Вставить("Данные", ВыбранныеДанные);

ФоновоеЗадание = ФоновыеЗадания.СоздатьНовоеЗадание(

"Обработка.ЭкспортДанных",

"ВыполнитьЭкспортНаСервере",

ПараметрыЗадания,

Истина, // Показывать прогресс

"Экспорт данных в Excel"

);

ФоновоеЗадание.ВыполнитьАсинхронно();

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

&НаСервере

Процедура ВыполнитьЭкспортНаСервере(Параметры, Оповещение) Экспорт

// Логика экспорта

Оповещение.СообщитьПользователю("Экспорт завершён!");

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

Способ вызова Блокировка интерфейса Поддержка тонкого клиента Макс. время выполнения
Прямой вызов (ПрямойВызовСервера) ❌ Да ⚠️ Частично Ограничено таймаутом сеанса
Фоновые задания ✅ Нет ✅ Да 60 минут (по умолчанию)
HTTP-сервисы ✅ Нет ✅ Да Зависит от настроек веб-сервера
⚠️ Внимание: Фоновые задания в 1С:Предприятие имеют ограничение на количество одновременно выполняемых задач (по умолчанию — 4). Если превысить этот лимит, новые задания будут ожидать в очереди. Чтобы изменить лимит, требуется правка параметров кластера серверов .

Настроены права доступа на объект "ФоновыеЗадания"|Проверено ограничение по времени выполнения|Реализована обработка ошибок в серверной процедуре|Настроено оповещение пользователя о завершении-->

3. HTTP-сервисы: вызов серверных процедур по протоколу HTTP

Если требуется вызвать серверную процедуру из внешней системы (например, с сайта или мобильного приложения) или организовать взаимодействие между разными базами , HTTP-сервисы становятся незаменимыми. Они позволяют:

  • 🌐 Вызывать процедуры по URL (например, http://server/hs/exchange/obnovit_dannye).
  • 🔒 Настраивать аутентификацию (базовая, по сертификатам, OAuth).
  • 📡 Работать с форматами JSON, XML или бинарными данными.
  • ⚠️ Требуют настройки веб-сервера (Apache, IIS, nginx) и публикации базы.

Пример создания HTTP-сервиса для обновления курсов валют:

&НаСервере

Процедура ОбновитьКурсыВалют(Запрос) Экспорт

ТелоОтвета = Новый Структура();

Попытка

// Логика обновления курсов

ТелоОтвета.Вставить("Статус", "OK");

ТелоОтвета.Вставить("Сообщение", "Курсы обновлены");

Исключение

ТелоОтвета.Вставить("Статус", "Error");

ТелоОтвета.Вставить("Сообщение", ОписаниеОшибки());

КонецПопытки;

Возврат Новый HTTPСервисОтвет(200, ТелоОтвета);

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

Чтобы вызвать этот сервис из клиентского кода, используйте HTTPСоединение:

Процедура ВызватьОбновлениеКурсов()

URL = "http://localhost/hs/currency/update";

Соединение = Новый HTTPСоединение(URL);

Ответ = Соединение.Получить();

Сообщить(Ответ.ПолучитьТекст());

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

Как опубликовать HTTP-сервис в IIS

1. Установите компонент "1С:Предприятие" для веб-сервера.

2. В IIS создайте новое приложение, указав путь к файлу default.vrd из каталога публикации 1С.

3. Настройте пул приложений с поддержкой .NET CLR версии 4.0.

4. В конфигураторе 1С опубликуйте веб-сервис через меню "Администрирование → Публикация на веб-сервере".

4. Механизм расширений: вызов серверных процедур из внешних обработок

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

  • 🔧 Модификации типовой конфигурации без изменения её кода.
  • 📦 Подключения внешних обработок с серверной логикой.
  • 🔄 Обмена данными между основной базой и расширением.

Пример вызова серверной функции из расширения:

&НаКлиенте

Процедура ВызватьСервернуюПроцедуру()

Результат = Расширения.ВыполнитьСервернуюФункцию(

"ОсновнаяКонфигурация.МодульОбщегоНазначения",

"ПолучитьАктуальныеДанные",

Параметр1

);

Сообщить(Результат);

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

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

5. Использование плановых заданий для отложенного выполнения

Если серверную процедуру нужно выполнить по расписанию или с задержкой (например, ночью для уменьшения нагрузки), подойдёт механизм плановых заданий. Он позволяет:

  • ⏰ Запускать процедуры в заданное время (ежедневно, еженедельно).
  • 🔄 Повторять выполнение при сбоях.
  • 📅 Привязывать задания к календарю (например, только по рабочим дням).
  • 🚫 Требует прав администратора для настройки.

Пример создания планового задания для архивации данных:

Процедура СоздатьЗаданиеНаАрхивацию()

РегламентноеЗадание = РегламентныеЗадания.СоздатьЗадание(

"Обработка.АрхивацияДанных",

"ВыполнитьАрхивациюНаСервере",

Новый Структура("Параметр1, Значение1")

);

РегламентноеЗадание.Расписание.Ежедневно(ВремяНачала(1, 30, 0)); // Каждый день в 1:30 ночи

РегламентноеЗадание.Записать();

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

💡

Для отладки плановых заданий используйте журнал регистрации (Администрирование → Журнал регистрации). Фильтруйте записи по типу события "Выполнение регламентного задания", чтобы быстро найти ошибки.

6. Типичные ошибки и как их избежать

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

  1. Ошибка "Операция не разрешена в данном контексте"

    Причина: Попытка вызвать серверную процедуру из модуля, где она не доступна (например, из модуля управляемой формы без директивы &НаСервере).

    Решение: Перенесите логику в модуль объекта или используйте ПрямойВызовСервера() с корректными параметрами.

  2. Таймаут при выполнении длительных операций

    Причина: Серверная процедура выполняется дольше, чем разрешает таймаут сеанса (по умолчанию — 300 секунд).

    Решение: Используйте фоновые задания или разбивайте задачу на более мелкие части.

  3. Ошибка "Недостаточно прав"

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

    Решение: Настройте роли в конфигураторе (Администрирование → Пользователи и права).

💡

Всегда проверяйте контекст выполнения серверной процедуры. Если она вызывается из клиентского кода, но работает с объектами базы данных (справочниками, документами), убедитесь, что у неё есть директива &НаСервере и корректные права доступа.

FAQ: Частые вопросы по вызову серверных процедур в 1С

Можно ли вызвать серверную процедуру из мобильного клиента 1С?

Да, но с ограничениями. В мобильном клиенте доступны:

  • Фоновые задания (асинхронный вызов).
  • HTTP-сервисы (если мобильное приложение взаимодействует с веб-сервером).

ПрямойВызовСервера() в мобильном клиенте не работает.

Как передать большой массив данных в серверную процедуру?

Для передачи больших данных (например, таблиц значений с тысячами строк) используйте:

  • Фоновые задания — если данные обрабатываются долго.
  • Временные таблицы — создайте временную таблицу на сервере и передавайте только её идентификатор.
  • Потоковую обработку — разбивайте данные на пакеты и обрабатывайте их порциями.

Пример с временной таблицей:

// На клиенте

ТаблицаДанных = ПолучитьДанные();

ИдВременнойТаблицы = ПоместитьВоВременноеХранилище(ТаблицаДанных);

// На сервере

&НаСервере

Процедура ОбработатьДанные(ИдВременнойТаблицы)

ТаблицаДанных = ПолучитьИзВременногоХранилища(ИдВременнойТаблицы);

// Обработка данных

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

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

Причины замедления могут быть разными:

  • Сетевые задержки — если клиент и сервер находятся в разных сетях (например, при работе через интернет).
  • Блокировки данных — если процедура работает с объектами, заблокированными другими сеансами.
  • Неоптимизированный код — например, циклы по большим выборкам без индексов.
  • Ограничения сервера 1С — нехватка памяти или процессорных ресурсов.

Решения:

  • Используйте ОбходРезультатаЗапроса вместо загрузки всех данных в память.
  • Настройте индексы для полей, по которым идут выборки.
  • Для длительных операций применяйте фоновые задания.
Как отладить серверную процедуру, вызванную из клиента?

Отладка серверного кода, вызванного с клиента, имеет нюансы:

  1. Установите точку останова в серверной процедуре.
  2. Включите режим отладки в настройках запуска конфигуратора (Отладка → Начать отладку).
  3. Если используется фоновое задание, отладьте его через журнал заданий (Администрирование → Фоновые задания).
  4. Для HTTP-сервисов используйте инструменты вроде Postman или curl для тестирования запросов.

Если отладчик не срабатывает, проверьте:

  • Правильно ли указана директива &НаСервере.
  • Нет ли ошибок в клиентском коде, препятствующих вызову.
  • Достаточно ли прав у пользователя для выполнения процедуры.
Можно ли вызвать серверную процедуру из другой базы 1С?

Да, для этого есть несколько способов:

  1. HTTP-сервисы — опубликуйте процедуру как веб-сервис в одной базе и вызовите её из другой через HTTPСоединение.
  2. COM-соединение — если базы находятся на одном компьютере, можно использовать Новый COMОбъект("V83.ComConnector").
  3. Обмен через файлы — экспортируйте данные в JSON/XML в одной базе и импортируйте в другой.
  4. Распределённые информационные базы (РИБ) — если базы связаны через механизм РИБ.

Пример вызова через COM:

Соединение = Новый COMОбъект("V83.ComConnector");

Попытка

Подключение = Соединение.Connect("File=""C:\Bases\Base1"";Usr=""Администратор"";");

Результат = Подключение.ОбновитьДанные();

Исключение

Сообщить("Ошибка подключения: " + ОписаниеОшибки());

КонецПопытки;