Как заблокировать горячие клавиши команд при редактировании поля в 1С?

Программист 1С v8.3 (Управляемые формы)
← На главную

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

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

Разберем ситуацию: у нас есть команда, привязанная к клавише 1. Когда пользователь находится в режиме просмотра формы, нажатие клавиши логично активирует команду. Но как только пользователь входит в режим редактирования ячейки (например, поля «Сумма»), он ожидает, что нажатие 1 введет символ в поле. Вместо этого платформа 1С отдает приоритет горячей клавише команды.

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

Способ 1: Программный сброс сочетаний клавиш (решение с форума)

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

Рассмотрим реализацию этого метода по шагам:

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

Пример кода для реализации:


&НаСервере
Процедура СброситьГорячиеКлавишиНаСервере()
    // Ищем нужные команды по именам и очищаем их сочетания клавиш
    МассивКоманд = Новый Массив;
    МассивКоманд.Добавить("КомандаКалькулятор1");
    МассивКоманд.Добавить("КомандаКалькулятор2");
    
    Для Каждого ИмяКоманды Из МассивКоманд Цикл
        ТекущаяКоманда = ЭтаФорма.Команды.Найти(ИмяКоманды);
        Если ТекущаяКоманда <> Неопределено Тогда
            ТекущаяКоманда.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.Нет);
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура СписокПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)
    // Чтобы избежать цикличных вызовов и лишних обращений к серверу, 
    // используем флаг редактирования
    Если НЕ ИдетРедактированиеСуммы Тогда
        СброситьГорячиеКлавишиНаСервере();
        
        ИдетРедактированиеСуммы = Истина;
        
        // Ключевой момент: возвращаем фокус в ячейку программно
        Элементы.Список.ИзменитьСтроку();
    КонецЕсли;
КонецПроцедуры

Важно помнить, что после окончания редактирования (событие ПриЗавершенииРедактирования) горячие клавиши нужно вернуть обратно тем же способом, иначе калькулятор перестанет работать по кнопкам клавиатуры до переоткрытия формы.

Способ 2: Использование акселераторов (стандарт 1С)

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

Если вместо клавиши 1 назначить сочетание Alt + 1, проблема исчезнет сама собой:

Способ 3: Обработчик ожидания для обхода «двойного клика»

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

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

Пример логики:

  1. В ПриНачалеРедактирования меняем видимость кнопок.
  2. Подключаем однократный обработчик ожидания: ПодключитьОбработчикОжидания("ВернутьФокусВПоду", 0.1, Истина);.
  3. В процедуре ВернутьФокусВПоле вызываем УстановитьТекущийЭлемент.

Способ 4: Проверка фокуса внутри самой команды

Рассмотрим еще один вариант: мы не блокируем горячую клавишу, но меняем поведение самой команды. В начале кода команды можно добавить проверку: какой элемент сейчас активен? Если текущий элемент — это поле ввода суммы, команда просто завершает работу без выполнения действий.


&НаКлиенте
Процедура КомандаКалькулятора(Команда)
    // Проверяем, не находится ли фокус в поле ввода
    Если ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ПолеФормы") Тогда
        Возврат; // Ничего не делаем, даем пользователю вводить данные
    КонецЕсли;
    
    // Логика калькулятора...
КонецПроцедуры

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

Резюме и рекомендации

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

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

Самый правильный с точки зрения UX/UI метод: использование сочетаний с Alt, Ctrl или Shift. Это избавляет от необходимости писать сложную логику перехвата событий и делает поведение интерфейса предсказуемым для пользователя.

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

← На главную