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