Как открыть произвольную форму в 1С и вернуть из нее значение в основную форму

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

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

Разбор типичных ошибок при открытии формы

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

Вторая типичная ошибка — попытка вызвать открытие формы на сервере. В 1С управляемое приложение четко разделяет контексты. Выполнение кода в процедуре с директивой &НаСервере или &НаСервереБезКонтекста не подразумевает взаимодействия с интерфейсом. Попытка вызвать метод Открыть() на сервере закономерно приводит к ошибке "Интерактивные операции недоступны". Весь интерфейсный цикл — открытие окон, вопросы пользователю, сообщения — должен происходить исключительно на клиенте.

Шаг 1. Подготовка вызова подчиненной формы

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

Для реализации возврата значения в современном 1С (особенно в веб-клиенте) используется асинхронный подход с применением объекта ОписаниеОповещения. Разберем пример кода на стороне основной формы:


&НаКлиенте
Процедура Поле1НачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    
    // 1. Отменяем стандартное действие платформы
    СтандартнаяОбработка = Ложь;
    
    // 2. Подготавливаем параметры для передачи в открываемую форму
    // Это может быть текущее значение поля или любые другие настройки
    ПараметрыВызова = Новый Структура;
    ПараметрыВызова.Вставить("ТекущееЗначение", Объект.Поле1);
    ПараметрыВызова.Вставить("РежимРаботы", "Расширенный");
    
    // 3. Создаем описание оповещения, которое сработает ПРИ ЗАКРЫТИИ формы
    // "ПослеЗакрытияФормы2" - это имя процедуры в этой же форме
    Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияФормы2", ЭтаФорма);
    
    // 4. Открываем форму
    // Обратите внимание на путь: Справочник.Имя.Форма.ИмяПроизвольнойФормы
    ОткрытьФорму(
        "Справочник.Клиенты.Форма.Форма2", 
        ПараметрыВызова, 
        ЭтаФорма, 
        Истина, 
        , 
        , 
        Оповещение, 
        РежимОткрытияОкнаФормы.БлокироватьОкноВладельца
    );

КонецПроцедуры

Шаг 2. Обработка данных в подчиненной форме (Форма2)

Теперь выясним, как принять данные в открытой форме и как вернуть результат. Когда мы передаем структуру параметров в ОткрытьФорму, эта структура становится доступной в подчиненной форме в обработчике ПриСозданииНаСервере через свойство Параметры.

Проанализируем код внутри подчиненной формы (Форма2):


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

&НаКлиенте
Процедура ЗавершитьВыборИЗакрыть()
    
    // Подготавливаем результат, который хотим вернуть
    Результат = "Новое измененное значение";
    
    // Закрываем форму и передаем результат
    // Этот результат попадет в процедуру оповещения в основной форме
    Закрыть(Результат);
    
КонецПроцедуры

Шаг 3. Получение результата в основной форме

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


&НаКлиенте
Процедура ПослеЗакрытияФормы2(Результат, ДополнительныеПараметры) Экспорт
    
    // Проверяем, что пользователь не просто закрыл форму крестиком, 
    // а действительно вернул какое-то значение
    Если Результат <> Неопределено Тогда
        
        // Присваиваем полученное значение реквизиту
        Объект.Поле1 = Результат;
        
        // Если нужно, уведомляем систему об изменении данных
        ЭтаФорма.Модифицированность = Истина;
        
    КонецЕсли;

КонецПроцедуры

Дополнительные возможности и нюансы

Рассмотрим подробнее важные параметры метода ОткрытьФорму, которые мы использовали:

  1. Владелец окна: Передавая ЭтаФорма, мы связываем окна. Если закрыть основную форму, подчиненная закроется автоматически.
  2. Режим открытия окна: Использование РежимОткрытияОкнаФормы.БлокироватьОкноВладельца — это лучший выбор для задач выбора. Пользователь не сможет случайно изменить что-то в основной форме, пока открыто вспомогательное окно, что гарантирует целостность данных.
  3. Уникальность: Если вам нужно, чтобы нельзя было открыть две одинаковые вспомогательные формы одновременно, используйте параметр КлючУникальности.

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

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

← На главную