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

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

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

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

Напрямую вызвать клиентскую процедуру из серверного кода в 1С нельзя: серверный и клиентский контексты физически разделены, и у сервера нет ссылки на сеанс конкретного пользователя. Это ограничение архитектуры клиент-серверного режима, а не недоработка платформы. Однако задача «сообщить клиенту о событии на сервере» решается несколькими штатными механизмами.

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

Ниже разобраны все варианты с примерами кода, условиями применения и типичными ошибками, из-за которых механизм «не работает» у начинающих разработчиков.

Почему прямой вызов невозможен и как обойти ограничение

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

Поэтому все рабочие схемы строятся по принципу «клиент спрашивает — сервер отвечает» или «сервер публикует событие — клиент его подхватывает». Попытка написать на сервере вызов клиентской процедуры приведёт либо к ошибке компиляции (процедура недоступна в серверном контексте), либо к ошибке исполнения.

Способ 1. Сообщение пользователю через СообщитьПользователю

Самый простой вариант, когда цель — не выполнить код на клиенте, а донести до пользователя информацию с сервера. Метод глобального контекста СообщитьПользователю() (или объект СообщениеПользователю) работает из серверного кода: сообщения накапливаются и показываются в клиентском сеансе после завершения серверного вызова.

Пример серверного кода:

&НаСервере

Процедура ОбработатьДанныеНаСервере()

// ... серверная обработка ...

Сообщение = Новый СообщениеПользователю;

Сообщение.Текст = "Обработано записей: " + Счетчик;

Сообщение.Сообщить();

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

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

Способ 2. Фоновое задание с опросом результата на клиенте

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

&НаКлиенте

Процедура ЗапуститьОбработку(Команда)

Результат = ЗапуститьФоновоеЗаданиеНаСервере();

ИдентификаторЗадания = Результат.ИдентификаторЗадания;

АдресРезультата = Результат.АдресРезультата;

ПодключитьОбработчикОжидания("ПроверитьВыполнение", 2, Ложь);

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

&НаКлиенте

Процедура ПроверитьВыполнение()

Если ЗаданиеВыполнено(ИдентификаторЗадания) Тогда

ОтключитьОбработчикОжидания("ПроверитьВыполнение");

Данные = ПолучитьИзВременногоХранилища(АдресРезультата);

ОбработатьРезультатНаКлиенте(Данные); // нужная клиентская процедура

КонецЕсли;

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

На сервере результат помещается во временное хранилище через ПоместитьВоВременноеХранилище(Результат, АдресРезультата). Важно: адрес хранилища должен быть передан в фоновое задание как параметр, иначе клиент не сможет забрать данные.

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

Способ 3. Длительные операции БСП

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

&НаКлиенте

Процедура ВыполнитьДлительнуюОперацию(Команда)

ПараметрыВыполнения = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);

ПараметрыВыполнения.ВыводитьОкноОжидания = Истина;

Оповещение = Новый ОписаниеОповещения("ПослеЗавершенияОперации", ЭтотОбъект);

ДлительнаяОперация = ВыполнитьОперациюНаСервере();

ДлительныеОперацииКлиент.ОжидатьЗавершение(ДлительнаяОперация, Оповещение, ПараметрыВыполнения);

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

&НаКлиенте

Процедура ПослеЗавершенияОперации(Результат, ДопПараметры) Экспорт

Если Результат.Статус = "Выполнено" Тогда

Данные = ПолучитьИзВременногоХранилища(Результат.АдресРезультата);

// клиентская обработка результата

Иначе

ПоказатьПредупреждение(, Результат.КраткоеПредставлениеОшибки);

КонецЕсли;

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

Это рекомендуемый путь для типовых и доработанных конфигураций на БСП: меньше ручного кода, штатная обработка ошибок и прогресс выполнения.

Способ 4. Оповещения между формами и система взаимодействия

Метод Оповестить() работает в клиентском контексте и рассылает событие открытым формам, подписанным через ОбработкаОповещения. Сам по себе он не решает задачу «сервер → клиент», но входит в цепочку: серверный вызов завершается, клиент в обработчике результата вызывает Оповестить(), и другие формы реагируют.

Для сценария «сервер инициирует событие без запроса клиента» подойдёт система взаимодействия (если она развёрнута в информационной базе) или периодический опрос серверных данных обработчиком ожидания — например, проверка появления новых записей в регистре сведений «очереди уведомлений».

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

Сравнение способов

СообщитьПользователю

Только текстовое уведомление, никакой клиентской логики. Подходит для статусов и ошибок

Фоновое задание + опрос

Универсально, работает без БСП, но требует ручного управления обработчиком ожидания

Длительные операции БСП

Рекомендуемый вариант для конфигураций на БСП: штатное ожидание, ошибки и прогресс

Очередь в регистре сведений

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

Типичные ошибки и ограничения

Самая частая ошибка — попытка вызвать из серверной процедуры клиентскую или обратиться к элементам формы в контексте &НаСервере без УправлениеФормой. Компилятор это отсекает, но в модулях без директив контекстной компиляции ошибка всплывает только в runtime.

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

Типичные ошибки
01
Вызов клиентской процедуры из серверного кода — ошибка компиляции или исполнения; перестройте схему на опрос или оповещение
02
Неэкспортный обработчик оповещения — платформа не найдёт процедуру при завершении операции
03
Потеря адреса временного хранилища — результат фонового задания становится недоступен клиенту
04
Опрос сервера чаще раза в секунду — лишняя нагрузка на сервер приложений
05
Передача несериализуемых данных между сервером и клиентом — ошибка при обмене контекстами

Как проверить, что механизм работает

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

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

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

Завершение фонового задания
Норма

Состояние задания «Выполнено», данные читаются из хранилища

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

Задание в статусе «Ошибка» или хранилище пустое

Вызов клиентского обработчика
Норма

Процедура оповещения срабатывает, точка останова в отладчике достигается

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

Обработчик не вызывается — проверьте Экспорт и имя процедуры

Нагрузка на сервер
Норма

Опрос не чаще 1–2 секунд, вызовы короткие

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

Постоянные серверные вызовы, рост времени отклика сеансов

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

FAQ

Можно ли с сервера показать модальное окно пользователю?

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

Как серверу сообщить клиенту о событии, если пользователь ничего не нажимал?

Используйте обработчик ожидания на клиенте, который периодически опрашивает сервер (например, читает новые записи из регистра-очереди), либо систему взаимодействия, если она развёрнута в базе.

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

Чаще всего процедура не экспортная, неверно указано имя в ОписаниеОповещения или форма-владелец уже закрыта. Проверьте слово Экспорт и совпадение имени процедуры с точностью до символа.

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

Напрямую — нет, таблица значений не сериализуется для передачи. Преобразуйте её в массив структур или используйте ЗначениеВСтрокуВнутр/хранилище значения, либо поместите данные во временное хранилище в сериализуемом виде.

Что выбрать для обычной обработки данных по кнопке в форме?

Если конфигурация на БСП — длительные операции с ОжидатьЗавершение. Если БСП нет — фоновое задание с обработчиком ожидания и опросом состояния. Для быстрых операций достаточно обычного серверного вызова с возвратом результата.

Итог

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

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