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