Сообщение пользователю в 1С: Сообщить, предупреждение, оповещение

· 8 мин

Содержание

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

Код ниже написан под управляемые формы платформы 8.3 с интерфейсом «Такси». Старые синхронные вызовы вроде Предупреждение() и Вопрос() остались для совместимости, в новой разработке их не применяют: они останавливают выполнение кода и не годятся для веб-клиента.

Сообщить: простая строка в окне сообщений

Самый короткий вариант. Строка появляется в панели сообщений внизу окна, ничего не блокируется:

Сообщить("Документ проведён");

Вторым параметром задают статус, от него зависит значок рядом с текстом:

Сообщить("Остаток меньше минимального", СтатусСообщения.Внимание);

Доступные значения перечисления СтатусСообщения:

  • ℹ️ Обычное — без значка, по умолчанию;
  • ❗ Важное — значок восклицания;
  • ⚠️ Внимание — предупреждающий значок;
  • 🔴 ОченьВажное — значок ошибки;
  • 💬 Информация — информационный значок.

Сообщить работает и на клиенте, и на сервере. Сообщение, выданное из серверной процедуры, дойдёт до пользователя, когда сервер вернёт управление клиенту.

Строки собирайте через СтрШаблон, а не склейкой: СтрШаблон("Не заполнен контрагент в строке %1", НомерСтроки). Число в шаблон подставится само, без Формат.

Минус у метода один: сообщение легко не заметить. Если пользователь работает в форме на весь экран , панель сообщений может быть свёрнута, и строка пройдёт мимо.

СообщениеПользователю: ошибка у конкретного поля

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

Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Укажите контрагента";
Сообщение.Поле = "Объект.Контрагент";
Сообщение.УстановитьДанные(Объект);
Сообщение.Сообщить();

Для реквизитов формы, а не объекта, в Поле пишут имя реквизита без префикса. Если сообщение относится к строке табличной части, путь строится так: Объект.Товары[0].Количество. Индекс в квадратных скобках начинается с нуля, поэтому для третьей строки пишут [2].

Свойство КлючДанных связывает сообщение с объектом, а ПутьКДанным — с конкретным реквизитом. Обычно хватает Поле и УстановитьДанные.

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

ПоказатьПредупреждение: окно с кнопкой ОК

Когда нужно, чтобы пользователь обязательно прочитал текст, выводят модальное по смыслу окно. В управляемых формах оно устроено асинхронно: код после вызова не ждёт закрытия окна.

&НаКлиенте
Процедура ПроверитьОстатки(Команда)
    ПоказатьПредупреждение(, "На складе нет нужного количества товара", 10, "Проверка остатков");
КонецПроцедуры

Параметры по порядку:

  1. Описание оповещения — что выполнить после закрытия. Если ничего не нужно, параметр пропускают, как в примере.
  2. Текст сообщения.
  3. Таймаут в секундах. Через 10 секунд окно закроется само. Ноль или пропуск — ждать нажатия.
  4. Заголовок окна.

Если после закрытия нужно продолжить работу, создают описание оповещения:

&НаКлиенте
Процедура Продолжить(Команда)
    Обработчик = Новый ОписаниеОповещения("ПослеПредупреждения", ЭтотОбъект);
    ПоказатьПредупреждение(Обработчик, "Данные будут выгружены в файл");
КонецПроцедуры

&НаКлиенте
Процедура ПослеПредупреждения(Результат, ДопПараметры) Экспорт
    // здесь продолжается логика
КонецПроцедуры

Код, который должен выполниться после закрытия окна, нельзя ставить следом за вызовом — он сработает сразу, не дожидаясь пользователя. Только в процедуре-обработчике.

ПоказатьВопрос: когда нужен ответ «Да» или «Нет»

Предупреждение не даёт выбора. Если от ответа зависит дальнейшее действие, используют вопрос:

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

