При разработке управляемых форм в платформе 1С:Предприятие 8 часто возникает необходимость информировать пользователя о ходе длительного процесса: например, при проведении серии документов, выгрузке данных или обмене по OLE/COM. Попытка вызвать клиентскую процедуру непосредственно из серверного кода приводит к ошибке компиляции. Проанализируем, почему возникает эта проблема и какими способами можно реализовать обратную связь с клиентом.
Рассмотрим причину возникновения ошибки «Процедура или функция с указанным именем не определена» при вызове процедур с директивой &НаКлиенте из серверного контекста &НаСервере.
В управляемом приложении платформа 1С строго разделяет контексты выполнения:
Взаимодействие происходит исключительно по инициативе клиента: клиент отправляет запрос на сервер, сервер обрабатывает его и возвращает результат. Сервер не может по собственной инициативе вызвать клиентскую процедуру или обратиться к элементам формы, так как на сервере пользовательский интерфейс отсутствует. Поэтому вызов процедуры ПоказатьСостояние() из серверного цикла принципиально невозможен.
Разберем наиболее универсальный подход, рекомендованный разработчиками платформы. Длительная обработка выносится в фоновое задание, а клиентский интерфейс периодически опрашивает состояние этого задания.
Алгоритм решения по шагам:
ФоновыеЗадания.Выполнить().ПоместитьВоВременноеХранилище() или вызов СообщитьПользователю()).ПодключитьОбработчикОжидания().Рассмотрим пример реализации фонового опроса на клиенте:
&НаКлиенте
Процедура ЗапуститьДлительныйПроцесс()
// Запускаем процесс на сервере
ИдентификаторЗадания = ЗапуститьЗаданиеНаСервере();
// Подключаем периодический опрос формы раз в 1-2 секунды
ПодключитьОбработчикОжидания("ПроверитьСтатусВыполнения", 2);
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьСтатусВыполнения()
РезультатОбработки = ПроверитьЗаданиеНаСервере(ИдентификаторЗадания);
// Обновляем состояние на форме
Состояние("Обработано объектов: " + РезультатОбработки.Прогресс);
Если РезультатОбработки.Завершено Тогда
ОтключитьОбработчикОжидания("ПроверитьСтатусВыполнения");
ПоказатьОповещениеПользователя("Обработка завершена!");
КонецЕсли;
КонецПроцедуры
Если разработка ведется в типовой конфигурации (например, 1С:Бухгалтерия 3.0 или 1С:ERP), в нее уже встроен механизм Библиотеки Стандартных Подсистем (БСП). Это позволяет не писать с нуля код работы с фоновыми заданиями.
Выясним, как использовать функционал БСП:
ДлительныеОперации.СообщитьПрогресс(Процент, Текст).ДлительныеОперацииКлиент.Рассмотрим альтернативный вариант без использования фоновых заданий, который подходит для небольших объемов данных или при отсутствии возможности запускать фоновые процессы.
Суть способа заключается в том, что основной цикл выполнения организуется на клиенте, а сервер вызывается небольшими порциями (пакетами по 50–100 документов):
&НаСервере.ОбработкаПрерыванияПользователя().Важный нюанс: Частые вызовы сервера увеличивают накладные расходы на сетевой обмен, поэтому размер порции данных необходимо подбирать экспериментально.
Начиная с версии платформы 8.3.11, появился механизм серверных push-уведомлений через Систему взаимодействия. Он позволяет передавать данные с сервера на клиент в реальном времени без использования постоянного таймера ПодключитьОбработчикОжидания.
Схема работы выглядит следующим образом:
НачатьПодключениеОбработчикаНовыхСообщений() менеджера системы взаимодействия.Обратите внимание: данный способ требует включенной и настроенной Системы взаимодействия в информационной базе.
Проанализируем специфику задачи, когда данные загружаются из внешней базы (например, из УТ 10.3 по OLE/COM) в контексте внешней обработки:
Экспорт.V83.COMConnector) нельзя передавать между клиентом и сервером или сохранять в сеансовых переменных. Инициализация подключения к сторонней базе и вся работа с OLE-объектами должны полностью выполняться внутри серверного контекста фонового задания.