Как программно открыть форму выбора и заполнить реквизит в 1С:Предприятии 8.3 (Управляемые формы)?

Программист 1С v8.3 (Управляемые формы)
← На главную

При разработке обработок или документов в системе 1С:Предприятие 8.3 часто возникает задача, когда при открытии новой формы необходимо сразу предложить пользователю выбрать значение из справочника или другого объекта, а затем автоматически подставить это значение в один из реквизитов текущей формы. Рассмотрим, как это можно реализовать несколькими способами в управляемых формах, обеспечивая удобство для пользователя и корректную логику работы.

Предположим, у нас есть обработка с реквизитом "Подразделение" типа СправочникСсылка.Подразделения. Наша цель – при открытии этой обработки, если реквизит "Подразделение" еще не заполнен, автоматически открыть форму выбора справочника "Подразделения". После того как пользователь сделает выбор, выбранное значение должно быть подставлено в реквизит обработки. Если пользователь отменит выбор, необходимо также предусмотреть соответствующую реакцию.

Решение 1: Открытие формы выбора с использованием ОписаниеОповещения

Этот метод является одним из наиболее универсальных и часто используемых в управляемых формах, поскольку он позволяет асинхронно дождаться результата работы другой формы и обработать его в указанной процедуре-обработчике.

Суть метода: Мы открываем форму выбора с помощью метода ОткрытьФорму(), передавая ему объект ОписаниеОповещения. Этот объект содержит информацию о том, какую процедуру и в каком модуле следует вызвать после закрытия открываемой формы, а также результат её работы.

  1. Инициирование открытия формы выбора при открытии обработки:

    Для этого мы используем обработчик события ПриОткрытии формы нашей обработки. В нем мы проверяем, заполнен ли реквизит "Подразделение". Если нет, то формируем ОписаниеОповещения и вызываем ОткрытьФорму().

    
    &НаКлиенте
    Процедура ПриОткрытии(Отказ)
        Если Не ЗначениеЗаполнено(Объект.Подразделение) Тогда
            // Создаем описание оповещения для обработки выбора
            ОписаниеВыбора = Новый ОписаниеОповещения("ОбработатьВыборПодразделения", ЭтаФорма);
                    
            // Открываем форму выбора справочника "Подразделения"
            // РежимОткрытияОкнаФормы.БлокироватьОкноВладельца - заблокирует текущее окно до выбора
            ОткрытьФорму("Справочник.Подразделения.ФормаВыбора",,,,,, ОписаниеВыбора, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
        КонецЕсли;
    КонецПроцедуры
    

    Разберем по шагам:

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

    После того как пользователь выберет элемент в форме справочника и закроет её, или просто закроет форму без выбора, будет вызвана процедура, указанная в ОписаниеОповещения.

    
    &НаКлиенте
    Процедура ОбработатьВыборПодразделения(РезультатЗакрытия, ДопПараметры) Экспорт
        Если Не ЗначениеЗаполнено(РезультатЗакрытия) Тогда
            // Если пользователь отменил выбор (закрыл форму без выбора),
            // РезультатЗакрытия будет пустым (Неопределено).
            // В этом случае мы можем либо ничего не делать, либо закрыть текущую форму.
            Закрыть(); // Опционально: закрыть текущую форму обработки, если выбор обязателен
            Возврат;
        КонецЕсли;
                
        // Если выбор был сделан, РезультатЗакрытия содержит выбранное значение.
        Объект.Подразделение = РезультатЗакрытия;
    КонецПроцедуры
    

    Проанализируем процедуру-обработчик:

    • &НаКлиенте: Процедура также выполняется на клиентской стороне.
    • Экспорт: Обязательно, чтобы процедура была доступна для вызова из других мест (в данном случае, из механизма оповещений).
    • РезультатЗакрытия: Этот параметр содержит значение, которое было выбрано пользователем в форме выбора. Если пользователь закрыл форму без выбора (например, кнопкой "Закрыть"), этот параметр будет Неопределено или пустым значением.
    • ДопПараметры: Структура дополнительных параметров, которую можно было бы передать при создании ОписаниеОповещения. В нашем примере она не используется, но может быть полезна для передачи контекстной информации.
    • Если Не ЗначениеЗаполнено(РезультатЗакрытия) Тогда: Мы проверяем, было ли что-то выбрано. Если нет, это означает, что пользователь отменил выбор. В этом случае мы можем решить, что делать: либо просто игнорировать (Возврат), либо, если выбор обязателен, закрыть текущую форму обработки (Закрыть()).
    • Объект.Подразделение = РезультатЗакрытия;: Если значение было выбрано, мы присваиваем его реквизиту нашей обработки.

Преимущества этого метода:

Решение 2: Открытие формы выбора с автоматическим заполнением через ЭлементДляВыбора

Для более простых сценариев, когда выбранное значение нужно просто подставить в конкретный элемент формы, система 1С предоставляет более короткий способ, который автоматически выполняет подстановку без необходимости явно описывать процедуру-обработчик оповещения.

Суть метода: Мы передаем ссылку на элемент формы, который должен быть заполнен, в качестве параметра ЭлементДляВыбора при вызове метода ОткрытьФорму().

  1. Инициирование открытия формы выбора с автоматическим заполнением:

    
    &НаКлиенте
    Процедура ПриОткрытии(Отказ)
        Если Не ЗначениеЗаполнено(Объект.Подразделение) Тогда
            // Открываем форму выбора, указывая Элементы.Подразделение как владелец.
            // Выбранное значение автоматически подставится в этот элемент.
            ОткрытьФорму("Справочник.Подразделения.ФормаВыбора",, Элементы.Подразделение,,,, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
        КонецЕсли;
    КонецПроцедуры
    

    Разберем особенности:

    • Вместо ОписаниеОповещения, мы передаем объект Элементы.Подразделение в третий параметр метода ОткрытьФорму(). Элементы.Подразделение – это ссылка на элемент формы, связанный с реквизитом "Подразделение".
    • Система 1С автоматически поймет, что после выбора значения в открываемой форме его нужно подставить в элемент "Подразделение" текущей формы.
    • Параметр РежимОткрытияОкнаФормы.БлокироватьОкноВладельца также рекомендуется использовать для обеспечения последовательности действий.
  2. Дополнительная обработка (опционально):

    Несмотря на автоматическую подстановку, вы все еще можете перехватить событие выбора и выполнить дополнительные действия в процедуре ОбработкаВыбора формы-владельца. Эта процедура будет вызвана после того, как значение будет автоматически подставлено в элемент.

    
    &НаКлиенте
    Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
        // Здесь ВыбранноеЗначение уже подставлено в Объект.Подразделение
        // Можно выполнить дополнительную логику, например, обновить другие поля,
        // если они зависят от выбранного подразделения.
        // Если ИсточникВыбора равен Элементы.Подразделение, то это наш случай.
        Если ИсточникВыбора = Элементы.Подразделение Тогда
            // Например, вывести сообщение или обновить связанные данные
            Сообщить("Выбрано подразделение: " + ВыбранноеЗначение);
        КонецЕсли;
    КонецПроцедуры
    

    Преимущества этого метода:

    • Простота: меньше кода для реализации базового функционала.
    • Автоматизация: система сама занимается подстановкой значения.

    Недостатки:

    • Меньшая гибкость: если требуется сложная обработка результата до его подстановки или нужно отменить подстановку при определенных условиях, этот метод может быть менее подходящим.
    • Сложности с обработкой отмены: при отмене выбора, поле останется пустым, и ОбработкаВыбора не будет вызвана с пустым значением для данного элемента (вызывается только при фактическом выборе).

Решение 3: Использование ВвестиЗначениеАсинх()

Метод ВвестиЗначениеАсинх() предназначен для получения одного значения от пользователя в отдельном диалоговом окне. Он также работает асинхронно и использует ОписаниеОповещения для обработки результата. Это решение более подходит для случаев, когда нужно выбрать простое значение (строку, число, дату, булево) или предопределенное значение из списка, а не элемент справочника через полнофункциональную форму выбора.

Суть метода: Вызывается функция ВвестиЗначениеАсинх(), которая показывает пользователю диалоговое окно для ввода значения. Результат возвращается через механизм оповещений.

  1. Инициирование ввода значения:

    
    &НаКлиенте
    Процедура ПриОткрытии(Отказ)
        Если Не ЗначениеЗаполнено(Объект.Подразделение) Тогда
            // Создаем описание оповещения для обработки введенного значения
            ОписаниеОбработчика = Новый ОписаниеОповещения("ОбработатьВводЗначенияПодразделения", ЭтаФорма);
                    
            // Вызываем ВвестиЗначениеАсинх для получения значения.
            // В данном случае, это не совсем для выбора элемента справочника,
            // а скорее для ввода ссылки, если пользователь знает ее представление.
            // Для выбора из справочника предпочтительнее ОткрытьФорму.
            ВвестиЗначениеАсинх(ОписаниеОбработчика, Объект.Подразделение, "Выберите подразделение", Тип("СправочникСсылка.Подразделения"));
        КонецЕсли;
    КонецПроцедуры
    

    Разберем:

    • ВвестиЗначениеАсинх() принимает ОписаниеОповещения для обработки результата.
    • Второй параметр – текущее значение, которое будет показано в поле ввода по умолчанию.
    • Третий параметр – заголовок диалогового окна.
    • Четвертый параметр – тип значения, которое ожидается от пользователя. Если это ссылка на справочник, то при вводе система может предложить подбор из справочника (но это будет не полная форма выбора).
  2. Обработка введенного значения:

    Процедура-обработчик будет аналогична той, что используется для ОткрытьФорму().

    
    &НаКлиенте
    Процедура ОбработатьВводЗначенияПодразделения(РезультатВвода, ДопПараметры) Экспорт
        Если РезультатВвода = Неопределено Тогда
            // Пользователь отменил ввод
            Возврат;
        КонецЕсли;
                
        // Заполняем реквизит введенным значением
        Объект.Подразделение = РезультатВвода;
    КонецПроцедуры
    

    Преимущества:

    • Простота диалога для пользователя, если требуется ввести одно значение.
    • Подходит для простых типов данных.

    Недостатки:

    • Менее приспособлен для полноценного выбора из справочников со сложными отборами и отображением, так как не открывает стандартную форму списка справочника, а лишь предоставляет поле ввода с возможностью подбора. Для данной задачи (выбор подразделения) ОткрытьФорму() с ФормаВыбора будет более предпочтительным.

Дополнительные важные аспекты

При работе с программным открытием форм и заполнением реквизитов важно учитывать несколько общих моментов, которые повысят надежность и удобство вашей разработки.

  1. Передача параметров в открываемую форму:

    Часто возникает необходимость открыть форму выбора с уже установленными отборами или предустановленными значениями. Мы можем передать эти параметры, используя второй аргумент метода ОткрытьФорму() – структуру Параметры.

    
    // Пример передачи отбора
    ПараметрыОткрытия = Новый Структура;
    ПараметрыОткрытия.Вставить("Отбор", Новый Структура("ГоловноеПодразделение", Истина));
            
    ОписаниеВыбора = Новый ОписаниеОповещения("ОбработатьВыборПодразделения", ЭтаФорма);
    ОткрытьФорму("Справочник.Подразделения.ФормаВыбора", ПараметрыОткрытия,,,,,, ОписаниеВыбора, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
    

    В открываемой форме (в нашем случае, в Справочник.Подразделения.ФормаВыбора) эти параметры можно получить в обработчике события ПриСозданииНаСервере() и использовать для настройки динамического списка или других элементов формы.

    
    // В модуле формы выбора справочника (например, Справочник.Подразделения.ФормаВыбора)
    &НаСервере
    Процедура ПриСозданииНаСервере(Отказ)
        Если Параметры.Свойство("Отбор") Тогда
            Для Каждого ЭлементОтбора Из Параметры.Отбор Цикл
                ЭлементДинамическогоСпискаОтбор = Список.Отбор.Элементы.Добавить(ВидСравнения.Равно);
                ЭлементДинамическогоСпискаОтбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(ЭлементОтбора.Ключ);
                ЭлементДинамическогоСпискаОтбор.ПравоеЗначение = ЭлементОтбора.Значение;
                ЭлементДинамическогоСпискаОтбор.Использование = Истина;
            КонецЦикла;
        КонецЕсли;
    КонецПроцедуры
    

    Это позволяет нам открывать формы выбора, которые сразу отфильтрованы или настроены под конкретный сценарий использования.

  2. Избегайте ОткрытьФормуМодально():

    В управляемых формах крайне не рекомендуется использовать метод ОткрытьФормуМодально(). Он блокирует работу пользователя со всем приложением до закрытия модальной формы, что может привести к зависаниям интерфейса и ухудшению пользовательского опыта, особенно в веб-клиенте. Всегда отдавайте предпочтение асинхронным методам с ОписаниеОповещения или передачей элемента-владельца, как мы рассмотрели выше.

  3. Обработка отмены выбора:

    Всегда предусматривайте сценарий, когда пользователь решает не выбирать значение и просто закрывает форму. В обработчиках ОписаниеОповещения (РезультатЗакрытия) или ОбработкаВыбора (ВыбранноеЗначение) обязательно проверяйте, было ли значение фактически выбрано. Если нет (например, РезультатЗакрытия равен Неопределено или пустое), принимайте соответствующие меры – не заполняйте реквизит, или, если выбор обязателен, предупредите пользователя или закройте текущую форму.

  4. Начальное заполнение реквизитов конфигурации:

    Для реквизитов объектов конфигурации (документов, справочников) можно также использовать свойства ЗначениеЗаполнения и ЗаполнятьИзДанныхЗаполнения. Эти свойства задаются в конфигураторе для реквизитов и позволяют автоматически заполнять их при создании нового объекта (например, на основании другого или при копировании). Это не связано напрямую с программным открытием форм выбора, но является еще одним механизмом автоматического заполнения реквизитов.

Мы рассмотрели основные и наиболее эффективные подходы для программного открытия форм выбора и заполнения реквизитов в 1С:Предприятии 8.3 в управляемых формах. Выбор конкретного метода зависит от сложности требуемой логики и удобства для пользователя. Для большинства случаев выбора элементов справочников или документов, использование ОткрытьФорму() с ОписаниеОповещения или с параметром ЭлементДляВыбора будет оптимальным решением.

← На главную