При переходе на новые версии платформы 1С:Предприятие 8.3 (начиная с релизов 8.3.25.x и 8.3.26.x) пользователи конфигураций на обычных формах, таких как УТ 10.3 (где часто дорабатывается функционал, например, добавляется счет на оплату с QR кодом (поможет печать счета с QR-кодом для УТ 10.3)), УПП 1.3 (в которой актуальна настройка современных сервисов вроде подсказок Dadata или заполнения по ИНН) или БП 1.6, часто сталкиваются с неприятным поведением интерфейса. Самая распространенная проблема — потеря фокуса ввода после закрытия модальных окон.
Типичный сценарий: кладовщик или менеджер открывает подбор номенклатуры в документе "Реализация товаров и услуг" (для этого подойдёт расширение формы подбора номенклатуры для 1С), выбирает товар, вводит количество в появившемся модальном окне, нажимает "ОК", и... фокус пропадает. Вместо того чтобы продолжить выбор товаров с клавиатуры, сотруднику приходится тянуться к мыши, чтобы снова активировать список. Рассмотрим подробнее, почему это происходит и как мы можем исправить ситуацию.
Проанализируем техническую сторону вопроса. Данная проблема не является ошибкой в коде конфигурации — это изменение в поведении самого движка платформы 1С. В последних релизах разработчики 1С изменили механизмы взаимодействия окон приложения с операционной системой Windows (в частности, обработку системных сообщений WM_SETFOCUS). В «управляемом» интерфейсе это проходит практически незаметно, но в «обычных» формах (ОФ) возникла деградация.
Когда закрывается модальное окно (например, форма ввода количества), операционная система должна вернуть управление «родителю». Однако из-за оптимизаций в новых версиях платформы 1С, родительская форма не всегда успевает корректно перехватить фокус. Интересно, что в режиме отладки через конфигуратор проблема может не воспроизводиться. Разберем почему: когда срабатывает точка останова, фокус принудительно передается конфигуратору, а при продолжении выполнения Windows заново пересчитывает активные окна, что «магическим» образом возвращает фокус на место. В реальной же работе без пауз выполнение кода происходит слишком быстро для того, чтобы системные механизмы отрисовки успели отработать корректно.
Если мы не можем откатить платформу на более старую версию, нам придется внести небольшие изменения в код обработки подбора. Рассмотрим наиболее эффективный метод — принудительную активацию нужного элемента формы сразу после закрытия модального окна.
Обычно вызов формы ввода количества выглядит следующим образом:
СтруктураПараметров = ФормаВводПараметров.ОткрытьМодально();
После этой строки нам необходимо «разбудить» родительскую форму. Простого вызова метода Активизировать() для всей формы часто бывает недостаточно. Опытным путем установлено, что лучше сначала явно указать, какой элемент управления должен стать активным. Посмотрим на пример модифицированного кода:
// Открываем форму ввода количества или характеристик модально
РезультатВыбора = ФормаВвода.ОткрытьМодально();
// Возвращаем фокус программно
ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.СписокНоменклатуры;
ЭтаФорма.Активизировать();
Важный нюанс: если вы используете обработку подбора в типовой УТ 10.3 (даже если вы уже оптимизировали базу и настроили хранение картинок номенклатуры на диске), искать место вызова нужно в процедурах ОбработкаВыбора или в специализированных процедурах самой формы подбора (например, СписокНоменклатурыВыбор). Если в форме подбора используется несколько закладок или списков, убедитесь, что вы активируете именно тот элемент (например, ТабличноеПоле), с которым пользователь работает в данный момент. Для работы в «старых» конфигурациях есть поддержка налогового законодательства в УТ 10.3.
Иногда даже прямая команда Активизировать() игнорируется платформой, так как она вызывается в тот микромомент, когда модальное окно еще не до конца «уничтожено» в памяти. В этом случае мы можем применить небольшую задержку. Рассмотрим, как реализовать это правильно:
// В месте, где закрывается модальное окно
ПодключитьОбработчикОжидания("ПринудительныйВозвратФокуса", 0.1, Истина);
// Сама процедура
Процедура ПринудительныйВозвратФокуса() Экспорт
ЭтаФорма.Активизировать();
Если ЭлементыФормы.Найти("Список") <> Неопределено Тогда
ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.Список;
КонецЕсли;
КонецПроцедуры
Использование интервала 0.1 секунды обычно достаточно для того, чтобы стек событий Windows очистился, и форма смогла принять фокус ввода.
Если конфигураций много и править код в каждой из них нецелесообразно (или база находится на поддержке), проанализируем инфраструктурный вариант. Платформа 1С позволяет запускать на одном физическом сервере несколько разных версий служб 1C:Enterprise Server.
Рассмотрим по шагам, как это реализовать:
1540, а вторая — на 1640.При таком подходе клиентское приложение (толстый клиент) будет запускаться именно той версии, которая соответствует серверной. Баг с фокусом в версии 8.3.10 отсутствует, и пользователи смогут продолжать работать в привычном режиме без доработки конфигурации.
Существуют также внешние факторы, влияющие на поведение окон в обычных формах на новых движках. Проанализируем их:
High DPI settings), передав управление масштабированием приложению./ForceStandardVCL. Хотя он предназначен для управления отрисовкой элементов управления, иногда он меняет логику взаимодействия окон с рабочим столом.ОткрытьМодально() на ОткрытьФорму() с использованием ОписаниеОповещения полностью решает проблему фокуса, так как окна перестают блокировать основной поток. Однако в старых конфигурациях это потребует переработки огромного количества кода.Подводя итог, отметим: если ваша компания находится в процессе перехода с УТ 10.3 на УТ 11 (поможет перенос данных из УТ 10.3 в УТ 11.5), и старая база нужна лишь временно, наиболее быстрым и дешевым решением будет комбинация программной активации элемента ТекущийЭлемент и настройка корректного масштабирования в ОС. Это позволит сотрудникам сохранить темп работы до полного переезда в новую систему.