Как убрать служебные сообщения в 1С 8.3 программно
Содержание
Служебные сообщения в нижней панели окна убираются методом ОчиститьСообщения() — одной строкой на клиенте. Если очистить нужно не окно целиком, а чтобы сообщение исчезало вместе с формой, его привязывают к данным формы через объект СообщениеПользователю. Это два разных механизма, и путаница между ними — главная причина, почему сообщения в 1С «не очищаются» или, наоборот, пропадают раньше времени.
Разберём, как устроена система сообщений в 1С 8.3 (интерфейс «Такси»), чем отличается глобальный метод Сообщить() от объекта СообщениеПользователю, как очищать окно сообщений в управляемых формах и в циклах обработки, и какие приёмы помогают не накапливать мусор в панели.
Как устроена панель сообщений в 1С 8.3
Служебные сообщения показываются в отдельной панели внизу активного окна. Туда попадает всё, что выведено методом Сообщить() или через объект СообщениеПользователю. Панель накапливает строки до тех пор, пока её явно не очистят или не закроют окно, к которому привязаны сообщения.
Важно различать два канала информирования:
- 📋 Служебные сообщения — немодальная панель внизу. Не прерывают работу, пользователь может их проигнорировать.
- ⚠️ Модальные окна —
Предупреждение(),Вопрос(). Останавливают выполнение до ответа пользователя. К панели сообщений отношения не имеют и очисткой не управляются.
Очистка касается только первого канала — панели служебных сообщений. Модальное окно «очищается» само, как только пользователь нажал кнопку.
Панель сообщений появляется автоматически, когда в неё что-то выводят, и прячется, когда строк не осталось. У каждого открытого окна (форма документа, список, рабочий стол) своя панель — сообщения из формы документа не смешиваются с сообщениями формы списка. Это важно помнить: очистка и вывод всегда работают в рамках одного окна.
В толстом клиенте под обычным приложением поведение панели похоже, но весь современный код на управляемых формах работает так, как описано ниже. Дальше речь про управляемое приложение.
Метод ОчиститьСообщения(): убрать всё окно сразу
Глобальный метод ОчиститьСообщения() удаляет все строки из панели сообщений активного окна. Параметров у него нет — он всегда чистит панель целиком.
ОчиститьСообщения();
Вызывается на клиенте. Типичное место вызова — самое начало обработчика команды, перед тем как заново выводить результаты проверки:
&НаКлиенте
Процедура ПроверитьДокумент(Команда)
ОчиститьСообщения(); // убрали прошлый результат
РезультатПроверки = ПроверитьНаСервере();
КонецПроцедуры
Без этой строки каждое нажатие кнопки добавляет новую порцию строк к старым, и панель за несколько кликов превращается в кашу из дублей. Если сообщения в вашей обработке накапливаются при повторном запуске — почти всегда дело в том, что ОчиститьСообщения() не вызван в начале.
Метод ОчиститьСообщения() доступен и в серверном контексте управляемой формы. На сервере сообщения, выведенные за один серверный вызов, собираются в буфер и передаются на клиент в конце вызова разом. Если нужно отменить накопленные за текущий вызов строки до их отправки — ОчиститьСообщения() на сервере очищает этот буфер.
Сообщить() против объекта СообщениеПользователю
Вывести строку в панель можно двумя способами.
Глобальный метод Сообщить() — самый короткий:
Сообщить("Документ проверен");
Он прост, но у сообщения нет привязки к конкретному полю или объекту: нельзя кликнуть по тексту и перейти к проблемному реквизиту, и такое сообщение не исчезнет автоматически при закрытии формы. В типовых конфигурациях Сообщить() считается устаревшим — его оставляют для быстрых отладочных выводов, когда адресность и очистка не важны.
На практике это выливается в неудобство: вывели пользователю десяток ошибок через Сообщить(), а он не понимает, к какой строке документа какая относится, и не может перейти к ней одним кликом. Поэтому в боевом коде почти всегда применяют объект.
Объект СообщениеПользователю — полноценный способ. Он умеет привязываться к полю формы, к строке таблицы и к конкретному объекту базы:
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Заполните контрагента";
Сообщение.Поле = "Контрагент";
Сообщение.Сообщить();
При клике по такому сообщению 1С сама откроет нужную форму и установит курсор в поле Контрагент. Именно поэтому в прикладном коде предпочтителен этот объект, а не голый Сообщить().
Ключевые свойства объекта:
| Свойство | Назначение |
|---|---|
Текст | Текст сообщения |
Поле | Путь к реквизиту формы, куда поставить курсор |
ПутьКДанным | Путь к данным формы (обычно "Объект") |
КлючДанных | Ссылка на объект, к которому относится сообщение |
УникальныйКлюч | Строка, чтобы отличать однотипные сообщения |
Для строки табличной части путь в свойстве Поле указывают с индексом строки:
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Укажите количество";
Сообщение.Поле = СтрШаблон("Товары[%1].Количество", НомерСтроки - 1);
Сообщение.ПутьКДанным = "Объект";
Сообщение.Сообщить();
Индекс строки отсчитывается от нуля, поэтому для первой строки это Товары[0]. Если спутать номер строки с индексом, курсор встанет не туда.
Очистка сообщений в управляемых формах
В управляемой форме привязка сообщения к данным решает задачу очистки сама собой. Когда сообщение привязано к форме через ПутьКДанным и КлючДанных, оно живёт ровно столько, сколько открыта форма: закрыли документ — сообщения исчезли вместе с окном. Отдельно их чистить не нужно.
Привязка к объекту выглядит так:
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Договор просрочен";
Сообщение.Поле = "Договор";
Сообщение.ПутьКДанным = "Объект";
Сообщение.КлючДанных = Объект.Ссылка;
Сообщение.Сообщить();
Если же вам нужно очистить панель принудительно, не закрывая форму (например, перед повторной проверкой), используйте ОчиститьСообщения() на клиенте. Он уберёт все строки активного окна независимо от того, привязаны они к данным или нет.
ОчиститьСообщения() чистит панель активного окна. Если сообщения выведены в одной форме, а метод вызван из другой, они не очистятся — это частая причина жалобы «вызываю очистку, а сообщения на месте».
Удалить из панели одно конкретное сообщение, оставив остальные, штатно нельзя: метод чистит окно целиком. Если нужна избирательность, стройте логику на привязке к форме — тогда ненужные сообщения уйдут вместе со своей формой, а не по отдельному вызову.
Как не копить сообщения в циклах и обработках
В обработках, где вы перебираете строки и выводите результат по каждой, панель забивается быстрее всего. Два правила держат её в порядке.
Чистите один раз — перед циклом, а не внутри. Если вызвать ОчиститьСообщения() в теле цикла, каждая новая строка будет стирать предыдущую, и в итоге останется только последнее сообщение. Очистка должна стоять до начала перебора:
&НаСервере
Процедура ПроверитьТоварыНаСервере()
ОчиститьСообщения();
Для Каждого Строка Из Объект.Товары Цикл
Если Строка.Количество = 0 Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = СтрШаблон("Строка %1: нулевое количество", Строка.НомерСтроки);
Сообщение.Поле = СтрШаблон("Товары[%1].Количество", Строка.НомерСтроки - 1);
Сообщение.ПутьКДанным = "Объект";
Сообщение.Сообщить();
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Здесь число подставляется в текст через СтрШаблон — так корректнее, чем склеивать строку с числом напрямую.
Привязывайте каждое сообщение к своей строке. Указав Поле с индексом строки, вы даёте пользователю кликабельный список ошибок: нажал на сообщение — курсор встал в проблемную ячейку. Это удобнее, чем пачка одинаковых строк без адреса.
В фоновом задании панели сообщений нет — показывать там нечего. Результат проверки из фонового задания возвращайте через параметры или служебные записи, а не через Сообщить(): до пользователя он не дойдёт.
Сообщения при проверке заполнения
Отдельно стоит механизм проверки заполнения — здесь очисткой сообщений управляет сама платформа, и это надо учитывать, чтобы не чистить лишнего руками.
Когда реквизит помечен свойством «Проверка заполнения: Выдавать ошибку», при проведении или записи 1С сама формирует сообщения по незаполненным полям и сама привязывает их к форме. При повторной попытке записи старые сообщения о заполнении платформа снимает и выводит заново — вручную ОчиститьСообщения() для них вызывать не нужно.
Свои проверки добавляют в обработчике ОбработкаПроверкиЗаполнения объекта. Там выводят СообщениеПользователю и исключают реквизит из списка проверяемых:
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
Если Сумма <= 0 Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Сумма должна быть больше нуля";
Сообщение.Поле = "Сумма";
Сообщение.ПутьКДанным = "Объект";
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
Сообщения, выведенные внутри ОбработкаПроверкиЗаполнения, подчиняются тому же циклу жизни, что и стандартные: платформа очищает их при следующей проверке. Поэтому мешать штатную проверку с ручным ОчиститьСообщения() не стоит — можно случайно стереть сообщения, которые система собиралась показать.
Дубли сообщений и УникальныйКлюч
Если один и тот же текст выводится из разных мест кода, в панели появляются дубли. Свойство УникальныйКлюч позволяет платформе понять, что это одно и то же сообщение, и не плодить копии:
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Не выбран склад";
Сообщение.Поле = "Склад";
Сообщение.УникальныйКлюч = "ПроверкаСклада";
Сообщение.Сообщить();
Ключ — произвольная строка. Главное, чтобы у логически одинаковых сообщений она совпадала, а у разных различалась. В связке с привязкой к полю это даёт чистую панель без повторов.
Если выводите список ошибок по строкам таблицы, делайте УникальныйКлюч разным для каждой строки — например, подставляйте в него номер строки через СтрШаблон. Иначе платформа посчитает их одинаковыми и покажет только одну.
Чем заменить сообщения: оповещения и статус
Иногда проблема не в очистке, а в том, что панель сообщений — неудачный инструмент для задачи. Есть более подходящие способы информировать пользователя, которые не нужно чистить вручную.
- 🔔 Всплывающее оповещение —
ПоказатьОповещениеПользователя(). Короткое уведомление в правом нижнем углу, которое само гаснет через несколько секунд. Годится для «Записано», «Отправлено».
ПоказатьОповещениеПользователя(
"Проведено",
,
"Документ успешно проведён",
БиблиотекаКартинок.Информация);
- ⏳ Статусная строка —
Состояние(). Показывает ход длительной операции. Пустой вызовСостояние()убирает текст.
Состояние("Обработка строк...");
// ... длительная операция ...
Состояние(); // убрать индикатор
- 💬 Модальный вопрос или предупреждение — когда реакция пользователя обязательна. В веб-клиенте используйте немодальные
ПоказатьПредупреждение()иПоказатьВопрос()с обработчиком оповещения: синхронныеПредупреждение()иВопрос()в веб-клиенте без включённого режима модальности вызовут ошибку.
Выбор способа по ситуации: разовый факт — оповещение, ход операции — статус, список ошибок с переходом к полям — СообщениеПользователю в панели, обязательное действие — модальное окно.
Такой подход заодно снимает проблему очистки: оповещение и статус не копятся в панели, а значит, и чистить там нечего. Панель сообщений оставляют для того, для чего она создана — для списка проблем, по которым пользователь должен пройтись и что-то исправить.
Типичные ошибки и как их чинить
Частые вопросы
Можно ли удалить из панели только одно сообщение, не трогая остальные?
ОчиститьСообщения() чистит окно целиком. Избирательность достигается привязкой сообщений к форме — ненужные уходят вместе со своим окном.Почему сообщения не исчезают после закрытия формы?
ПутьКДанным/КлючДанных) или через Сообщить(). Привяжите сообщение к объекту формы — тогда оно закроется вместе с ней.Как очистить сообщения с сервера?
ОчиститьСообщения() в серверной процедуре управляемой формы до вывода новых строк. Он очистит буфер сообщений текущего серверного вызова перед передачей на клиент.В чём разница между Сообщить() и СообщениеПользователю?
Сообщить() просто выводит текст без адреса. СообщениеПользователю умеет привязываться к полю, строке таблицы и объекту, поэтому по нему можно кликнуть и перейти к проблемному реквизиту. В прикладном коде используют объект.