Как получить форму и обработать её закрытие через оповещение в 1С 8.3

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

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

Разница между методами ОткрытьФорму и ПолучитьФорму

Для начала проанализируем, в чем заключается принципиальное отличие этих подходов. Метод ОткрытьФорму является более высокоуровневым и «быстрым». Он за один вызов выполняет создание формы на сервере, её инициализацию и отображение на клиенте. Однако его главный минус — ограниченная возможность вмешательства в состояние формы до того, как она будет отрисована, если не использовать параметры формы.

Метод ПолучитьФорму возвращает нам объект типа УправляемаяФорма. Это позволяет нам обратиться к реквизитам формы напрямую в программном коде до вызова метода Открыть(). Но именно здесь кроется ловушка: в параметрах метода ПолучитьФорму нет места для передачи объекта ОписаниеОповещения. Разберем, как решить эту задачу.

Использование свойства ОписаниеОповещенияОЗакрытии

Когда мы работаем с объектом, полученным через ПолучитьФорму, мы должны помнить, что у самой формы есть программный интерфейс. Одним из ключевых свойств управляемой формы является ОписаниеОповещенияОЗакрытии. Именно в него нужно записать наше оповещение. Рассмотрим алгоритм действий по шагам.

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


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

Шаг 2. Создаем описание оповещения и назначаем его форме. Теперь пропишем код вызова формы. Вместо того чтобы передавать оповещение в метод, мы присвоим его свойству полученного объекта.


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

Важные нюансы работы с методом Закрыть()

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

  1. Передача результата: Если в дочерней форме вызвать просто Закрыть() без параметров, в процедуру ПослеЗакрытияДочернейФормы придет значение Неопределено. Чтобы передать данные назад, в дочерней форме нужно использовать синтаксис Закрыть(СтруктураСДанными).
  2. Закрытие «крестиком»: Если пользователь закрывает форму стандартной кнопкой закрытия окна (крестиком), система автоматически передает Неопределено. Программист должен всегда обрабатывать этот случай, чтобы избежать ошибок при попытке обращения к полям структуры, которой нет.
  3. Асинхронность: Код, следующий за методом Форма.Открыть(), выполнится СРАЗУ, не дожидаясь закрытия формы. Весь код, который должен работать с результатом, обязан находиться внутри процедуры оповещения.

Альтернатива: Использование параметров формы

Рассмотрим более современный и рекомендуемый стандарт разработки 1С. Хотя прямое заполнение через ПолучитьФорму кажется удобным, оно провоцирует лишние клиент-серверные вызовы. Вместо этого проанализируем возможность использования ОткрытьФорму с передачей параметров.

Все данные, переданные во втором параметре метода ОткрытьФорму, попадают в обработчик ПриСозданииНаСервере открываемой формы. Это позволяет инициализировать форму за один «поход» на сервер.


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

В этом случае в модуле открываемой формы в процедуре ПриСозданииНаСервере мы сможем прочитать эти значения из коллекции Параметры и применить их к объекту.

Ключ уникальности формы

При использовании ПолучитьФорму крайне важно следить за тем, какую именно форму возвращает система. Если вызвать ПолучитьФорму несколько раз с одинаковыми параметрами, 1С может вернуть ссылку на уже существующее, открытое ранее окно.

Если вы установите новое ОписаниеОповещенияОЗакрытии для уже открытой формы, старое оповещение будет перезаписано. Это может привести к тому, что логика первого вызвавшего кода никогда не завершится. Чтобы гарантированно получить новый экземпляр формы для заполнения, всегда используйте параметр КлючУникальности, генерируя для него Новый УникальныйИдентификатор().

Особенности Веб-клиента

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

Использование Владельца для возврата значения

Если ваша цель — не просто выполнить какой-то код после закрытия, а вернуть выбранное значение в поле ввода или в другую форму, можно воспользоваться механизмом Владелец. Рассмотрим пример:

  1. При вызове ПолучитьФорму передайте в качестве владельца элемент формы или саму форму.
  2. В дочерней форме вызовите метод ОповеститьОВыборе(ВыбранноеЗначение).
  3. Система автоматически закроет дочернюю форму и вызовет обработчик ОбработкаВыбора у владельца.

Этот способ позволяет избежать явного создания объектов ОписаниеОповещения, если взаимодействие ограничивается стандартным выбором данных.

Порядок выполнения событий

Проанализируем цепочку событий при использовании связки ПолучитьФорму и Открыть():

Таким образом, мы выяснили, что использование ПолучитьФорму вполне допустимо, если вам требуется тонкая настройка объекта формы перед визуализацией, а для обработки завершения работы достаточно напрямую обратиться к свойству ОписаниеОповещенияОЗакрытии объекта УправляемаяФорма.

← На главную