При переходе с платформы 1С:Предприятие 8.2 на версию 8.3 многие разработчики и пользователи сталкиваются с досадным изменением в поведении интерфейса обычных форм. Суть проблемы заключается в том, что после выбора даты в поле ввода или завершения ввода периода нажатие клавиши Enter или Tab не переводит фокус на следующий элемент формы с первого раза. Пользователю приходится нажимать клавишу дважды: первый раз для подтверждения выбора в самом элементе, и второй раз — для перехода к следующему реквизиту. В версии 8.2 этот процесс происходил за одно нажатие, что значительно ускоряло работу оператора.
В рамках данной статьи мы детально разберем, почему это происходит, проанализируем технические причины такого поведения платформы и рассмотрим способы программного исправления ситуации, если обновление платформы не помогает.
Давайте проанализируем ситуацию с технической точки зрения. В платформе 8.3 для обычных форм был существенно переработан механизм обработки событий клавиатуры и взаимодействия с системными окнами (такими как выпадающий календарь).
Выясним основную причину: в версии 8.2 событие закрытия календаря и событие «Завершение ввода» в поле были тесно связаны. Одно нажатие клавиши Enter при открытом календаре закрывало его и одновременно сигнализировало полю ввода о необходимости завершить редактирование. В 8.3 эти события зачастую разделены архитектурно. Платформа интерпретирует первое нажатие Enter только как выбор значения в интерактивном окне (календаре), при этом фокус остается в поле ввода, которое все еще находится в режиме редактирования. Только второе нажатие воспринимается как команда к перемещению фокуса далее по порядку обхода.
Также стоит отметить влияние параметра Режим совместимости. Если ваша конфигурация запущена на 8.3, но в свойствах корня конфигурации установлен режим совместимости с версией 8.2.16, старое поведение может сохраняться. Однако при отключении режима совместимости или его повышении до 8.3.х «проблема двойного клика» проявляется в полной мере.
Прежде чем приступать к изменению программного кода, рассмотрим системные возможности решения. Как показывает практика эксплуатации различных релизов, это поведение признавалось разработчиками 1С то ошибкой, то особенностью реализации.
8.2.16. Это может восстановить привычную работу интерфейса, но лишит вас возможности использовать новые методы платформы 8.3.Если изменить настройки платформы невозможно, мы можем прибегнуть к программному обходу проблемы. Наша задача — заставить систему поверить, что пользователь нажал клавишу перехода сразу после выбора значения. Для этого идеально подходит использование объекта WScript.Shell.
Рассмотрим пример реализации. Предположим, у нас есть поле ввода ДатаНачала. Мы можем добавить код в обработчик события ПриИзменении. Разберем по шагам, как это сделать:
1. Откройте форму в конфигураторе.
2. Выберите нужное поле ввода и создайте обработчик события ПриИзменении.
3. Вставьте следующий код:
Процедура ДатаНачалаПриИзменении(Элемент)
// Создаем объект для работы с системными командами Windows
Попытка
WshShell = Новый COMОбъект("WScript.Shell");
// Имитируем нажатие клавиши TAB для перехода на следующее поле
WshShell.SendKeys("{TAB}");
Исключение
// Если создание объекта запрещено настройками безопасности
// или ОС, ошибка будет проигнорирована
КонецПопытки;
КонецПроцедуры
Важный нюанс: метод SendKeys отправляет команду в активное окно Windows. Поскольку в момент выполнения кода 1С фокус находится именно на поле ввода, команда {TAB} будет интерпретирована как переход к следующему элементу в порядке обхода формы.
Иногда использование SendKeys может быть нежелательным из-за ограничений прав доступа или работы в терминальном сервере. В таком случае проанализируем возможность использования штатных методов управления фокусом 1С.
Посмотрим на пример использования события ОкончаниеВводаТекста. Хотя оно чаще применяется для текстовых полей, для полей с датой оно также может срабатывать при ручном вводе. Однако более надежным для обычных форм является принудительная установка текущего элемента.
Рассмотрим программный код, который можно разместить в событии ПриИзменении:
Процедура ДатаКонцаПриИзменении(Элемент)
// Пытаемся программно перевести фокус на следующий элемент
// В обычных формах это делается через свойство ТекущийЭлемент формы
СледующийЭлемент = Форма.ЭлементыФормы.Найти("КнопкаСформировать");
Если СледующийЭлемент <> Неопределено Тогда
ЭтаФорма.ТекущийЭлемент = СледующийЭлемент;
КонецЕсли;
КонецПроцедуры
Этот способ более «чистый» с точки зрения архитектуры 1С, так как не использует внешние COM-объекты. Однако он требует жесткого указания имени следующего элемента, что не всегда удобно, если порядок обхода формы динамически меняется.
Проанализируем преимущества и недостатки каждого метода:
WScript.Shell в операционной системе.Подводя итог, можно сказать, что проблема двойного нажатия в 1С 8.3 на обычных формах — это следствие эволюции платформы и ее постепенного отказа от старых механизмов отрисовки интерфейса в пользу управляемого приложения. Тем не менее, используя предложенные выше методы, мы можем вернуть комфорт работы пользователям, привыкшим к быстрому вводу данных в среде 1С 8.2.