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