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