Как программно открыть форму подбора в 1С и установить фокус на поле поиска?

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

При разработке интерфейсов в конфигурациях на обычных (неуправляемых) формах 1С (таких как «Управление торговым предприятием для Украины 1.2», «Управление производственным предприятием 1.3» или «Управление торговлей 10.3») программисты часто сталкиваются с неочевидным поведением платформы при работе с подчиненными окнами. Типичный сценарий: при открытии нового документа реализации необходимо автоматически открыть форму подбора номенклатуры и сразу позиционировать курсор в поле поиска, чтобы пользователь мог начать вводить артикул или наименование без лишних кликов мышкой.

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

Выясняем причину: почему теряется фокус ввода?

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

  1. Инициируется открытие формы документа.
  2. Внутри обработчика ПриОткрытии срабатывает код, который создает, открывает и пытается активизировать форму подбора номенклатуры.
  3. Форма подбора действительно открывается и получает фокус ввода.
  4. Но затем платформа завершает процедуру открытия самого документа и принудительно передает фокус (активизирует) форму основного документа, так как ее визуализация завершилась последней.

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

Рассмотрим подробнее три практических метода решения этой задачи.

Решение 1. Использование обработчика «ОбновлениеОтображения» (метод автора темы)

Самый простой способ поймать момент, когда форма документа полностью отрисована и активизирована — это использование предопределенного события формы ОбновлениеОтображения. Данный обработчик вызывается платформой автоматически при любом изменении состояния элементов интерфейса.

Чтобы код активации подбора сработал только один раз при старте, мы введем специальную переменную-флаг. Давайте посмотрим на программную реализацию в модуле формы документа:


Переменная БылоПервоеОбновлениеФормы;

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

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

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

Решение 2. Асинхронный вызов через обработчик ожидания (рекомендуемый метод)

Наиболее красивым, надежным и стандартным решением в среде 1С является использование механизма однократного обработчика ожидания. Мы можем дать указание платформе выполнить код активации подбора через долю секунды после того, как управление вернется к пользователю.

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

Проанализируем программный код в модуле формы документа:


Переменная СсылкаНаФормуПодбора;

Процедура ПриОткрытии()
    Если ЭтоНовый() Тогда
        СсылкаНаФормуПодбора = Неопределено;
        СтруктураПараметровПодбора = Новый Структура;
        
        // Открываем форму подбора и получаем на нее ссылку
        РаботаСДиалогами.ОткрытьПодборНоменклатуры(ЭтаФорма, СтруктураПараметровПодбора, Метаданные(), СсылкаНаФормуПодбора);
        
        // Подключаем одноразовый обработчик ожидания с минимальной задержкой
        ПодключитьОбработчикОжидания("АктивизироватьПолеПоискаВПодборе", 0.1, Истина);
    КонецЕсли;
КонецПроцедуры

Процедура АктивизироватьПолеПоискаВПодборе() Экспорт
    Если СсылкаНаФормуПодбора <> Неопределено И СсылкаНаФормуПодбора.Открыта() Тогда
        Попытка
            // Устанавливаем курсор в текстовое поле поиска
            СсылкаНаФормуПодбора.ТекущийЭлемент = СсылкаНаФормуПодбора.ЭлементыФормы.ПолеПоиска;
            // Активизируем саму форму подбора
            СсылкаНаФормуПодбора.Aктивизировать();
        Исключение
            // Защита на случай, если пользователь успел закрыть форму подбора за 0.1 секунды
        КонецПопытки;
    КонецЕсли;
КонецПроцедуры

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

Решение 3. Использование механизма глобальных оповещений

Если логика открытия формы подбора инкапсулирована в общих модулях и у нас нет прямого доступа к возвращаемой переменной формы подбора (или мы не хотим жестко связывать модули), можно применить механизм оповещений платформы 1С.

Рассмотрим, как это реализовать по шагам:

Шаг 1. В модуле формы документа сразу после открытия подбора посылаем глобальное оповещение:


Процедура ПриОткрытии()
    Если ЭтоНовый() Тогда
        РаботаСДиалогами.ОткрытьПодборНоменклатуры(ЭтаФорма, СтруктураПараметровПодбора, Метаданные());
        // Отправляем сигнал, который поймает открытая форма подбора
        Оповестить("АктивизироватьПоискВПодборе");
    КонецЕсли;
КонецПроцедуры

Шаг 2. В модуле самой формы подбора (например, в обработке ПодборНоменклатуры) настраиваем перехват этого события в процедуре ОбработкаОповещения:


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

Анализ метода: Такой подход полностью соответствует принципам объектно-ориентированного программирования и слабой связанности модулей. Форма подбора сама решает, как ей реагировать на внешнее событие активации.

Важное дополнение: проблемы с фокусом в подборе на платформе 8.3.25 и выше

Если вы запускаете конфигурации на обычных формах (УТ 10.3, УПП 1.3) на современных релизах платформы 1С:Предприятие 8.3.25 и выше, вы можете столкнуться с новой системной ошибкой фокуса.

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

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


// Пример кода после закрытия окна ввода количества:
ФормаВводаПараметров.ОткрытьМодально();

// Принудительно возвращаем фокус на поле поиска или список товаров
ЭлементыФормы.ПолеПоиска.Активизировать();
// Или:
// ТекущийЭлемент = ЭлементыФормы.СправочникСписок;

Применение любого из предложенных методов (лучше всего — обработчика ожидания) позволит сделать работу ваших пользователей с подбором номенклатуры максимально быстрой, удобной и избавит их от лишних монотонных кликов мышкой.

← На главную