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