&НаКлиенте
Процедура ПослеВопроса(Результат, ДопПараметры) Экспорт
    Если Результат = КодВозвратаДиалога.Да Тогда
        Объект.Товары.Очистить();
    КонецЕсли;
КонецПроцедуры

Режимы диалога перечислены в РежимДиалогаВопрос: ОК, ОКОтмена, ДаНет, ДаНетОтмена, ПовторитьОтмена, ПрерватьПовторитьПропустить. В обработчик приходит значение из КодВозвратаДиалога.

Четвёртым и следующими параметрами можно задать таймаут, кнопку по умолчанию и заголовок. Для вопросов с подтверждением опасных действий кнопку по умолчанию лучше ставить на безопасный вариант (КодВозвратаДиалога.Нет), чтобы случайное нажатие Enter ничего не удалило.

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

Если нужно сообщить о результате, но не отвлекать, подходит всплывающее оповещение. Оно появляется в углу экрана, через несколько секунд исчезает и ничего не требует:

ПоказатьОповещениеПользователя(
    "Выгрузка завершена",
    ,
    "Файл сохранён в указанную папку");

Параметры: заголовок, навигационная ссылка (куда перейти по щелчку), пояснение, картинка, статус и идентификатор.

Навигационная ссылка превращает оповещение в быстрый переход к созданному документу:

ПоказатьОповещениеПользователя(
    "Создан документ",
    ПолучитьНавигационнуюСсылку(НовыйДокумент),
    Строка(НовыйДокумент));

Здесь НовыйДокумент — ссылка на созданный объект. Пользователь щёлкает по плашке и открывает документ.

Оповещение подходит для успешных результатов: «записано», «отправлено», «загружено». Ошибки в нём показывать не стоит — плашка исчезнет раньше, чем её прочитают.

Сравнение способов вывода сообщений

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

Если замечаний несколько, не выводите по окну на каждое. Соберите их в цикле через Сообщить и в конце покажите одно предупреждение: «Найдено 5 замечаний, смотрите окно сообщений».

Пример: проверка заполнения перед записью

Типовая задача — не дать записать документ без обязательных данных и объяснить причину. Проверку делают в обработчике ПередЗаписью на сервере или в ОбработкаПроверкиЗаполнения:

Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    Для Каждого Строка Из Товары Цикл
        Если Строка.Количество <= 0 Тогда
            Сообщение = Новый СообщениеПользователю;
            Сообщение.Текст = СтрШаблон("В строке %1 не указано количество", Строка.НомерСтроки);
            Сообщение.Поле = СтрШаблон("Товары[%1].Количество", Строка.НомерСтроки - 1);
            Сообщение.УстановитьДанные(ЭтотОбъект);
            Сообщение.Сообщить();
            Отказ = Истина;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Что здесь важно:

  • 🔢 НомерСтроки начинается с единицы, а индекс в пути поля — с нуля, поэтому вычитаем единицу. Для пятой строки получится Товары[4].Количество.
  • 🚫 Отказ = Истина прерывает запись. Без него сообщение появится, а документ всё равно сохранится.
  • 📋 Цикл не останавливается на первой ошибке: пользователь увидит все проблемные строки сразу, а не будет исправлять по одной.

Как выбрать способ

Что должно произойти после сообщения?

Как писать тексты сообщений

Хороший текст отвечает на три вопроса: что случилось, где и что делать. Сравните:

  • ❌ «Ошибка заполнения»;
  • ✅ «В строке 3 не указана номенклатура. Выберите товар из справочника».

Несколько простых правил:

  • 📝 называйте поле или строку, где проблема, и по возможности значение;
  • 🎯 один текст — одна проблема, не склеивайте пять замечаний в одну фразу;
  • 🧾 не показывайте пользователю технические тексты ошибок платформы: их пишут в журнал регистрации, а человеку выводят понятное объяснение;
  • 🔤 не используйте капслок и восклицательные знаки, статус уже передаёт важность.

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

