Как предотвратить перехват фокуса и активации окна при работе обработчика ожидания в 1С

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

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

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

Причина проблемы: почему фокус "улетает"?

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

Решение через проверку доступности ввода

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

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

Рассмотрим правильную реализацию обработчика ожидания:


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    // Подключаем обработчик с интервалом 15 секунд
    ПодключитьОбработчикОжидания("ОбновитьЗаявки", 15, Ложь);
КонецПроцедуры

&НаКлиенте
Процедура ОбновитьЗаявки()
    // Проверяем, не занят ли пользователь другим окном
    Если ВводДоступен() Тогда
        ОбновитьДанныеНаСервере();
    Иначе
        // Если окно не активно, ничего не делаем, 
        // чтобы не прерывать работу пользователя в другом окне
        Возврат;
    КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ОбновитьДанныеНаСервере()
    // Логика получения данных и записи в реквизит формы
    НовыйТекст = ПолучитьСписокАктивныхЗаявок();
    Если ЭтаФорма.ТекстЗаявок <> НовыйТекст Тогда
        ЭтаФорма.ТекстЗаявок = НовыйТекст;
    КонецЕсли;
КонецПроцедуры

Оптимизация: избегаем лишних обновлений интерфейса

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

Использование фоновых заданий для подготовки данных

Для конфигураций, работающих на управляемых формах (УТ 11, ERP, КА), более современным подходом является вынос тяжелой логики сбора данных в фоновое задание. Это позволяет интерфейсу оставаться полностью "отзывчивым", так как основной поток клиента не блокируется на время выполнения серверного запроса.

Схема реализации выглядит следующим образом:

  1. Обработчик ожидания проверяет, не запущено ли уже фоновое задание.
  2. Если задание не запущено — запускаем его на сервере.
  3. В следующем цикле обработчика проверяем состояние задания через ФоновыеЗадания.НайтиПоУникальномуИдентификатору.
  4. Если задание завершено успешно, забираем результат из ВременноеХранилище и обновляем форму.

Механизм оповещений как альтернатива опросу

Вместо того чтобы "терзать" базу данных запросами каждые 15 секунд, выясним, можно ли использовать событийную модель. Если данные в справочнике «Заявки» меняются не так часто, логично использовать метод Оповестить() при записи новой заявки. Форма списка сделок поймает это событие в обработчике ОбработкаОповещения и обновит данные только тогда, когда это действительно необходимо.

Пример кода в модуле формы справочника «Заявки»:


&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
    Оповестить("ОбновленыЗаявкиКлиентов", ПараметрыЗаписи, ЭтотОбъект);
КонецПроцедуры

И ответная часть в форме списка «Сделки»:


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

Работа в условиях модальных окон

Посмотрим на ситуацию, когда у пользователя открыто модальное окно (например, предупреждение системы). В этом случае ВводДоступен() гарантированно вернет Ложь, что спасет нас от ошибок. Дополнительно рекомендуется проверять свойство ЭтаФорма.Открыта(), так как обработчик ожидания может продолжать попытки вызова даже после того, как пользователь закрыл основную форму, если он не был явно отключен методом ОтключитьОбработчикОжидания.

Использование Библиотеки стандартных подсистем (БСП)

Если ваша конфигурация использует БСП, рекомендуем обратить внимание на подсистему "Длительные операции". В ней реализованы штатные механизмы для выполнения фоновых задач с индикацией прогресса или без неё. Использование ДлительныеОперации.ЗапуститьВыполнениеВФоне позволяет корректно обрабатывать состояние формы и не мешать работе пользователя, соблюдая все стандарты разработки «1С».

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

← На главную