Как открыть форму существующего документа с оповещением о закрытии в 1С 8.3

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

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

Почему открывается форма нового документа вместо существующего

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

Посмотрим на базовый пример формирования параметров:


ПараметрыФормы = Новый Структура("Ключ", СсылкаНаДокумент);
ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаОбъекта", ПараметрыФормы);

При передаче структуры с ключом Ключ платформа находит существующий объект и открывает именно его форму.

Передача описания оповещения о закрытии через метод ОткрытьФорму

Выясним, как передать управление обратно в вызывающую форму после того, как пользователь закроет открытый документ. Для этого используется седьмой параметр метода ОткрытьФорму — ОписаниеОповещенияОЗакрытии. Также рекомендуется указать третий параметр — владельца формы (текущую форму ЭтотОбъект).

Разберем по шагам реализацию этого механизма:

  1. Создадим экземпляр объекта ОписаниеОповещения, указав имя экспортной процедуры обратного вызова и модуль, в котором она расположена.
  2. Сформируем структуру параметров с ключом Ключ для позиционирования на существующем документе.
  3. Вызовем метод ОткрытьФорму, передав параметры и объект оповещения.
  4. Опишем клиентскую процедуру-обработчик с директивой Экспорт и двумя обязательными параметрами: РезультатЗакрытия и ДополнительныеПараметры.

Посмотрим на пример реализации в коде формы-источника:


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

&НаКлиенте
Процедура ПослеЗакрытияДокумента(РезультатЗакрытия, ДополнительныеПараметры) Экспорт
    
    // Код, который выполнится после закрытия открытого документа
    ПоказатьОповещениеПользователя("Действие завершено", , "Форма документа была закрыта.");
    Элементы.Список.Обновить();
    
КонецПроцедуры

Блокировка вызывающего окна (эмуляция модальности)

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

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


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

&НаКлиенте
Процедура ПослеЗакрытияБлокирующегоОкна(РезультатЗакрытия, ДополнительныеПараметры) Экспорт
    // Пользователь закрыл документ, интерфейс владельца снова доступен
КонецПроцедуры

Если требуется заблокировать вообще все окна программы, можно использовать значение РежимОткрытияОкнаФормы.БлокироватьВесьИнтерфейс.

Современный подход: использование асинхронных процедур (Асинх / Ждать)

Начиная с версии платформы 1С:Предприятие 8.3.18, появился более лаконичный способ работы с асинхронными вызовами без необходимости создавать явный объект ОписаниеОповещения и отдельную процедуру обратного вызова. Для этого используется метод ОткрытьФормуАсинх совместно с оператором Ждать.

Рассмотрим, как выглядит код в асинхронной процедуре:


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

Такой подход делает код линейным, сохраняя при этом все преимущества немодального асинхронного интерфейса.

Альтернативный вариант: явная установка свойства формы на клиенте

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

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

Посмотрим на клиентский пример настройки формы:


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

Особенности возврата результата закрытия

Проанализируем поведение параметра РезультатЗакрытия:

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