Сервер, фоновые задания и долгие операции

Что показывать в долгих операциях

Пока выполняется долгая обработка, пользователь должен видеть, что программа не зависла. Для этого есть Состояние:

Состояние("Загрузка данных...");

Строка выводится в нижней части окна и пропадает, когда выполнение вернётся к пользователю. У Состояние есть дополнительные параметры: числовой индикатор прогресса и пояснение. Но в новых разработках долгие операции чаще переносят в фоновые задания, а ход выполнения отдают через ДлительныеОперации из Библиотеки стандартных подсистем.

Куда уходят сообщения из серверного кода и фоновых заданий

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

Сообщения = ПолучитьСообщенияПользователю(Истина);

Параметр Истина очищает накопленный буфер, чтобы сообщения не показались дважды. Работает это в клиентском контексте или внутри серверной процедуры, которая вызвана из формы.

Для регламентных заданий окно сообщений ничего не даёт: пользователя нет. Для них пишут в журнал регистрации:

ЗаписьЖурналаРегистрации(
    "ВыгрузкаДанных",
    УровеньЖурналаРегистрации.Ошибка,
    ,
    ,
    ОписаниеОшибки());

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

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

Окно сообщений хранит строки только до закрытия сеанса. Если замечания нужно сохранить, есть три пути:

  • 📝 записать в журнал регистрации, как показано выше;
  • 📄 вывести в табличный документ и показать его пользователю как отчёт;
  • 🗄️ записать в регистр сведений с датой, пользователем и текстом.

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

Типичные ошибки и отладка

Частые ошибки при выводе

Код после ПоказатьВопрос срабатывает до ответа. Следующая строка выполняется сразу. Всё, что зависит от ответа, переносят в процедуру-обработчик.

В обработчике нет слова Экспорт. Процедура, на которую ссылается ОписаниеОповещения, должна быть экспортной, иначе платформа её не вызовет.

Сообщение с длинным текстом обрезается. В панели сообщений полезно держать короткие фразы. Подробности лучше вынести в предупреждение или отчёт.

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

Отладка: сообщение не появляется

Бывает, что код написан верно, а на экране пусто, встречается чаще, чем кажется.

Если вызов написан, а текста на экране нет, проверьте по порядку:

  1. Вызов вообще выполняется: поставьте точку останова в конфигураторе на строке с Сообщить.
  2. Не выведена ли панель сообщений за границу окна. Её можно растянуть мышью.
  3. Не очищается ли панель сразу же: некоторые процедуры закрывают форму или переоткрывают её после вывода.
  4. Не вызван ли метод в серверном коде, который выполняется как фоновое задание или регламентное задание. В этом случае пользователь сообщений не получит.
  5. Не стоит ли перед сообщением условие, которое всегда ложно, например сравнение со строкой без учёта регистра.

Во время отладки полезно временно писать в сообщения значения переменных: Сообщить("Контрагент = " + Строка(Контрагент)). Когда проблема найдена, эти строки удаляют, чтобы пользователи не видели служебных данных.

Частые вопросы

Чем отличается Сообщить от Предупреждение?
Сообщить пишет строку в панель сообщений и не мешает работе. Предупреждение открывает окно, которое нужно закрыть.
Можно ли вывести сообщение с красным значком ошибки?
Да. Вторым параметром Сообщить передайте СтатусСообщения.ОченьВажное.
Как подсветить конкретное поле формы?
Используйте объект СообщениеПользователю и задайте свойство Поле с путём к реквизиту, например Объект.Контрагент.
Как остановить проведение документа с сообщением?
В обработчике проведения выведите текст через Сообщить, затем установите Отказ = Истина. Документ не проведётся, а пользователь увидит причину.
Почему сообщение из фонового задания не появилось?
Фоновое задание выполняется отдельно от формы. Сообщения нужно забрать через ПолучитьСообщенияПользователю или передать результат другим способом.