К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как выводить служебные сообщения в 1С

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

Служебные сообщения в 1С — основной способ обратной связи программы с пользователем: предупреждения об ошибках заполнения, результаты проведения документа, информация о ходе длительной операции. Платформа предлагает несколько механизмов вывода, и выбор между ними влияет не только на внешний вид, но и на поведение системы: например, сообщение может быть привязано к конкретному полю формы или заблокировать дальнейшую работу до подтверждения.

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

Ниже разобраны основные способы вывода сообщений, различия между ними, примеры кода и типичные ошибки, которые приводят к потере сообщений или некорректной работе формы.

Какие механизмы вывода сообщений есть в платформе

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

Дополнительно существуют методы протоколирования: запись в журнал регистрации через ЗаписьЖурналаРегистрации() и вывод в состояние длительной операции через ДлительныеОперации.СообщитьПрогресс() при использовании БСП. Они не показывают текст напрямую, но часто именно их следует выбирать для служебной диагностики, чтобы не засорять интерфейс пользователя.

Сравнение вариантов

Сообщить()

Быстро и просто, но без привязки к полю и без управления категорией. Подходит для отладки и фоновых заданий.

СообщениеПользователю

Привязка к данным и полю формы, категории, ключ данных. Рекомендуемый способ в прикладном коде форм и проведения.

ПоказатьПредупреждение / ПоказатьВопрос

Модальный диалог с обязательной реакцией пользователя. Только на клиенте, только асинхронно с описанием оповещения.

ПоказатьОповещениеПользователя

Ненавязчивое всплывающее уведомление, не блокирует работу. Для информационных событий.

Процедура Сообщить(): простой вывод и его ограничения

Самый известный способ — вызов Сообщить("Текст сообщения"). Вторым параметром можно передать статус: СтатусСообщения.Важное, Внимание, Информация и другие — он влияет на оформление в панели сообщений. Процедура доступна и на сервере, и на клиенте.

Сообщить("Документ успешно проведен", СтатусСообщения.Информация);

Сообщить("Не заполнен контрагент!", СтатусСообщения.Важное);

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

Типичные ошибки
01
Использование Сообщить() для каждой строки табличной части при проверке — пользователь получает сотни сообщений без привязки к строкам.
02
Вызов Сообщить() на клиенте после серверного вызова — серверные сообщения и клиентские перемешиваются, теряется контекст.
03
Вывод технических деталей ошибки (текст исключения, стек) конечному пользователю вместо записи в журнал регистрации.

Объект СообщениеПользователю: привязка к данным и полю формы

Объект СообщениеПользователю — правильный инструмент для сообщений, связанных с конкретным объектом или реквизитом. Он создаётся конструктором, заполняется свойствами и выводится методом Сообщить() самого объекта.

Сообщение = Новый СообщениеПользователю;

Сообщение.Текст = "Не заполнено поле ""Контрагент""";

Сообщение.Поле = "Контрагент";

Сообщение.УстановитьДанные(Объект);

Сообщение.Сообщить();

Свойство Поле принимает путь к данным формы. Для табличной части указывается путь с индексом строки, например "Товары[2].Количество" — тогда при двойном щелчке по сообщению форма активирует именно эту ячейку. Метод УстановитьДанные() связывает сообщение с объектом, что позволяет платформе корректно показывать сообщения при открытии формы объекта.

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

Порядок действий
  1. 1
    Создайте объект: Сообщение = Новый СообщениеПользователю.
  2. 2
    Заполните Текст понятной пользователю формулировкой без технических деталей.
  3. 3
    Укажите Поле — путь к реквизиту формы, например Объект.Контрагент или Товары[0].Цена.
  4. 4
    Вызовите УстановитьДанные(Объект) для связи с редактируемыми данными.
  5. 5
    Вызовите Сообщение.Сообщить() и проверьте, что двойной щелчок по сообщению активирует нужное поле.

Интерактивные диалоги: предупреждения, вопросы, оповещения

Когда требуется гарантированная реакция пользователя, панель сообщений не подходит — нужен модальный диалог. В управляемом приложении работают только асинхронные методы: ПоказатьПредупреждение(), ПоказатьВопрос(), ПоказатьВводЗначения(). Модальные синхронные аналоги (Предупреждение(), Вопрос()) в тонком и веб-клиенте не работают.

ОписаниеОповещения = Новый ОписаниеОповещения("ПослеЗакрытияПредупреждения", ЭтотОбъект);

ПоказатьПредупреждение(ОписаниеОповещения, "Проведение отменено: отрицательные остатки", 10, "Внимание");

Третий параметр — таймаут в секундах, после которого диалог закроется сам. Для вопроса результат приходит в процедуру обработчика первым параметром (например, КодВозвратаДиалога.Да). Важно помнить: эти методы доступны только в клиентском контексте, вызов на сервере приведёт к ошибке.

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

Сообщения при проведении и в обработчиках проверки заполнения

