Как вывести сообщение пользователю из модуля объекта внешней обработки с видом «Заполнение объекта»?

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

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

Разберем причину проблемы: почему сообщения «пропадают»?

Проанализируем ситуацию. Внешняя обработка с видом ЗаполнениеОбъекта регистрируется в системе и вызывается из формы списка или формы объекта. Когда мы выбираем тип команды ВызовСерверногоМетода, выполнение кода происходит в процедуре ВыполнитьКоманду модуля объекта обработки. Несмотря на то, что платформа 1С должна автоматически передавать сообщения с сервера на клиент, в контексте БСП существуют нюансы:

  1. Отсутствие привязки к форме: Если сообщение создается в модуле объекта, оно не всегда может автоматически определить «владельца» — активное окно пользователя. Если форма списка, из которой вызвана команда, не является явно заданным владельцем сообщения, платформа может проигнорировать вывод.
  2. Механизм фонового выполнения: В современных версиях БСП многие серверные команды могут выполняться асинхронно через фоновые задания (особенно если это настроено в справочнике «Дополнительные отчеты и обработки»). Сообщения, созданные внутри фонового задания, требуют специальной обработки для передачи в основной сеанс пользователя.
  3. Безопасный режим: Если обработка запущена в безопасном режиме, работа с некоторыми интерфейсными механизмами может быть ограничена.

Рассмотрим первый вариант решения: Переход к клиентскому вызову

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

Во-первых, в функции СведенияОВнешнейОбработке необходимо изменить тип вызова команды. Вместо ВызовСерверногоМетода указываем ВызовКлиентскогоМетода. Посмотрим на пример настройки таблицы команд:


Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = "")
    НоваяКоманда = ТаблицаКоманд.Добавить();
    НоваяКоманда.Представление = Представление;
    НоваяКоманда.Идентификатор = Идентификатор;
    НоваяКоманда.Использование = "ВызовКлиентскогоМетода"; // Важный момент!
    НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
    НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры

Во-вторых, создадим во внешней обработке форму. Она может быть пустой, без реквизитов и кнопок. В модуле этой формы опишем процедуру, которая будет принимать управление от БСП. Вызов произойдет в методе ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения) модуля формы.

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


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

Разберем второй вариант решения: Использование стандартных механизмов БСП на сервере

Если создание формы кажется избыточным, можно остаться в рамках ВызовСерверногоМетода, но использовать правильные инструменты для передачи результата. В процедуру ВыполнитьКоманду модуля объекта передается параметр ПараметрыВыполненияКоманды.

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

Посмотрим на исправленный пример процедуры в модуле объекта:


Процедура ВыполнитьКоманду(ИмяКоманды, ОбъектыНазначения, ПараметрыВыполненияКоманды) Экспорт
    
    Для Каждого СсылкаНаОбъект Из ОбъектыНазначения Цикл
        Попытка
            // Логика создания или изменения документа
            // ...
            
            // Вместо обычного Сообщить() используем специализированный модуль
            Текст = СтрШаблон("Документ %1 успешно создан", СсылкаНаОбъект.Номер);
            ОбщегоНазначенияКлиентСервер.СообщитьПользователю(Текст);
            
        Исключение
            ТекстОшибки = СтрШаблон("Ошибка при обработке %1: %2", СсылкаНаОбъект, ОписаниеОшибки());
            ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстОшибки);
        КонецПопытки;
    КонецЦикла;
    
КонецПроцедуры

Важный нюанс: Чтобы сообщение «приклеилось» к конкретной форме, из которой была вызвана обработка, можно использовать свойство ИдентификаторФормы, которое часто передается в составе ПараметрыВыполненияКоманды. Это позволит платформе понять, какому именно окну адресован вывод.

Проанализируем ситуацию с привязкой к реквизитам

В тексте обсуждения упоминалась привязка к конкретным полям формы. Если вы хотите, чтобы пользователь мог нажать на сообщение в панели сообщений и курсор автоматически перешел к ошибочному реквизиту, необходимо заполнять свойства ПутьКДанным и КлючДанных объекта СообщениеПользователю.

Рассмотрим пример детальной настройки сообщения:


Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Не удалось заполнить поле 'Склад'";
Сообщение.Поле = "Объект.Склад"; // Путь к реквизиту на форме
Сообщение.УстановитьДанные(НовыйДокумент); // Привязка к самому объекту данных
Сообщение.Сообщить();

Однако стоит помнить: при вызове из формы списка такая детальная привязка к реквизитам внутри создаваемого документа не всегда имеет смысл, так как форма этого документа еще не открыта. В этом случае достаточно простого текстового уведомления.

Выводы и рекомендации

Подведем итог. Если вам необходимо гарантированно выводить сообщения из внешней обработки заполнения в УТ 11.4:

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

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

← На главную