При работе с конфигурацией 1С:Документооборот 3.0 (и другими решениями на базе БСП) программисты часто сталкиваются с проблемой отладки: если внешняя обработка запускается напрямую из справочника ДополнительныеОтчетыИОбработки (через кнопку «Выполнить»), то стандартные методы вывода сообщений, такие как Сообщить() или ОбщегоНазначенияКлиентСервер.СообщитьПользователю(), не срабатывают. Пользователь видит индикатор выполнения, но по завершении процесса никакие информационные окна не появляются.
Разберем детально, почему так происходит и какие существуют способы решения этой задачи, от стандартных настроек БСП до более продвинутых методик.
Проанализируем ситуацию: когда в параметрах регистрации обработки указан тип команды ВызовСерверногоМетода, система 1С:Предприятие запускает выполнение кода в фоновом задании. Это делается для того, чтобы интерфейс пользователя не «зависал» во время длительных операций. Однако фоновое задание выполняется в отдельном сеансе на сервере, который не имеет прямой связи с экранными формами клиентского приложения.
Хотя платформа 8.3 накапливает сообщения, вызванные методом Сообщить(), в буфере фонового задания, они будут показаны пользователю только в том случае, если вызывающий программный код (в данном случае — механизмы БСП) принудительно прочитает их после завершения задания и передаст на клиент. В старых версиях или при определенных настройках БСП в «Документообороте» этот механизм может не срабатывать автоматически для команд из списка.
Самый правильный и «штатный» способ — изменить логику взаимодействия с пользователем, перенеся управление на сторону клиента. Для этого нам необходимо отредактировать функцию СведенияОВнешнейОбработке.
Рассмотрим пример настройки команды:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке();
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = "Выполнить обработку с уведомлением";
НоваяКоманда.Идентификатор = "ВыполнитьСУведомлением";
// Вместо ВызовСерверногоМетода используем ВызовКлиентскогоМетода
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовКлиентскогоМетода();
Возврат ПараметрыРегистрации;
КонецФункции
После этого в модуле формы обработки необходимо создать экспортную процедуру Печать (или другую, в зависимости от контекста), которая примет управление. Поскольку код выполняется на клиенте, мы можем использовать ПоказатьОповещениеПользователя(), которое мгновенно выведет всплывающее окно в углу экрана.
Если пользователю принципиально не нужно видеть форму обработки, но сообщения крайне важны (например, уведомление о том, что файл занят), мы можем использовать тип команды ОткрытиеФормы. Проанализируем, как это реализовать так, чтобы форма не мешала работе:
СведенияОВнешнейОбработке устанавливаем использование ТипКомандыОткрытиеФормы().ПриОткрытии.Пример кода в модуле формы:
&НаКлиенте
Процедура ПриОткрытии(Отказ)
// Выполняем основную логику (можно вызвать серверный метод)
Результат = ВыполнитьДействиеНаСервере();
// Выводим мгновенное сообщение
ТекстСообщения = ?(Результат, "Файл успешно записан", "Ошибка: файл открыт другим пользователем!");
ПоказатьОповещениеПользователя("Статус обработки", , ТекстСообщения);
// Закрываем форму сразу после выполнения, чтобы пользователь её не заметил
Отказ = Истина;
КонецПроцедуры
В данном случае пользователь нажмет «Выполнить», форма попытается открыться, выполнит код, покажет уведомление и тут же закроется (благодаря параметру Отказ = Истина или методу ЭтаФорма.Закрыть()). Это создает эффект бесшовной работы.
Выясним причину, почему это решение считается наиболее современным. Если ваша организация использует Систему взаимодействия (встроенный мессенджер 1С), вы можете отправлять сообщения пользователю напрямую с сервера, даже из самого глубокого фонового задания.
Рассмотрим программную реализацию на сервере:
// Код внутри серверного метода внешней обработки
ВыборкаПользователей = Пользователи.НайтиПоИмени(ИмяПользователя);
Если ВыборкаПользователей.Количество() > 0 Тогда
Участник = СистемаВзаимодействия.СоздатьИдентификаторПользователя(ВыборкаПользователей[0].ИдентификаторПользователяИнформационнойБазы);
НовоеСообщение = СистемаВзаимодействия.СоздатьСообщение();
НовоеСообщение.Текст = "Внимание! Файл, в который происходит запись, сейчас открыт.";
НовоеСообщение.Получатели.Добавить(Участник);
НовоеСообщение.Записать();
КонецЕсли;
Преимущество этого метода в том, что сообщение придет пользователю мгновенно, вне зависимости от того, как завершилось фоновое задание и какой тип команды был выбран.
Если в вашем «1С:Документооборот» включена подсистема «Напоминания пользователя», можно применить «костыльный», но рабочий метод, предложенный участниками обсуждения. Мы можем программно создать напоминание, которое должно сработать «сейчас».
Посмотрим на пример логики:
НапоминанияПользователя.Однако, как заметил автор темы, для задач типа «файл открыт прямо сейчас» этот метод подходит плохо из-за задержки срабатывания регламентного задания напоминаний.
Подводя итог нашему анализу, выделим наиболее эффективную стратегию:
ПоказатьВопрос().Важно помнить, что при использовании серверных методов (фоновых заданий) стандартный Сообщить() предназначен скорее для логирования хода выполнения, чем для оперативного взаимодействия с интерфейсом пользователя.