В процессе разработки в среде 1С:Предприятие 8 часто возникает ситуация, когда стандартные механизмы оповещения становятся избыточными. Например, при вызове процедур из других форм или при выполнении автоматизированных действий в РМК (рабочем месте кассира), системные сообщения могут мешать пользователю, хотя они крайне полезны для администратора или при отладке. В этой статье мы подробно разберем, как управлять выводом сообщений, почему стандартная команда ОчиститьСообщения() не всегда помогает и какие архитектурные подходы считаются наиболее правильными.
Рассмотрим стандартную ситуацию: разработчик вызывает ОчиститьСообщения() на клиенте после выполнения серверной команды, но сообщения все равно «всплывают». Выясним причину такого поведения платформы. Дело в том, что метод ОчиститьСообщения() удаляет только те сообщения, которые уже выведены в окно сообщений пользователя. Если же сообщения были сформированы в коде на стороне сервера и еще не переданы на клиент, эта команда их не затронет.
Сообщения в 1С накапливаются в специальном стеке во время выполнения серверного вызова и «выстреливают» на клиентскую сторону только в момент завершения серверного вызова и возврата управления. Поэтому, если вы вызываете метод очистки уже после того, как управление вернулось на форму, платформа успевает отобразить накопленный стек.
Самым эффективным техническим способом «заглушить» сообщения является использование метода ПолучитьСообщенияПользователю(Истина). Проанализируем, как это работает. Параметр Истина указывает платформе, что после получения массива сообщений их нужно удалить из внутреннего стека.
Важно: этот вызов должен происходить в той же серверной транзакции или в том же серверном контексте, где генерируются сообщения. Рассмотрим пример реализации на сервере:
// Процедура на сервере, вызываемая из первой формы
&НаСервере
Процедура ВыполнитьКомандуБезЛишнихСообщений()
// Вызываем логику второй формы или общего модуля,
// которая содержит нежелательные вызовы Сообщить()
Обработки.ТестированиеОборудования.ВыполнитьКомандуОткрытияЯщика();
// "Забираем" все накопленные сообщения и очищаем стек.
// Переменная СкрытыеСообщения будет содержать массив объектов СообщениеПользователю,
// но на экран они не попадут.
СкрытыеСообщения = ПолучитьСообщенияПользователю(Истина);
КонецПроцедуры
Этот метод идеально подходит, если вам нужно подавить сообщения «постфактум», не внося изменения в глубоко вложенные процедуры (те самые 4 процедуры из вопроса автора).
Если вы хотите подойти к задаче более системно, разберем вариант с использованием флагов подавления. Это позволяет избежать «выстрелов в ногу», как было метко замечено в обсуждении. Мы можем создать механизм, при котором процедура вывода сообщения сама решает, нужно ли ей отрабатывать.
Для реализации этого подхода можно использовать Параметры сеанса или ДополнительныеСвойства объекта. Посмотрим на алгоритм:
ПодавлятьСообщения = Истина.Сообщить(), добавляем проверку этого флага.Ложь.Пример модификации кода в процедурах вывода:
// В тех самых 4-х процедурах, которые не хочется править,
// но для чистоты кода это стоит сделать один раз
Если НЕ ПараметрыСеанса.РежимТишины Тогда
Сообщить("Команда выполнена успешно!");
КонецЕсли;
Проанализируем ситуацию с точки зрения архитектуры. Если сообщения нужны администратору для теста оборудования, но мешают пользователю, использование Сообщить() — не лучший выбор. Рассмотрим альтернативы:
Состояние(). Это выводит текст в нижнюю панель платформы, он не требует нажатия кнопок для закрытия и не перекрывает интерфейс РМК.Выясним причину появления сообщений в контексте ККТ. Часто сообщения генерируются не самой 1С, а драйвером торгового оборудования. В этом случае программная очистка внутри 1С методами ОчиститьСообщения() может не помочь, так как драйвер может вызывать свои диалоговые окна через внешнюю компоненту.
В такой ситуации рекомендуется проверить настройки интеграционной библиотеки в 1С. Обычно при вызове методов драйвера (например, ОткрытьДенежныйЯщик) можно передать структуру параметров, где указать «тихий режим». Если драйвер поддерживает такое управление, это будет самым надежным решением.
Для оперативного решения проблемы «здесь и сейчас» без глобальной переработки кода используйте связку серверного вызова и ПолучитьСообщенияПользователю(Истина) в конце процедуры. Однако для качественного развития системы мы рекомендуем постепенно отказываться от Сообщить() в пользу параметров сеанса и записи в журнал регистрации. Это сделает ваш интерфейс чище, а работу пользователей — продуктивнее.