Как вывести сообщение пользователю сразу после открытия обычной формы в 1С 8.3

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

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

Анализ проблемы: почему стандартные методы не работают в ПриОткрытии

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


Процедура ПриОткрытии()
    Предупреждение("Внимание! Проверьте данные.");
КонецПроцедуры

Система приостанавливает выполнение потока интерфейса на строке с методом Предупреждение. Поскольку модальное окно блокирует выполнение кода, платформа «замирает» в ожидании реакции пользователя. При этом сама основная форма всё еще находится в очереди на отрисовку. Только после того, как пользователь нажмет «ОК», процедура завершится, и 1С продолжит цикл отрисовки, наконец-то показав форму. Наша задача — «разорвать» эту последовательность и заставить систему сначала показать форму, а затем вывести сообщение.

Основное решение: использование обработчика ожидания

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

Разберем по шагам, как это реализовать:

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

Посмотрим на пример кода:


Процедура ПриОткрытии()
    // Подключаем процедуру с задержкой в 0.1 секунды.
    // Этого времени достаточно, чтобы форма успела появиться на экране.
    ПодключитьОбработчикОжидания("ВывестиСообщениеПослеОткрытия", 0.1, Истина);
КонецПроцедуры

Процедура ВывестиСообщениеПослеОткрытия() Экспорт
    // Здесь мы пишем код, который должен сработать после появления формы
    Предупреждение("Теперь форма открыта, и это сообщение выведено поверх неё!");
КонецПроцедуры

В данном примере 0.1 — это интервал в секундах. Это минимально возможное значение, которое воспринимается пользователем как мгновенное действие, но технически оно позволяет платформе завершить цикл отрисовки Обычной формы.

Безопасность выполнения: проверка состояния формы

Проанализируем ситуацию глубже. Что произойдет, если пользователь закроет форму быстрее, чем через 0.1 секунды (например, сработает какой-то программный отказ)? В этом случае процедура ВывестиСообщениеПослеОткрытия может вызвать ошибку, так как контекст формы уже будет уничтожен. Чтобы избежать аварийного завершения работы, рекомендуется добавить проверку состояния формы.

Модернизируем наш код:


Процедура ВывестиСообщениеПослеОткрытия() Экспорт
    // Проверяем, открыта ли форма на данный момент
    Если ЭтаФорма.Открыта() Тогда
        ПоказатьПредупреждение(, "Проверка данных успешно завершена!");
    КонецЕсли;
КонецПроцедуры

Использование свойства ЭтаФорма.Открыта() гарантирует, что мы не пытаемся обратиться к несуществующему интерфейсному объекту.

Альтернативный подход: Немодальные оповещения

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

Преимущество этого метода заключается в том, что он не блокирует выполнение кода и отрисовку интерфейса. Окно оповещения всплывает в углу экрана и не требует от пользователя нажатия кнопки «ОК».


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

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

Особенности для платформы 8.3 и режима модальности

Рассмотрим ситуацию, когда в настройках конфигурации установлено свойство «Режим использования модальности» в значение «Не использовать». Это часто встречается при переходе с обычных форм на управляемые или при обновлении платформенных стандартов.

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


Процедура ВывестиСообщениеПослеОткрытия() Экспорт
    Если ЭтаФорма.Открыта() Тогда
        ОписаниеОповещения = Новый ОписаниеОповещения("ПослеЗакрытияПредупреждения", ЭтаФорма);
        ПоказатьПредупреждение(ОписаниеОповещения, "Важное сообщение!");
    КонецЕсли;
КонецПроцедуры

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

Использование события ОбновлениеОтображения

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

  1. Объявляем переменную в начале модуля: Перем СообщениеПоказано;
  2. В процедуре ПриОткрытии устанавливаем СообщениеПоказано = Ложь;
  3. В процедуре ОбновлениеОтображения проверяем флаг.

Процедура ОбновлениеОтображения()
    Если Не СообщениеПоказано Тогда
        СообщениеПоказано = Истина;
        Сообщить("Форма полностью визуализирована!");
    КонецЕсли;
КонецПроцедуры

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

Резюме

Мы проанализировали несколько способов вывода сообщений после открытия формы. Подведем итоги:

Выбирайте подходящий метод в зависимости от ваших задач и настроек конфигурации. Теперь ваши пользователи будут видеть информационные окна вовремя и в правильном контексте!

← На главную