Почему при открытии формы в 1С открываются два окна и как правильно установить фокус на элемент списка

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

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

Разбираем причину появления «лишнего» окна

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

Метод ВыбратьЭлемент() принадлежит объекту СписокЗначений. Его основная задача — вызвать стандартное системное диалоговое окно, которое блокирует работу интерфейса и ждет, пока пользователь выберет один из элементов списка. Когда этот код помещается в процедуру ПриОткрытии, происходит следующее:

  1. Платформа начинает процесс отображения основной формы.
  2. Выполняется код инициализации.
  3. Метод ВыбратьЭлемент() прерывает процесс отрисовки и выводит поверх еще не до конца открытой формы модальный список.
  4. Пользователь видит два окна одновременно.

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

Различие между интерактивным выбором и позиционированием

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

В обычных формах (1С 8.2 или 8.3 в режиме обычного приложения) за отображение данных отвечают элементы управления, такие как ПолеСписка или ТабличноеПоле. Чтобы управлять курсором в них, нужно обращаться к свойству ТекущаяСтрока соответствующего элемента формы, а не к самому объекту данных.

Как правильно установить фокус на первую строку при открытии

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


Процедура ПриОткрытии()
    // 1. Заполняем список значений (данные)
    ПолеСписка1.Добавить("Новый");
    ПолеСписка1.Добавить("Старый");
    
    // 2. Проверяем, есть ли в списке элементы, чтобы избежать ошибки
    Если ПолеСписка1.Количество() > 0 Тогда
        // 3. Устанавливаем текущую строку в элементе управления на форме.
        // Мы берем первый элемент из данных (индекс 0) и присваиваем его свойству ТекущаяСтрока
        ЭлементыФормы.ПолеСписка1.ТекущаяСтрока = ПолеСписка1.Получить(0);
    КонецЕсли;
КонецПроцедуры

В этом примере ПолеСписка1 (без приставки ЭлементыФормы) — это реквизит формы типа СписокЗначений, а ЭлементыФормы.ПолеСписка1 — это визуальный элемент управления. Присваивая значение свойству ТекущаяСтрока, мы визуально выделяем нужный нам пункт для пользователя.

Возврат значения из модально открытой формы

Часто вторая форма открывается для того, чтобы пользователь что-то в ней выбрал, и это значение вернулось в основное окно. Для этого используется метод ОткрытьФормуМодально(). Выясним, как правильно организовать передачу выбранных данных обратно.

Когда вы вызываете форму модально, выполнение кода в первой форме приостанавливается на строке вызова до тех пор, пока вторая форма не будет закрыта. Рассмотрим, как это выглядит в коде первой формы:


// Код в первой форме
ВыбранноеЗначение = ОткрытьФормуМодально("ВнешняяОбработка.МояОбработка.Форма.Форма2");
Если ВыбранноеЗначение <> Неопределено Тогда
    Сообщить("Пользователь выбрал: " + ВыбранноеЗначение);
КонецЕсли;

Теперь разберем, что нужно написать во второй форме, чтобы значение действительно вернулось. Для этого используется метод Закрыть(), в который передается параметр. Например, это может происходить при двойном клике по списку или при нажатии кнопки «ОК»:


// Код во второй форме (например, обработчик нажатия кнопки)
Процедура КомандаОК(Кнопка)
    // Получаем текущее выделенное значение из элемента формы
    РезультатВыбора = ЭлементыФормы.ПолеСписка1.ТекущаяСтрока.Значение;
    
    // Закрываем форму и передаем это значение в вызывавшее окно
    ЭтаФорма.Закрыть(РезультатВыбора);
КонецПроцедуры

Риски использования интерактивных методов в обработчиках событий

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

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

Заключение

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

  1. Для выделения строки используйте ЭлементыФормы.ИмяЭлемента.ТекущаяСтрока.
  2. Избегайте метода ВыбратьЭлемент(), если у вас уже есть список на форме.
  3. Передавайте данные обратно через параметр метода Закрыть().
  4. Всегда проверяйте наличие данных в списке перед тем, как пытаться позиционироваться на первую строку, чтобы избежать обращения к пустому индексу.

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

← На главную