Типичный сценарий — отказ в проведении документа с объяснением причины. В модуле объекта сообщение выводится через СообщениеПользователю, после чего устанавливается параметр Отказ = Истина. Платформа покажет сообщения пользователю, а документ не проведётся.

Процедура ОбработкаПроведения(Отказ, Режим)

Если ОстатокНедостаточен Тогда

Сообщение = Новый СообщениеПользователю;

Сообщение.Текст = "Недостаточно товара на складе";

Сообщение.КлючДанных = Ссылка;

Сообщение.Сообщить();

Отказ = Истина;

КонецЕсли;

КонецПроцедуры

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

Вывод сообщений из фоновых заданий и длительных операций

Фоновое задание не имеет интерфейса, поэтому вызванные в нём Сообщить() и СообщениеПользователю накапливаются во внутреннем буфере задания. На клиенте их можно забрать вручную: ПолучитьСообщенияПользователю(Истина) — второй параметр включает сообщения фоновых заданий, после чего их нужно перебрать и вывести повторно в пользовательском сеансе.

При использовании Библиотеки стандартных подсистем задача решается штатно: механизм длительных операций сам передаёт сообщения и прогресс на клиента, разработчику достаточно вызывать ДлительныеОперации.СообщитьПрогресс() и обычные сообщения внутри серверной процедуры. Если БСП в конфигурации нет, реализуйте передачу через временное хранилище: сервер складывает массив сообщений в адрес результата, клиент по завершении читает и выводит его.

Контрольные точки

Как проверить результат

Привязка к полю
Норма

Двойной щелчок по сообщению активирует нужный реквизит или ячейку таблицы

Тревожный признак

Сообщение есть, но форма не реагирует на щелчок — неверно указан путь в свойстве Поле

Отказ в проведении
Норма

После сообщения документ не проводится, сообщения видны в панели

Тревожный признак

Сообщение вывелось, но документ провелся — не установлен Отказ = Истина

Сообщения фонового задания
Норма

После завершения операции пользователь видит все сообщения процесса

Тревожный признак

Панель пуста — сообщения остались в буфере задания и не перенесены на клиента

Журнал регистрации вместо сообщений пользователю

Не всякая служебная информация предназначена конечному пользователю. Технические детали ошибок, трассировка обменов, диагностика фоновых процессов должны попадать в журнал регистрации через ЗаписьЖурналаРегистрации(). Там эти данные доступны администратору, не пугают пользователя и не теряются при закрытии сеанса.

ЗаписьЖурналаРегистрации("ОбменДанными.Загрузка",

УровеньЖурналаРегистрации.Ошибка, , ,

"Ошибка загрузки: " + ОписаниеОшибки());

Хорошая практика — комбинировать оба канала: пользователю показывается короткое понятное сообщение («Не удалось загрузить данные, обратитесь к администратору»), а полное описание исключения пишется в журнал регистрации. Так вы не раскрываете внутреннее устройство системы и одновременно сохраняете данные для диагностики.

Маршрут решения

Как выбрать действие

Ошибка связана с конкретным реквизитом формыИспользуйте СообщениеПользователю с заполненным Поле и УстановитьДанные
Нужна обязательная реакция или выбор пользователяПоказатьПредупреждение или ПоказатьВопрос с описанием оповещения, только на клиенте
Фоновое задание или массовая обработкаПишите в протокол задания и журнал регистрации, на клиент переносите сводку
Техническая диагностика для администратораЗаписьЖурналаРегистрации без вывода пользователю

Часто задаваемые вопросы

Почему сообщение из серверной процедуры не видно пользователю?

Чаще всего процедура выполняется в фоновом задании — его сообщения не попадают в панель автоматически. Заберите их через ПолучитьСообщенияПользователю(Истина) на клиенте и выведите повторно, либо используйте механизм длительных операций БСП, который делает это сам.

Как привязать сообщение к строке табличной части?

В свойстве Поле укажите путь с индексом строки, например "Товары[2].Количество" (индексация с нуля). Тогда двойной щелчок по сообщению активирует конкретную ячейку. Для формы документа путь обычно начинается с "Объект." — проверьте точный путь к данным в дереве реквизитов формы.

Можно ли использовать Предупреждение() вместо ПоказатьПредупреждение()?

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

Чем отличается КлючДанных от УстановитьДанные?

КлючДанных — это ссылка на объект информационной базы: по ней платформа может открыть объект из панели сообщений, даже если форма закрыта. УстановитьДанные связывает сообщение с редактируемыми данными конкретной формы, что обеспечивает навигацию к полю внутри открытой формы. Для документа в форме обычно используют оба механизма вместе.

Как вывести сообщение об ошибке и прервать выполнение?

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

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

Типичная причина — проверка выполняется и в ОбработкаПроверкиЗаполнения, и в ОбработкаПроведения, либо одна и та же процедура вызывается дважды (например, из подписки на событие и из модуля объекта). Оставьте проверку в одном месте и убедитесь, что подписки на события не дублируют логику модуля.

Итог

Что важно запомнить

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