Как в 1С сохранить текущую форму справочника, закрыть её и открыть форму нового элемента другого справочника?

Программист 1С v8.3 (Обычные формы) Сфера услуг, туризм и социальный сектор
← На главную

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

Проанализируем причины такого поведения платформы 1С и разберем проверенные способы реализации этого механизма.

Выясним причину: почему закрывается новая форма или не закрывается старая

Рассмотрим две основные проблемы, возникающие при выполнении подобного кода:

  1. Передача текущей формы в качестве владельца: если при вызове метода получения новой формы указать параметр Владелец (например, передать туда ЭтаФорма), платформа жестко свяжет время жизни нового окна с родительским. При последующем вызове метода Закрыть() для родительской формы платформа автоматически уничтожит и дочернее окно.
  2. Неуспешная запись или незавершенные обработчики: если вызывать простую процедуру Записать() без проверки результата, в случае ошибки валидации или отказа в процедуре ПередЗаписью объект не сохранится, а последующие команды могут привести к непредсказуемому состоянию интерфейса. Кроме того, если свойство Модифицированность остается в значении Истина, форма может выдать пользователю стандартный вопрос о сохранении данных при закрытии.

Способ 1. Использование метода ЗаписатьВФорме() и открытие формы без владельца

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


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

Посмотрим на ключевые моменты этого кода:

  1. Метод ЗаписатьВФорме() возвращает булево значение (Истина / Ложь), что позволяет прервать выполнение алгоритма, если запись не удалась (например, не заполнены обязательные поля).
  2. В вызове ПолучитьФормуНовогоЭлемента() не передается ссылка на текущее окно, поэтому новая форма становится самостоятельным окном приложения.
  3. Явный сброс Модифицированность = Ложь гарантирует, что форма закроется без лишних диалоговых окон с подтверждением.

Способ 2. Программное создание объекта с заполнением реквизитов

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


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

Способ 3. Отложенное закрытие через обработчик ожидания

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


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

Процедура ВыполнитьЗакрытиеТекущейФормы() Экспорт
    Модифицированность = Ложь;
    Закрыть();
КонецПроцедуры

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

Реализация аналогичной логики на управляемых формах

Рассмотрим, как подобная задача решается в современном интерфейсе 1С на управляемых формах. Здесь используется клиентский метод ОткрытьФорму() с передачей параметров заполнения.


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