При пакетной обработке или проведении документов в фоновом режиме разработчики часто сталкиваются с ситуацией, когда метод ПолучитьСообщенияПользователю() возвращает пустой массив, хотя в окне служебных сообщений или при интерактивной работе текст отображается. Разберем особенности сбора сообщений, типичные ошибки и правильные подходы к получению протокола работы процедур.
Рассмотрим основные технические причины, по которым коллекция сообщений оказывается пустой:
ПолучитьСообщенияПользователю() перехватывает исключительно те сообщения, которые были сформированы через создание экземпляра объекта СообщениеПользователю и вызов его метода Сообщить(). Если в алгоритмах проведения (особенно в конфигурациях на обычных формах) используется классический оператор Сообщить(...), такие сообщения не попадают во внутренний стек платформы и не могут быть программно получены данным методом.ПолучитьСообщенияПользователю() считывает буфер сообщений только текущего сеанса. Если длительная процедура запущена как фоновое задание в отдельном потоке, обращение к глобальной функции из вызывающего сеанса вернет пустой результат. Для фонового потока получение сообщений выполняется через обращение к конкретному объекту ФоновоеЗадание.ПолучитьСообщенияПользователю(Истина) очищает буфер сообщений сеанса. Если типовой код конфигурации или библиотека стандартных подсистем (БСП) уже вызвала этот метод с очисткой ранее по стеку вызовов, последующее обращение вернет пустой массив.Проанализируем синтаксис и корректный способ извлечения сообщений, сформированных фоновым процессом:
// Получаем сообщения непосредственно у объекта фонового задания
МассивСообщений = Задание.ПолучитьСообщенияПользователю(Истина);
Для Каждого Сообщение Из МассивСообщений Цикл
ТекстРезультат = ТекстРезультат + " " + Сообщение.Текст + ";";
КонецЦикла;
Обратите внимание на синтаксис метода объекта ФоновоеЗадание:
Параметр <УдалятьПолученные> (необязательный, тип Булево) указывает платформе, нужно ли очищать полученные сообщения из очереди задания. Если передано значение Истина, при следующем обращении к объекту эти сообщения уже не вернутся.
Посмотрим на пример кода, гарантирующий попадание выводимой информации в буфер сообщений платформы:
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Обнаружено расхождение остатков при проведении документа.";
Сообщение.Поле = "ТабличнаяЧасть[0].Количество";
Сообщение.УстановитьДанные(ЭтотОбъект);
Сообщение.Сообщить();
Такой вызов корректно регистрирует сообщение как в контексте сеанса, так и внутри потока фонового задания.
Перехват сообщений пользователя через разбор текстовых строк часто является ненадежным механизмом для контроля корректности проведения документов. Рассмотрим рекомендуемые альтернативные варианты сбора информации о предупреждениях и ошибках:
ЗаписьЖурналаРегистрации() с уровнем УровеньЖурналаРегистрации.Предупреждение или УровеньЖурналаРегистрации.Ошибка. После завершения пакета информацию можно централизованно выгрузить через метод ВыгрузитьЖурналРегистрации().