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

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия IT и автоматизация бизнеса
← На главную

При разработке управляемых форм в платформе 1С:Предприятие 8 часто возникает необходимость информировать пользователя о ходе длительного процесса: например, при проведении серии документов, выгрузке данных или обмене по OLE/COM. Попытка вызвать клиентскую процедуру непосредственно из серверного кода приводит к ошибке компиляции. Проанализируем, почему возникает эта проблема и какими способами можно реализовать обратную связь с клиентом.

Причина ошибки и архитектурное ограничение

Рассмотрим причину возникновения ошибки «Процедура или функция с указанным именем не определена» при вызове процедур с директивой &НаКлиенте из серверного контекста &НаСервере.

В управляемом приложении платформа 1С строго разделяет контексты выполнения:

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

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

Способ 1. Использование фоновых заданий и обработчика ожидания

Разберем наиболее универсальный подход, рекомендованный разработчиками платформы. Длительная обработка выносится в фоновое задание, а клиентский интерфейс периодически опрашивает состояние этого задания.

Алгоритм решения по шагам:

  1. Запуск фонового задания: На клиенте вызывается серверная процедура, которая запускает длительную обработку через менеджер ФоновыеЗадания.Выполнить().
  2. Фиксация прогресса на сервере: В процессе выполнения фоновое задание передает данные о текущем статусе (например, через ПоместитьВоВременноеХранилище() или вызов СообщитьПользователю()).
  3. Периодический опрос с клиента: На форме запускается таймер методом ПодключитьОбработчикОжидания().
  4. Обновление интерфейса: Клиентская процедура-обработчик опрашивает состояние задания, забирает актуальные данные из временного хранилища и обновляет индикатор прогресса или текст состояния на форме.

Рассмотрим пример реализации фонового опроса на клиенте:


&НаКлиенте
Процедура ЗапуститьДлительныйПроцесс()
    // Запускаем процесс на сервере
    ИдентификаторЗадания = ЗапуститьЗаданиеНаСервере();
    
    // Подключаем периодический опрос формы раз в 1-2 секунды
    ПодключитьОбработчикОжидания("ПроверитьСтатусВыполнения", 2);
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьСтатусВыполнения()
    РезультатОбработки = ПроверитьЗаданиеНаСервере(ИдентификаторЗадания);
    
    // Обновляем состояние на форме
    Состояние("Обработано объектов: " + РезультатОбработки.Прогресс);
    
    Если РезультатОбработки.Завершено Тогда
        ОтключитьОбработчикОжидания("ПроверитьСтатусВыполнения");
        ПоказатьОповещениеПользователя("Обработка завершена!");
    КонецЕсли;
КонецПроцедуры

Способ 2. Использование подсистемы «Длительные операции» БСП

Если разработка ведется в типовой конфигурации (например, 1С:Бухгалтерия 3.0 или 1С:ERP), в нее уже встроен механизм Библиотеки Стандартных Подсистем (БСП). Это позволяет не писать с нуля код работы с фоновыми заданиями.

Выясним, как использовать функционал БСП:

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

Способ 3. Попорционная (пакетная) обработка на клиенте

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

Суть способа заключается в том, что основной цикл выполнения организуется на клиенте, а сервер вызывается небольшими порциями (пакетами по 50–100 документов):

  1. Клиент получает общий массив или список идентификаторов объектов.
  2. В цикле на клиенте берется очередная порция данных и передается на сервер в быструю процедуру &НаСервере.
  3. После возврата управления с сервера клиентский код обновляет индикатор прогресса на форме.
  4. Для сохранения отзывчивости интерфейса в клиентском цикле вызывается метод ОбработкаПрерыванияПользователя().

Важный нюанс: Частые вызовы сервера увеличивают накладные расходы на сетевой обмен, поэтому размер порции данных необходимо подбирать экспериментально.

Способ 4. Оповещения через Систему взаимодействия (платформа 8.3.11 и выше)

Начиная с версии платформы 8.3.11, появился механизм серверных push-уведомлений через Систему взаимодействия. Он позволяет передавать данные с сервера на клиент в реальном времени без использования постоянного таймера ПодключитьОбработчикОжидания.

Схема работы выглядит следующим образом:

  1. На клиенте оформляется подписка на сообщения с помощью метода НачатьПодключениеОбработчикаНовыхСообщений() менеджера системы взаимодействия.
  2. Сервер в ходе выполнения процедуры отправляет служебные структурированные данные в специальное обсуждение.
  3. Клиентский обработчик мгновенно получает данные по протоколу WebSocket и обновляет интерфейсные элементы.

Обратите внимание: данный способ требует включенной и настроенной Системы взаимодействия в информационной базе.

Особенности работы с внешними обработками и COM/OLE

Проанализируем специфику задачи, когда данные загружаются из внешней базы (например, из УТ 10.3 по OLE/COM) в контексте внешней обработки:

  1. Запуск из внешней обработки: При вызове фонового задания из внешнего файла программный код длительной операции должен находиться в модуле объекта этой обработки и содержать ключевое слово Экспорт.
  2. Ограничения COM-соединений: COM-объекты (например, V83.COMConnector) нельзя передавать между клиентом и сервером или сохранять в сеансовых переменных. Инициализация подключения к сторонней базе и вся работа с OLE-объектами должны полностью выполняться внутри серверного контекста фонового задания.
← На главную