Как вывести сообщение пользователю из внешней обработки при запуске через справочник Дополнительные отчеты и обработки

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

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

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

Почему сообщения не отображаются при серверном выполнении?

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

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

Решение №1: Изменение типа команды на клиентский метод

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

Рассмотрим пример настройки команды:


Функция СведенияОВнешнейОбработке() Экспорт
    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке();
    
    НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
    НоваяКоманда.Представление = "Выполнить обработку с уведомлением";
    НоваяКоманда.Идентификатор = "ВыполнитьСУведомлением";
    
    // Вместо ВызовСерверногоМетода используем ВызовКлиентскогоМетода
    НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовКлиентскогоМетода();
    
    Возврат ПараметрыРегистрации;
КонецФункции

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

Решение №2: Использование «Формы-невидимки»

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

  1. В функции СведенияОВнешнейОбработке устанавливаем использование ТипКомандыОткрытиеФормы().
  2. В модуле основной формы обработки прописываем логику в обработчике ПриОткрытии.

Пример кода в модуле формы:


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

В данном случае пользователь нажмет «Выполнить», форма попытается открыться, выполнит код, покажет уведомление и тут же закроется (благодаря параметру Отказ = Истина или методу ЭтаФорма.Закрыть()). Это создает эффект бесшовной работы.

Решение №3: Система взаимодействия (Push-уведомления)

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

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


// Код внутри серверного метода внешней обработки
ВыборкаПользователей = Пользователи.НайтиПоИмени(ИмяПользователя);
Если ВыборкаПользователей.Количество() > 0 Тогда
    Участник = СистемаВзаимодействия.СоздатьИдентификаторПользователя(ВыборкаПользователей[0].ИдентификаторПользователяИнформационнойБазы);
    
    НовоеСообщение = СистемаВзаимодействия.СоздатьСообщение();
    НовоеСообщение.Текст = "Внимание! Файл, в который происходит запись, сейчас открыт.";
    НовоеСообщение.Получатели.Добавить(Участник);
    НовоеСообщение.Записать();
КонецЕсли;

Преимущество этого метода в том, что сообщение придет пользователю мгновенно, вне зависимости от того, как завершилось фоновое задание и какой тип команды был выбран.

Решение №4: Механизм напоминаний БСП

Если в вашем «1С:Документооборот» включена подсистема «Напоминания пользователя», можно применить «костыльный», но рабочий метод, предложенный участниками обсуждения. Мы можем программно создать напоминание, которое должно сработать «сейчас».

Посмотрим на пример логики:

  1. В серверном коде обработки создаем запись в регистре сведений НапоминанияПользователя.
  2. Устанавливаем время напоминания равным текущему моменту.
  3. При следующем сеансе проверки (обычно раз в минуту) у пользователя всплывет стандартное окно напоминания.

Однако, как заметил автор темы, для задач типа «файл открыт прямо сейчас» этот метод подходит плохо из-за задержки срабатывания регламентного задания напоминаний.

Резюме и рекомендации

Подводя итог нашему анализу, выделим наиболее эффективную стратегию:

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

← На главную