Как вернуть фокус и работу стрелок в форме подбора УПП на платформе 8.3.27

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

Переход на новые релизы платформы 1С часто преподносит сюрпризы, особенно когда речь идет о поддержке «классики», такой как Управление производственным предприятием (УПП). Одной из наиболее острых проблем в ветке 8.3.27.* стала потеря фокуса в обычных формах (Thick Client) после выполнения интерактивных действий. В частности, в форме подбора товаров после выбора позиции и закрытия модального окна (или окна ввода количества) фокус «улетает», и пользователь больше не может перемещаться по списку стрелками или переходить между полями клавишей Tab. Рассмотрим подробно, почему это происходит и как мы можем исправить эту ситуацию программно.

Анализируем причину возникновения ошибки

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

Данная проблема официально признана ошибкой платформы и проявляется в конфигурациях с режимом совместимости ниже 8.3.24, работающих на ядре 8.3.27. Поскольку УПП 1.3 является конфигурацией на обычных формах, она попадает в зону риска в первую очередь.

Решение №1: Программное «передергивание» фокуса

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


// В процедуре ОбработкаВыбора или в месте завершения подбора
текАктивныйЭлемент = ЭтаФорма.ТекущийЭлемент;
// Переносим фокус на любой другой элемент, например, вспомогательную кнопку
ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.кнСправка; 
// Возвращаем фокус на исходный элемент списка или поле ввода
ЭтаФорма.ТекущийЭлемент = текАктивныйЭлемент;

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

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

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

Создадим вспомогательную процедуру в модуле формы:


Процедура ВосстановитьФокусПослеПодбора() Экспорт
    Если ТекущийЭлемент <> Неопределено Тогда
        ЭтаФорма.Активизировать();
        ЭтаФорма.ТекущийЭлемент = ТекущийЭлемент;
    КонецЕсли;
КонецПроцедуры

А в месте, где происходит выбор товара (например, после открытия формы ввода количества), вызовем её с минимальной задержкой:

ПодключитьОбработчикОжидания("ВосстановитьФокусПослеПодбора", 0.1, Истина);

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

Решение №3: Имитация системных клавиш через COM-объект

Если штатные методы 1С не помогают, мы можем пойти по пути «обмана» операционной системы. Известно, что нажатие клавиши Alt или сочетания Alt+Tab часто возвращает фокус окну. Мы можем автоматизировать это с помощью WScript.Shell. Этот метод может пригодиться, когда в форму интегрированы сложные внешние компоненты, такие как подсказки Dadata для ввода адресов в УПП.

Посмотрим на пример реализации такого костыля:


Попытка
    wsh = Новый COMОбъект("WScript.Shell");
    // Симулируем нажатие клавиши ALT
    wsh.SendKeys("%"); 
    // Симулируем нажатие ESC для закрытия системного меню, если оно активировалось
    wsh.SendKeys("{ESC}");
Исключение
    // Обработка случая, если COM-объект недоступен (например, в Linux-клиенте)
    ЗаписьЖурналаРегистрации("Ошибка восстановления фокуса", УровеньЖурналаРегистрации.Предупреждение);
КонецПопытки;

Разберем этот подход. Метод SendKeys отправляет нажатия клавиш непосредственно в очередь сообщений Windows. Несмотря на то что это решение считается «грязным», в условиях блокирующих багов платформы оно часто оказывается единственным рабочим вариантом для УПП.

Решение №4: Настройка интерфейса (без программирования)

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

  1. Перейдите в меню Сервис — Параметры.
  2. Вкладка Интерфейс.
  3. Переключите режим с «Формы в закладках» на «Каскад» (отдельные окна).

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

Итоги и рекомендации

Выясним, какой метод лучше выбрать. Если вы имеете возможность редактировать код подбора, мы рекомендуем использовать Решение №2 (Обработчик ожидания), так как оно наиболее стабильно и не зависит от наличия внешних библиотек в системе. В дополнение к исправлению фокуса, вы можете внедрить групповую обработку изображений, чтобы сделать визуальную работу с номенклатурой более удобной. Если же вы столкнулись с ситуацией, когда фокус теряется в типовом механизме, который нельзя менять — попробуйте Решение №4 с настройкой интерфейса.

Не забывайте, что работа с объектами ЭлементыФормы в обычном приложении требует внимательности к тому, какой именно элемент должен быть активным в данный момент. Всегда проверяйте, что ЭтаФорма.ТекущийЭлемент указывает на список товаров (табличное поле), прежде чем завершать процедуру выбора.

← На главную