При разработке нестандартных механизмов подбора и заполнения реквизитов документов в платформе 1С:Предприятие 7.7 часто требуется открыть форму списка справочника модально, передав в нее определенные параметры (например, значение для отбора), а затем получить выбранный пользователем элемент. Однако при простом вызове ОткрытьФормуМодально() двойной щелчок мыши или нажатие клавиши Enter открывает карточку элемента на редактирование вместо выбора строки, а предопределенные процедуры выбора не срабатывают так, как ожидается. Разберем причины такого поведения и рассмотрим надежные варианты решения этой задачи.
Когда форма списка справочника открывается через процедуру ОткрытьФормуМодально(), платформа открывает ее в обычноном режиме просмотра списка, а не в системном режиме выбора. Если в метаданных справочника установлено свойство Редактировать в диалоге, то при двойном клике на строку платформа стандартно пытается открыть форму редактирования элемента. Процедура ПриНачалеВыбораЗначения() предназначена только для элементов управления диалога при начале выбора из поля ввода и в модуле формы списка не вызывается.
Чтобы форма списка начала перехватывать нажатие клавиши Enter и двойной клик мыши как выбор строки, необходимо явно активировать режим перехвата выбора с помощью метода Форма.ОбработкаВыбораСтроки(1) и описать логику в предопределенной процедуре ПриВыбореСтроки().
Рассмотрим по шагам стандартный и наиболее гибкий подход к открытию формы с отбором и возвратом выбранного элемента через объект СписокЗначений.
Вызов формы из документа или обработки:
Создаем список значений, помещаем в него параметры фильтрации и открываем требуемую форму списка справочника модально.
ПараметрыОтбора = СоздатьОбъект("СписокЗначений");
ПараметрыОтбора.Установить("Страна", ТекСтрана);
ПараметрыОтбора.Установить("ВыбранныйЭлемент", ПолучитьПустоеЗначение("Справочник.Абоненты"));
ОткрытьФормуМодально("Справочник.Абоненты.ДляВыбора", ПараметрыОтбора);
// Проверяем результат после закрытия модальной формы
ВыбЭлемент = ПараметрыОтбора.Получить("ВыбранныйЭлемент");
Если ВыбЭлемент.Выбран() = 1 Тогда
Адрес = ВыбЭлемент.Адрес;
КонецЕсли;
Обработка открытия и включение режима выбора в форме справочника:
В модуле формы списка справочника в процедуре ПриОткрытии() считываем входящие параметры, устанавливаем отбор и включаем перехват выбора строки методом Форма.ОбработкаВыбораСтроки(1).
Процедура ПриОткрытии()
Парам = Форма.Параметр;
Если ТипЗначенияСтр(Парам) = "СписокЗначений" Тогда
ФильтрСтрана = Парам.Получить("Страна");
Если ПустоеЗначение(ФильтрСтрана) = 0 Тогда
УстановитьОтбор("Страна", ФильтрСтрана);
КонецЕсли;
// Включаем перехват выбора строки для вызова процедуры ПриВыбореСтроки
Форма.ОбработкаВыбораСтроки(1);
КонецЕсли;
КонецПроцедуры
Обработка клика и возврат значения:
В предопределенной процедуре ПриВыбореСтроки() получаем текущую позицию курсора с помощью функции ТекущийЭлемент(), записываем результат в переданный список значений и закрываем форму.
Процедура ПриВыбореСтроки()
// Проверяем, что выбрана не группа справочника (если справочник иерархический)
Если ТекущийЭлемент().ЭтоГруппа() = 1 Тогда
// Разрешаем стандартный вход в папку
Возврат;
КонецЕсли;
Парам = Форма.Параметр;
Если ТипЗначенияСтр(Парам) = "СписокЗначений" Тогда
Парам.Установить("ВыбранныйЭлемент", ТекущийЭлемент());
Иначе
// Если передан не список, возвращаем элемент напрямую в параметр формы
Форма.Параметр = ТекущийЭлемент();
КонецЕсли;
// Закрываем форму с признаком завершения
Форма.Закрыть(1);
КонецПроцедуры
Если сложная передача контекста не требуется, а нужно лишь открыть форму списка в штатном режиме выбора и получить выбранное значение, платформа предоставляет встроенный метод объекта Справочник — Выбрать().
Разберем пример его использования:
Спр = СоздатьОбъект("Справочник.Абоненты");
Если Спр.Выбрать("Выберите абонента", "ДляВыбора") = 1 Тогда
ВыбранныйАбонент = Спр.ТекущийЭлемент();
Адрес = ВыбранныйАбонент.Адрес;
КонецЕсли;
При таком подходе форма сразу открывается в системном режиме выбора, а двойной щелчок автоматически завершает работу диалога и возвращает 1. Однако передача параметров фильтрации в этом случае ограничена: передать параметры внутрь открываемой формы можно только через глобальные переменные конфигурации или предопределенные свойства родителя/владельца.
УстановитьОтбор() работает только по тем реквизитам справочника, для которых в конфигураторе взведен флаг Отбор или Сортировка. Если отбор по реквизиту не поддерживается метаданными, можно предварительно отобрать элементы запросом и применить метод ИспользоватьСписокЭлементов(СписокНайденных).СписокЗначений передается в Форма.Параметр по ссылке. Любые изменения через метод Установить() внутри формы списка сохраняются в исходном списке вызывающего документа.внКонтекст.Адрес = ...) не рекомендуется, так как при закрытии формы выбора клавишей Esc или системной кнопкой закрытия окно может оставить вызывающий документ в несогласованном состоянии. Корректнее возвращать выбранный элемент в параметр и обрабатывать результат в вызывающем модуле.